前文介绍过代理层,代理层平台解决了多租户模式下的MySQL高可用能力。由于代理层上的业务众多,一旦出问题,就会影响大片的业务,所以在质量方面投入的比较多的精力,它的运维和监控一直是考虑的重点。业务问题的可追踪能力也很关键,本篇章主要介绍一下代理层的慢日志平台,业务方和DBA都能快速的查询到系统出现的慢日志,对于业务问题和系统故障定位都会提供助力。
生成慢日志
代理层平台不依赖于MySQL的慢日志,它自己会生成慢日志,主要从以下几个方面考虑:
代理层毕竟是业务和MySQL之间加了一层,会有一定的性能损耗;
代理层解决了跨机房的问题,写操作只能到主库,所以在多机房部署的情况下,会有代理层跨机房访问MySQL,代理层自己生成日志,可以把跨机房网络问题造成的慢日志记录下来;
可以自己决定慢日志的格式,定制感兴趣的元素。
慢日志格式:
时间|代理层IP|业务名|客户端IP|账号|发起机房|目标机房|是否自动提交|操作模式|DB Name|MySQL IP|MySQL Port|耗时|SQL
日志内容例子如下:
1492013991141|10.20.30.40|test_business|3.4.5.6|user|广州|深圳|false|0|db_test|6.7.8.9|3306|22539|delete from abc where ttt = ''
日志内容非常详尽,基本涵盖了所有可能的元素。笔者采用了纯文本的格式来存储满日志,出于以下几个目的:
- 不需要额外的工具就可以随时查看;
- 各种开源的日志收集工具都能支持;
为了采用纯文本来存储,SQL语句必须进行格式化: - 去掉不可见字符;
- 把回车换行符替换成空格;
- 超长SQL语句截断;
日志平台架构
日志平台架构如下所示:
graph LR
代理层主机1-LogStash--> ES集群
代理层主机2-LogStash--> ES集群
代理层主机...LogStash --> ES集群
代理层主机N-LogStash--> ES集群
ES集群--> Kibana
ES集群--> DBMS
日志收集
在每台代理层主机上部署LogStash,用于收集日志,根据指定的慢日志格式,为了实现
input {
file {
type => "slowlog"
path => ["/data/proxy-layer/slowlog/*"]
}
}
filter {
if [type] == "slowlog" {
ruby {
init => "@kname = ['time', 'host', 'business', 'clientip', 'user', 'fromidc', 'toidc','autcommit', 'mode', 'db', 'mysqlip', 'mysqlport', 'used', 'sql' ]"
code => "event.remove('host') ; event.append(Hash[@kname.zip(event['message'].split('|', @kname.size()))]) "
}
}
date {
match => ["time", "UNIX_MS"]
target => "@timestamp"
remove_field => ["message", "path"]
}
}
output {
elasticsearch { hosts => ["es.abc.com:9200"] }
stdout { codec =>rubydebug }
}
关于上面的logstash配置文件,主要有以下几点解释一下:
- 日志类型配置为:slowlog,将会在ES中自动生成slowlog开头的索引;
- 删除logstash自动生成的host字段,因为,我们的主机太多,所以每台主机的hostname基本相同,所以这个host字段基本无效;
- 采用慢日志中的代理层主机IP作为host字段;
- 时间戳字段不用Logstash生成,而是采用慢日志中的时间戳;
- 删除path字段,基本没用;
慢日志展示
代理层缺省设置超过1秒为慢日志,每个业务可以自己设置超时时间,毫秒为单位,现在随便找一个测试业务,执行 SELECT sleep(3);
等待SQL语句执行完毕,我们可以在DBMS中查看慢日志了:
本人只截取了测试用的SQL,仅供参考。
至于Kibana的展示,这里就不细说了,网上有更多详细的说明。