一、 Atlas简介
Atlas是Qihoo 360 Web平台部基础架构团队开发维护的一个基于MySQL协议的数据中间层项目。它在MySQL官方推出的MySQL Proxy 0.8.2版本的基础上,修改了大量bug,添加了很多功能特性。目前该项目在360公司内部得到了广泛应用,很多MySQL业务已经接入了Atlas平台,每天承载的读写请求数达几十亿条。
主要功能:
1、读写分离
2、从库负载均衡
3、IP过滤
4、自动分表
5、DBA可平滑上下线DB
6、自动摘除宕机的DB
二、 编译安装
1、rpm包安装
下载地址:https://github.com/Qihoo360/Atlas/releases
rpm–ivh Atlas-2.0.5.el6.x86_64.rpm
2、源码安装
依赖包:glib(2.32.x)、libevent(1.4)、Lua(5.1.x)、OpenSSL(0.9.8以上)
这儿glib要求2.32.x以上,然后安装glib又要求libffi3.0以上
可以通过下面的命令来相看相应的是否已经安装
rpm-qa | grep name
下载地址:https://github.com/Qihoo360/Atlas/releases
编译Atlas:
tarxvf Atlas-2.0.5.tar.gz
cdAtlas-2.0.5
vimbootstrap.sh
修改mysql_config路径,一般是/usr/bin/mysql_config
修改pkgconfig路径,一般是/usr/local/lib/pkgconfig
./bootstrap.sh
make&& make install
Atlas默认安装在/usr/local/mysql-proxy下,它的启动脚本里也默认是从/usr/local/mysql-proxy下启动。
如果想修改安装路径需要在bootstrap中加入prefix=/install-path,另外还在启动时还得修改启动脚本mysql-proxyd中的proxydir。
修改/usr/local/mysql-proxy/conf/下的配置文件instance.cnf(配置文件中相关参数的说明见下面)。
3、启动、停止和重启
启动:/usr/local/mysql-proxy/bin/mysql-proxydinstance start
停止:/usr/local/mysql-proxy/bin/mysql-proxydinstance stop
重启:/usr/local/mysql-proxy/bin/mysql-proxydinstance restart
三、 配置文件
Atlas运行需要依赖一个配置文件(test.cnf)。在运行Atlas之前,需要对该文件进行配置。Atlas的安装目录是/usr/local/mysql-proxy,进入安装目录下的conf目录,可以看到已经有一个名为test.cnf的默认配置文件,我们只需要修改里面的某些配置项,不需要从头写一个配置文件。
1、 配置范例及说明如下
[mysql-proxy]
(必备,默认值即可)管理接口的用户名
admin-username= root
(必备,默认值即可)管理接口的密码
admin-password= password
(必备,默认值即可)实现管理接口的Lua脚本所在路径
admin-lua-script= /usr/local/mysql-proxy/lib/mysql-proxy/lua/admin.lua
(必备,根据实际情况配置)主库的IP和端口,可设置多项,用逗号分隔(注:Atlas现在支持多master,但不建议使用,估计还不太完善)
proxy-backend-addresses= 192.168.0.1:3306
(非必备,根据实际情况配置)从库的IP和端口,@后面的数字代表权重,用来作负载均衡,若省略则默认为1,可设置多项,用逗号分隔。proxy-read-only-backend-addresses = 192.168.0.2:3306,192.168.0.3:3306
(必备,根据实际情况配置)用户名与其对应的加密过的MySQL密码,密码使用PREFIX/bin目录下的加密程序encrypt加密,用户名与密码之间用冒号分隔。主从数据库上需要先创建该用户并设置密码(用户名和密码在主从数据库上要一致)。比如用户名为myuser,密码为mypwd,执行./encryptmypwd结果为HJBoxfRsjeI=,则设置如下行所示:
pwds= myuser: HJBoxfRsjeI=
(必备,默认值即可)Atlas的运行方式,设为true时为守护进程方式,设为false时为前台方式,一般开发调试时设为false,线上运行时设为true
daemon= true
(必备,默认值即可)设置Atlas的运行方式,设为true时Atlas会启动两个进程,一个为monitor,一个为worker,monitor在worker意外退出后会自动将其重启,设为false时只有worker,没有monitor,一般开发调试时设为false,线上运行时设为true
keepalive= true
(必备,根据实际情况配置)工作线程数,推荐设置成系统的CPU核数
event-threads= 4
(必备,默认值即可)日志级别,分为message、warning、critical、error、debug五个级别
log-level= message
(必备,默认值即可)日志存放的路径
log-path= /usr/local/mysql-proxy/log
(必备,根据实际情况配置)SQL日志的开关,可设置为OFF、ON、REALTIME,OFF代表不记录SQL日志,ON代表记录SQL日志,REALTIME用于调试,代表记录SQL日志且实时写入磁盘,默认为OFF
sql-log= OFF
(必备)实例名称,用于同一台机器上多个Atlas实例间的区分
instance= test
(必备,默认值即可)Atlas监听的工作接口IP和端口
proxy-address= 0.0.0.0:1234
(必备,默认值即可)Atlas监听的管理接口IP和端口admin-address = 0.0.0.0:2345
(可选项,可不设置)分表设置,此例中person为库名,mt为表名,id为分表字段,3为子表数量,可设置多项,以逗号分隔,若不分表则不需要设置该项,子表需要事先建好,子表名称为表名数字,数字范围为[0,子表数-1],如本例里,子表名称为mt_0、mt_1、mt_2
tables= person.mt.id.3
(可选项,可不设置)默认字符集,若不设置该项,则默认字符集为latin1
charset= utf8
(可选项,可不设置)允许连接Atlas的客户端的IP,可以是精确IP,也可以是IP段,以逗号分隔,若不设置该项则允许所有IP连接,否则只允许列表中的IP连接
client-ips= 127.0.0.1, 192.168.1.
(可选项,极少需要)Atlas前面挂接的LVS的物理网卡的IP(注意不是虚IP),若有LVS且设置了client-ips则此项必须设置,否则可以不设置
lvs-ips= 192.168.1.1
2、 重要配置说明
以下几项配置参数对性能和正常运行起到重要作用,需要正确设置。
(1)线程数
event-threads项设置,过小无法充分发挥多核CPU的性能,过大造成不必要的线程切换开销,推荐设置为CPU的核数。
(2)最小空闲连接数(2.x以上版本不需要该项,1.x版本需要)
min-idle-connections项设置,过小则在高并发下会有报错,过大虽然不报错但在测试时不容易看出读写分离效果,推荐设置为比客户端的并发峰值稍大。
a、 该参数用来实现连接数控制功能。
b、 该值应设为event-threads的整数倍(不是整数倍的情况会自动向上取整数倍),且不低于实际使用时的并发量,若小于event-threads会没有可用连接导致报错。
c、 Atlas为每台DB建立一个连接池。
d、 当有客户端连接Atlas时,Atlas会先在第一台DB上建立连接,直到第一台DB连接池内的空闲连接数达到min-idle-connections,再在下一台DB上建立连接,直到所有DB连接池内的空闲连接数都达到min-idle-connections,便不再建立新连接,而开始复用连接池内的连接。
e、 Atlas启动时,配置里的所有DB会按照主库在前从库在后的顺序在内存里排好次序,所以初始阶段会先在主库上建立连接。
f、 Atlas在运行过程中,某连接如果触发了DB的wait_timeout,Atlas会把该连接销毁,如果因此而导致连接池内的空闲连接数低于min-idle-connections,Atlas将在客户端下一次连接时重新在该DB上建立连接。
g、 以上策略是因为在客户端与MySQL的交互过程中,connect和query是两个独立的阶段,在connect阶段Atlas需要决定在哪台DB上建立连接(或从哪台DB的连接里取出连接复用),而到了query阶段Atlas才能知道客户端发来的SQL语句是读还是写,这就决定了必须在主库上预留一定数量的连接供写语句使用。
h、 初使用者常常会误认为读写分离不起作用,其实是由于min-idle-connections设置得较大,而测试时只连接了一次或几次,这样的话建立的连接都在主库上,从库上还没有建立连接,此时发送读语句,自然也只能打向主库。只有在连接次数超过了min-idle-connections时,从库上才开始建立连接,从库上有连接后,读语句才能打向从库,此时读写分离才能生效。
i、 因此在测试读写分离时,可以将min-idle-connections设得较小,这样可以在少数几次连接后就看到读写分离的效果,而在线上运行时,应将min-idle-connections调大,防止并发量高峰时取不到可用连接导致前端报错。
j、 DB的wait_timeout建议不要设得太小,因为Atlas有连接池机制,不会一直新建连接导致DB上连接数过多,所以DB不需要依赖wait_timeout防止过多连接,如果wait_timeout太小会导致Atlas的一些不必要的销毁超时连接的开销。
上面的配置范例是针对Atlas2.X版本,没有该选项。对于Atlas1.X版本的配置文件,需要加入该配置选项。
(3)pwds
a、该参数用来实现多用户的权限控制功能。Atlas2.x版本中必须配置该项参数。
b、密码使用PREFIX/bin/encrypt程序加密,避免有人打开配置文件就能看到所有用户的密码,只是简单地防护一下,并不能防止专门的恶意破解。
c、在Atlas的内存中,多个用户共用连接池,池内同时有多个用户名及使用其密码认证过的连接,在A用户连接Atlas时,从池中取出的连接有可能是B用户认证过的,这就需要使用A用户的密码将此连接change为A用户的认证连接,否则直接给A用户使用该连接就会引发权限问题。
d、如果将各用户的连接池独立,则无法与min-idle-connections机制良好配合,会造成连接数一直上涨的问题。(此项说明只针对Atlas1.x版本。在Atlas2.x版本中当连接池中没有可用连接时,Atlas支持自建连接,已经不需要min-idle-connections机制。)
e、官方版本中多用户也是共用连接池,但没有实现change机制,因此经常发生A用户看到B用户的库和表的现象。
(4)client-ips
a、该参数用来实现IP过滤功能。
b、在传统的开发模式中,应用程序直接连接DB,因此DB会对部署应用的机器(比如web服务器)的IP作访问授权。
c、在引入中间层后,因为连接DB的是Atlas,所以DB改为对部署Atlas的机器的IP作访问授权,如果任意一台客户端都可以连接Atlas,就会带来潜在的风险。
d、client-ips参数用来控制连接Atlas的客户端的IP,可以是精确IP,也可以是IP段,以逗号分隔写在一行上即可,如client-ips=192.168.1.2,192.168.2,这就代表192.168.1.2这个IP和192.168.2.*这个C段的IP可以连接Atlas,其他IP均不能连接。
e、如果该参数不设置,则任意IP均可连接Atlas。
f、如果设置了client-ips参数,且Atlas前面挂有LVS,则必须设置lvs-ips参数,否则可以不设置lvs-ips。
(5)lvs-ips
a、该参数是Atlas前面挂接的LVS的物理网卡的IP,不是虚IP。
b、该参数用来实现平滑重启功能,否则在重启Atlas的瞬间的那些SQL请求都会失败,如果认为应用可以接受瞬间的报错则可以直接重启。
c、平滑重启的条件:至少有两台配置相同的Atlas,且挂接在LVS之后。
d、平滑重启的原理:LVS周期性地对后端Atlas的存活检测有两种方式,一是直接去探测端口是否可连接,二是执行一个脚本,这个脚本会去尝试连接Atlas,通过脚本的返回值来决定每个后端是否可用。Atlas有两种运行状态,通常为online,可通过发信号将其置为offline。Atlas检测到来请求的IP是LVS的网卡IP时,如果处于online状态,就向LVS的检测脚本返回online,如果处于offline状态,就向脚本返回offline。比如我现在因为某种原因需要重启一台Atlas,但直接重启势必导致瞬间的SQL请求全部失败,对前端应用造成影响。因此我先发下线信号将Atlas置为offline状态,当LVS的检测脚本发现返回值是offline时,便将这台Atlas摘除,从此时开始便没有新的请求导向这台Atlas。等到已经打向这台Atlas的SQL请求处理完毕后(这是一个很短的时间),就可以安然重启Atlas而不必担心对前端造成影响了。
e、对于大多数应用来说,可能并没有那么敏感,因此不使用平滑重启功能而直接重启也是可以接受的。但在设置了client-ips参数的情况下,必须设置lvs-ips参数,否则LVS的物理网卡的IP会被Atlas拒绝,如果未设置client-ips参数,说明不开启IP过滤功能,则lvs-ips也可以不设置。
3、 可选配置说明
以下几项可以设置,也可以使用默认值,区别不大。
(1)Atlas的工作端口
proxy-address项配置,例如proxy-address= 0.0.0.0:1234代表客户端应该使用1234这个端口连接Atlas来发送SQL请求。
(2)Atlas的管理端口
admin-address项配置,例如admin-address= 0.0.0.0:2345代表DBA应该使用2345这个端口连接Atlas来执行运维管理操作。
(3)管理接口的用户名和密码
admin-username项和admin-password项设置,这两项是用来进入Atlas的管理界面的,与后端连接的MySQL没有关系,所以可以任意设置,不需要MySQL在配置上做任何改动。
(4)日志级别
以log-level项配置,分为message、warning、critical、error、debug五个级别。
(5)日志路径
以log-path项配置,如log-path= /usr/local/mysql-proxy/log。
参考资料:
https://github.com/Qihoo360/Atlas
https://github.com/Qihoo360/Atlas/wiki/Atlas%E7%9A%84%E5%AE%89%E8%A3%85
https://github.com/Qihoo360/Atlas/wiki/Atla%E9%83%A8%E5%88%86%E9%85%8D%E7%BD%AE%E5%8F%82%E6%95%B0%E5%8F%8A%E5%8E%9F%E7%90%86%E8%AF%A6%E8%A7%A3