Mysql Proxy 美团点评开源的DBProxy
2020-10-23 14:12 宋海宾 阅读(515) 评论(0) 收藏 举报Mysql读写分离中间件-DBProxy详解
【写在前面】
在互联网应用场景中,使用比较广泛的数据库是mysql,在很多业务场景中涉及到读写分离,目前市面上读写分离中间件不少,比如奇虎360开源的Atlas,百度的DBProxy(未开源),美团点评开源的DBProxy等等。
从个人使用感受来讲,这些中间件都是比较稳定可靠的,考虑到开源和现状,本文结合具体的实践经验聊一下DBProxy。
【功能介绍】
本文介绍的中间件是来自美团点评开源的DBProxy,github地址:
https://github.com/Meituan-Dianping/DBProxy
DBProxy是基于奇虎360开源的Atlas基础上进行改进的,根据个人在奇虎360工作经验来看,Atlas还是比较稳定可靠地。个人建议使用Atlas改进版--DBProxy。
DBProxy主要功能如下:
(1)读写分离
可以自动实现读请求路由到slave中,写请求路由到master中,对开发而言,使用方式和mysql一样,只是配置一下DBProxy连接就可以了。
(2)从库负载均衡
如果存在多个slave,支持读请求按照slave的权重,分别路由到各个slave中,分担读请求压力。可以人为设置各个slave的权重,默认权重为1.
(3)IP过滤
支持哪些IP(段)可以访问,提升安全性。
(4)DBA可平滑上下线mysql节点
支持在线扩容slave、调整后端mysql(包括master和slave),不需要重启。
说明:流量高峰期期间,该操作需要慎重。
(5)自动摘除宕机的mysql节点
如果后端某个mysql节点宕机,该节点自动从中间件上下掉,读写请求不再路由到该节点实现自动止损,如果所有slave全部宕机,读请求自动路由到master节点。
(6)监控信息完备
DBProxy打印了比较详细的日志,方便DBA追查问题。
(7)密文存储密码
DBProxy提供了加密工具,对密码加密,然后在配置文件中设置密文密码,可以提高安全性。
(8)解耦业务和mysql
通过DBProxy可以解耦业务和mysql,可以实现透明调整mysql,尤其适合DBA白天操作mysql。
说明:DBProxy官方称目前只支持mysql(percona)5.5和5.6。如果想使用mysql5.7或者8.0,可能需要选择其他方案。
sql限制:
受到限制的sql主要包括不常用的管理命令,以及不带where的dml等,对于一般情况的应用几乎没有影响。考虑到限制的sql点比较多(尽管大部分不常用),建议先测试所有的业务sql,然后再上线DBProxy。
具体sql限制参考:
https://github.com/Meituan-Dianping/DBProxy/blob/master/doc/USER_GUIDE.md#3.2.1
【最佳实践】
(1)环境说明
操作系统:centos 6.9 x86_64
mysql版本:percona-server-5.6(二进制版本)
DBProxy版本:0.2.5
glib2: 2.42.0
说明:考虑到master高可用以及DBProxy自身的高可用,本文采用了keepalived+haproxy+MHA方案。
(2)安装依赖包
首先需要安装依赖包 glib-2.42,如下:
yum install -y Percona-Server-devel-56.x86_64 Percona-Server-shared-56 jemalloc jemalloc-devel libevent libevent-devel openssl openssl-devel lua lua-devel bison flex libtool.x86_64 libffi.x86_64 libffi-devel.x86_64 gettext.x86_64 gettext-devel.x86_64
说明:由于具体的操作系统有所差别,依赖包安装也存在差别。
wget https://src.fedoraproject.org/repo/pkgs/mingw-glib2/glib-2.42.0.tar.xz/
71af99768063ac24033ac738e2832740/glib-2.42.0.tar.xz
xz -d glib-2.42.0.tar.xz
tar -xvf glib-2.42.0.tar
cd glib-2.42.0
autoreconf -ivf
./configure --prefix=/usr/local/glib-2.42 --enable-iconv=no --with-libiconv=gnu
make && make install
然后执行:
echo "/usr/local/glib-2.42" >>/etc/ld.so.conf && ldconfig
(3)编译安装DBProxy
从github下载 DBProxy-master.zip
unzip DBProxy-master.zip && cd DBProxy-master
首先修改bootstrap.sh,修改后的内容如下:
#!/bin/sh
base=$(cd "$(dirname "$0")"; pwd)
cd $base
./configure --prefix=/usr/local/mysql-proxy CFLAGS="-g -O0" \
GLIB_CFLAGS="-I/usr/local/glib-2.42/include/glib-2.0 -I/usr/local/glib-2.42/lib/glib-2.0/include" \
GLIB_LIBS="-L/usr/local/glib-2.42/lib -lglib-2.0" \
GMODULE_CFLAGS="-pthread -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include" \
GMODULE_LIBS="-L/usr/local/glib-2.42/lib -Wl,--export-dynamic -lgmodule-2.0 -pthread -lrt" \
GTHREAD_CFLAGS="-pthread -I/usr/local/glib-2.42/include/glib-2.0 -I/usr/local/glib-2.42/lib/glib-2.0/include" \
GTHREAD_LIBS="-L/usr/local/glib-2.42/lib -lgthread-2.0 -pthread -lrt"
说明:/usr/local/glib-2.42 是之前glib-2.42编译安装的目录,此处要保持一致
建议prefix设置为:/usr/local/mysql-proxy
然后执行:
cd DBProxy-master
sh autogen.sh
sh bootstrap.sh
make && make install
安装完成后,可以拷贝 /usr/local/glib-2.42 和 /usr/local/mysql-proxy 到其他服务器对应目录即可。
(4)集成MHA和haproxy
MHA作为mysql比较常用的高可用方案,可以实现master高可用
在DBProxy配置文件中,相关设置:
proxy-backend-addresses = <mha-vip>:<mysql-port>
<mha-vip>就是mha对应的vip
<mysql-port>就是mysql的端口号
图1
说明:
1) LVS采用keepalived + haproxy方案,可以解决DBProxy单点问题,
2) MHA解决mysql master单点问题。
3) 2个或者多个DBProxy,避免DBProxy自身单点,还可以实现负载均衡,提高并发。
4) 根据实际需求,部署1个或者多个slave,提升度请求并发量。
5) 盖家沟实现了mysql master和slave高可用。,同时实现了读写分离。
【配置文件介绍】:
主要参数配置如下,仅供参考
[mysql-proxy]
admin-username=admin_user
admin-password=admin_pwd
### mysql_pwd1 mysql_pwd2为密文
pwds=mysql_user1:mysql_pwd1,mysql_user2:mysql_pwd2
backend-monitor-pwds=monitor_user:monitor_pwd
admin-user-hosts=10.111.12%,10.151.%
user-hosts=%@10.111.12%,%@10.151.%
admin-address=0.0.0.0:23456
proxy-address=0.0.0.0:13456
proxy-backend-addresses=10.111.123.135:3456
proxy-read-only-backend-addresses=10.111.123.137:3456@10
log-path=/usr/local/mysql-proxy/log
sql-log=ON
sql-log-buffer-size=256
sql-log-file-size=1073741824
sql-log-file-num=3
sql-log-mode=ALL
log-trace-modules=0
daemon=true
keepalive=true
query-response-time-stats=1
mysql-version=5.6
event-threads=8
instance=proxy3456
user=dba
max-connections=5000
long-wait-time=1000
long-query-time=100
wait-timeout=7200
db-connection-idle-timeout=7200
backend-max-thread-running=0
thread-running-sleep-delay=10
remove-backend-timeout=1024
shutdown-timeout=60
check-state-interval=4
check-state-conn-timeout=1
说明:密文密码生成方法:
cd /usr/local/mysql-proxy/bin && ./encrypt <raw_pwd>
<raw_pwd>表示原始密码,该命令生成一个密文密码
启停DBProxy:
/usr/local/mysql-proxy/bin/mysql-proxyd $instance start|stop|status|restart
$instance:DBProxy的instance参数值
也可以自行封装脚本管理。
【管理DBProxy】
登录管理端口,可以执行:select * from help;
查看所有的管理功能
常用的功能如下:
(1) 查看backend
图2
(2)调整backend节点
下线backend
图3
上线backend:
图4
移除backend:
图5
添加slave节点:
图6
说明:本操作常用于mysql节点调整,假设迁移一个slave节点到另外一台服务器,流程如下:
1)做数据
在新服务器上,可以采用镜像或者在线热备方式,启动一个新slave节点,直到同步追上
2)添加slave节点
按照上述方法添加一个slave,并且观察是否接入流量
3)下掉老slave节点
可以先下线该节点,然后再移除该节点
如果迁移master节点,可以执行MHA在线切换命令,不需要上下线这里的 rw节点。
这样,mysql节点调整对开发是透明的,是一种比较友好的方式。
(3)添加删除用户
删除用户
图7
添加用户
图8
说明:添加用户也可以使用 ADD ENPWD <user_name>:<encrypted_password>
<encrypted_password>是密文密码
(4)调整IP白名单
添加用户IP白名单
图9
删除用户IP白名单
图10
添加管理host:
图11
删除管理host:
图12
说明:在增加IP段的场景下,可以参照以上操作添加或者删除IP白名单;也可以在线增加用户,在线修改参数后,可以执行 SAVE CONFIG 持久化保存。
(5)监控proxy状态
图13
通过执行该命令,采集状态值,结合zabbix系统,可以有效监控proxy运行情况。
(6)sql过滤
如果希望某些sql禁止访问,可以参照如下操作:
图14
登录proxy端口,执行如下命令验证:
图15
去除blacklist:
图16
说明:在生产环境中,谨慎使用sql过滤功能,避免影响业务。
(7)其他参数设置
登录管理端口,执行:select * from help; 查看其它参数设置的方法,这里不再赘述。
【使用建议】
(1)端口设置
DBProxy涉及到如下端口:
1)mysql主库端口
2)mysql从库端口
3)proxy端口
4)管理端口
为了方便管理和使用DBProxy,可以如下命名这些端口:
比如,mysql主库端口为3456,从库和主库保持一致,proxy端口为13456,管理端口为23456,同时,可以设置 instance=proxy3456
(2)读请求走主库方法
如果写完数据,确保可以立即查询出结果,可以人为路由该请求到主库,方式如下:
/*MASTER*/ select c1,c2,c3 from tab1 where xxx;
(3)读请求路由到指定的slave
如果希望读请求路由到某个指定的slave节点,可以设置tag,然后sql改为如下方式:/*slave@$slave_tag*/ sql-statement;这样,该查询就可以路由到指定的slave了
【注意事项】
从使用经验看,DBProxy可以很不错地解决mysql读写分离的需求,支持php,java等编程语言,但是,需要注意:
(1)不支持mysql5.7以及更高版本
(2)不支持java-mysql 1.8版本,笔者使用的是5.1.46 java-mysql驱动包
(3)Php访问DBProxy时候,不支持MYSQLI_CLIENT_COMPRESS设置
(4)停止更新维护,期待“有志之士”继续维护更新。
同时,笔者也测试了cetus读写分离,和DBProxy相比,cetus存在如下缺点:
(1)cetus日志不够详细
(2)如果mysql主从节点不在同一个网段,登陆cetus管理后台,查看从库状态为unknown,估计是不支持跨网段
(3) 需要配置默认db,使用起来不方便
(4) 不支持设置slave权重
(5) 密码明文保存
当然,cetus也存在优点:比如支持高版本mysql等。
以上是对比测试结果,如有纰漏,欢迎交流指正。
【写在最后】
DBProxy作为读写分离中间件,比较可靠稳定的解决了mysql读写分离的需求,维护简单。它实现了slave高可用,同时,结合MHA可以解决master单点问题,结合keepalived+haproxy,可以解决DBProxy自身的单点问题,尤其适合于中小规模业务场景。另外,需要注意haproxy和DBProxy监控,从而保障整个链路的可用性。
【参考文献】
https://github.com/Meituan-Dianping/DBProxy/blob/master/doc/USER_GUIDE.md
浙公网安备 33010602011771号