MySQL之监控binlog日志,解决系统响应慢的问题【maxwell】

视频地址: https://www.bilibili.com/video/BV1PY4y1s7a1


一、场景

不知道你是否有无数次吐槽公司的架构设计,比如某一个关键的列表, join 了无数张表 (join 代表了left join、 inner join 等)

做了一个新功能,新增了几张表,列表为了展示一个字段,又去关联一张大表,这样的操作,速度不慢才怪嘞

很遗憾我们现在的系统就是这样的,不知道你们有没有听说过ADB这样的数据库,它们主要是用来处理大数据的,性能超强,我们一个查询20s的SQL,迁移到ADB里面那就0.Ns了 (我们不去探索它为什么这么快哈)

但尽管如此,终会有一天ADB这样的数据库也扛不住,这一天已经不远了

以前我的想法总是说去重构代码,但每次只是想想就头痛,一个关键的列表,关联了十几张表,谁敢去动它呢?


二、解决方案

是不是一定没有办法解决呢?答案是否定的,最近我们有一个解决方案,并且已经实践了,一个20s的查询优化后可以达到0.Ns

怎么做呢?我们知道所有的数据最终都是写入MySQL数据库,那么我们就可以监控binlog 把十几张表里面我们需要用到的字段冗余到一张表里面(也就20个左右的字段),这样我们的查询就只需要 join一张表 join一次还是带了索引它能不快吗?

我们之所以关联了那么多张表不正是想要从它里面获取某个数据吗?假如我们关联A表是为了获取a1字段,那么我们是不是可以监控操作A表增、删、改的全部binlog,然后把每次操作都写入我们的宽表里面?是不是就做到了?

监控binlog的插件有很多,这里我推荐一个 MaxWell ,它是国外的一家公司开源用于监控binlog的软件,基于java开发的。

它使用起来很简单,完全和你的代码解耦,你单独的部署它,它可以把监控到的结果发送到 kafka、rabbitmq、redis等很多地方,然后你只需要去消费这个消息,对它进行业务处理即可。


三、实践

3-1、开始

下面我们来搭建一下maxwell,需要准备下面的环境

  • JDK 11
  • MySQL
  • MaxWell
  • RabbitMQ
  • Linux/Mac 服务器

注:rabbitmq不是必须的,如果想要发送到rabbitmq里面则可以安装,默认是输出到控制台

JDK、MySQL、rabbitmq都自行安装,这里说一下,一般我们都已经安装好了JDK8,我们可以再下载一下JDK11,安装就行,不需要配置环境变量,到时候我们执行maxwell的时候指定JDK11 就好


3-2、下载maxwell

https://github.com/zendesk/maxwell/releases/download/v1.37.6/maxwell-1.37.6.tar.gz

它是一个解压即可用的软件,解压后目录如下:

在这里插入图片描述

我们需要把它上传到Linux服务器上,如果你是Mac电脑那么恭喜你,直接可以运行


3-3、MySQL配置

找到我们的 my.cnf,添加上如下配置

# 给当前mysql一个唯一id
server_id=1
# 开启binlog
log-bin=master
binlog_format=row

binlog_format 是设置binlog的格式,它有三种格式

  • statement 基于SQL语句的复制
  • row 基于行的复制(row-based replication, RBR)
  • mixed 混合模式复制(mixed-based replication, MBR)

详情参考 MySQL日志篇,MySQL日志之binlog日志,binlog日志详解


3-4、配置文件

把下面的配置文件放在 bin 目录下, 配置文件都很简单,相信你能看懂

# tl;dr config
log_level=info
# mysql login info
host=127.0.0.1
port=3306
user=root
password=123456

# 结果打印在控制台
producer=stdout


# 结果输出到rabbitmq
#producer=rabbitmq
#rabbitmq_host=127.0.0.1
#rabbitmq_port=5672
#rabbitmq_user=guest
#rabbitmq_pass=guest
#rabbitmq_virtual_host=/
#rabbitmq_exchange=maxwell
#rabbitmq_exchange_type=fanout
#rabbitmq_exchange_durable=false
#rabbitmq_exchange_autodelete=false
#rabbitmq_routing_key_template=%db%.%table%
#rabbitmq_message_persistent=false
#rabbitmq_declare_exchange=true

3-5、修改启动文件

启动文件是 bin/maxwell ,因为大部分人配置都是JDK8,所以直接从环境变量里面读取是不行的,这里我们要把JDK换成11的

找到你JDK11的安装目录,把下面的代码删掉换成你自己的JDK11位置,比如我的配置如下
在这里插入图片描述

JAVA="/usr/local/jdk-11.0.15.1/bin/java"

3-6、启动

进入到bin目录下,输入下面的命令

./maxwell

有可能提示权限不够,我们可以使用下面的命令赋值权限后,再启用

chmod 777 ./maxwell

在这里插入图片描述


3-7、测试

我们可以使用navicat或者任意操作数据库的办法,比如我们在数据库里面执行这样一句

INSERT INTO user (id, user_name) VALUES (7, '小道仙');

我们的控制台会打印这样的数据(数据是一行的,为了展示,我把它换行了)

{
	"database": "test",
	"table": "user",
	"type": "insert",
	"ts": 1654417263,
	"xid": 70955,
	"commit": true,
	"data": {
		"id": "7",
		"user_name": "小道仙"
	}
}

更新语句

UPDATE `user` SET user_name = '小道仙97' WHERE id = 7;

{
	"database": "test",
	"table": "user",
	"type": "update",
	"ts": 1654417405,
	"xid": 71147,
	"commit": true,
	"data": {
		"id": "7",
		"user_name": "小道仙97"
	},
	"old": {
		"user_name": "小道仙"
	}
}

删除语句

DELETE FROM `user` WHERE id IN(1,2);

{
	"database": "test",
	"table": "user",
	"type": "delete",
	"ts": 1654417609,
	"xid": 71478,
	"xoffset": 0,
	"data": {
		"id": "1",
		"user_name": "张三"
	}
} 
{
	"database": "test",
	"table": "user",
	"type": "delete",
	"ts": 1654417609,
	"xid": 71478,
	"xoffset": 1,
	"data": {
		"id": "2",
		"user_name": "李四"
	}
}

四、其它


4-1、maxwell 官方文档

https://maxwells-daemon.io/


4-2、实际使用中的问题

其实也就是一些队列消费的问题了,比如保持幂等消息丢失消费速率消息积压问题等,这里主要说一下消息积压的问题。

我们开了40个线程,消费队列5k,但依旧消费不过来,线程池默认的拒绝策略是丢弃并抛出异常,我们可以改成使用当前线程处理,这样虽然消费会慢点,但不至于丢数据。 (当然实际上开多少个线程还是要根据你的业务来)

maxwell是监控当前链接的全部数据库,我们可以进行一个限制,使其只监控我们需要的库、表。

ps:这里吐槽一下,线程池的拒绝策略我背了很熟了,但出了问题我却没想到可以换一种策略来处理。

4-N、下面是准备的安装包

在这里插入图片描述

关注微信公众号回复关键字获取:maxwellFile

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值