Atlas

简介

  • Atlas在mysql-proxy基础上二次开发而来,主要有如下功能
  1. 读写分离
  2. 从库负载均衡
  3. IP白名单管理
  4. 大表分片操作
  5. 平滑上下线DB
  6. 自动摘除宕机的DB

架构

Atlas是一个位于应用程序与MySQL之间中间件。在后端DB看来,Atlas相当于连接它的客户端,在前端应用看来,Atlas相当于一个DB。Atlas作为服务端与应用程序通讯,它实现了MySQL的客户端和服务端协议,同时作为客户端与MySQL通讯。它对应用程序屏蔽了DB的细节,同时为了降低MySQL负担,它还维护了连接池。架构与proxy相同,可以用下面的图表示
Atlas_第1张图片

  • Atlas的线程模型
  1. Atlas启动后会创建多个线程,其中一个为主线程,其余为工作线程。主线程负责监听所有的客户端连接请求,工作线程只监听主线程的命令请求。
  2. 主线程接收到客户端的连接请求,将该请求的相关信息封装为一个名为CON的结构,再把该结构推入一个异步队列。然后通过round-robin方式选择一个工作线程,向其发送一个字节的数据包以激活它。工作线程在收到主线程的激活指令后,从异步队列中取出CON结构,开始处理客户端的请求。
    Atlas_第2张图片
  • Atlas配合LVS使用的架构
    LVS前端做负载均衡,两个Atlas做HA,防止单点故障。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而不必担心对前端造成影响了。
    Atlas_第3张图片

分表配置

  • Atlas的分表功能,通过在配置文件(test.cnf)设置tables参数实现
  • tables参数设置格式:数据库名.表名.分表字段.子表数量,比如你的数据库名叫school,表名叫stu,分表字段叫id,总共分为100张表,那么就写为school.stu.id.100,如果还有其他的分表,以逗号分隔即可。用户需要手动建立100张子表(stu_0,stu_1,…stu_99,注意子表序号是从0开始的)。且所有的子表必须在DB的同一个database里。
  • 当通过Atlas执行(SELECT、DELETE、UPDATE、INSERT、REPLACE)操作时,Atlas会根据分表结果(id%100=k),定位到相应的子表(stu_k)。例如,执行select * from stu where id=110;,Atlas会自动从stu_10这张子表返回查询结果。但如果执行SQL语句(select * from stu;)时不带上id,则会提示执行stu 表不存在。
  • 注:Atlas暂不支持自动建表和跨库分表的功能。Atlas目前支持分表的语句有SELECT、DELETE、UPDATE、INSERT、REPLACE。

配置文件

cat /usr/local/mysql-proxy/conf/test.cnf
[mysql-proxy]

(必备,默认值即可)管理接口的用户名

admin-username = user

(必备,默认值即可)管理接口的密码

admin-password = pwd

(必备,根据实际情况配置)主库的IP和端口

proxy-backend-addresses = 192.168.0.12:3306

(非必备,根据实际情况配置)从库的IP和端口,@后面的数字代表权重,用来作负载均衡,若省略则默认为1,可设置多项,用逗号分隔。如果想让主库也能分担读请求的话,只需要将主库信息加入到下面的配置项中。

proxy-read-only-backend-addresses = 192.168.0.13:3306,192.168.0.14:3306

(必备,根据实际情况配置)用户名与其对应的加密过的MySQL密码,密码使用PREFIX/bin目录下的加密程序encrypt加密,用户名与密码之间用冒号分隔。主从数据库上需要先创建该用户并设置密码(用户名和密码在主从数据库上要一致)。比如用户名为myuser,密码为mypwd,执行./encrypt mypwd结果为HJBoxfRsjeI=。如果有多个用户用逗号分隔即可。则设置如下行所示:

pwds = myuser: HJBoxfRsjeI=,myuser2:HJBoxfRsjeI=

(必备,默认值即可)Atlas的运行方式,设为true时为守护进程方式,设为false时为前台方式,一般开发调试时设为false,线上运行时设为true

daemon = true

(必备,默认值即可)设置Atlas的运行方式,设为true时Atlas会启动两个进程,一个为monitor,一个为worker,monitor在worker意外退出后会自动将其重启,设为false时只有worker,没有monitor,一般开发调试时设为false,线上运行时设为true

keepalive = true

(必备,根据实际情况配置)工作线程数,推荐设置成系统的CPU核数的2至4倍

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

(可选项,可不设置)慢日志输出设置。当设置了该参数时,则日志只输出执行时间超过sql-log-slow(单位:ms)的日志记录。不设置该参数则输出全部日志。

sql-log-slow = 10

(可选项,可不设置)关闭不活跃的客户端连接设置。当设置了该参数时,Atlas会主动关闭经过’wait-timeout’时间后一直未活跃的连接。单位:秒

wait-timeout = 10

(必备,默认值即可)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

Atlas部分配置参数及原理详解

  • password
  1. 密码使用PREFIX/bin/encrypt程序加密,避免有人打开配置文件就能看到所有用户的密码,只是简单地防护一下,并不能防止专门的恶意破解。
  2. 在Atlas的内存中,多个用户共用连接池,池内同时有多个用户名及使用其密码认证过的连接,在A用户连接Atlas时,从池中取出的连接有可能是B用户认证过的,这就需要使用A用户的密码将此连接change为A用户的认证连接,否则直接给A用户使用该连接就会引发权限问题。
  • client-ips
  1. 该参数用来实现IP过滤功能。
  2. 在引入中间层后,因为连接DB的是Atlas,所以DB改为对部署Atlas的机器的IP作访问授权,如果任意一台客户端都可以连接Atlas,就会带来潜在的风险。
  3. client-ips参数用来控制连接Atlas的客户端的IP,可以是精确IP,也可以是IP段,以逗号分隔写在一行上即可,如client-ips=192.168.1.2, 192.168.2,这就代表192.168.1.2这个IP和192.168.2.*这个网段的IP可以连接Atlas,其他IP均不能连接。
  4. 如果该参数不设置,则任意IP均可连接Atlas。
  5. 如果设置了client-ips参数,且Atlas前面挂有LVS,则必须设置lvs-ips参数,否则可以不设置lvs-ips。
  • lvs-ips
  1. 该参数是Atlas前面挂接的LVS的物理网卡的IP,不是虚IP。
  2. 该参数用来实现平滑重启功能,滑重启的条件:至少有两台配置相同的Atlas,且挂接在LVS之后。
  3. 平滑重启的原理: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而不必担心对前端造成影响了。
  4. 在设置了client-ips参数的情况下,必须设置lvs-ips参数,否则LVS的物理网卡的IP会被Atlas拒绝,如果未设置client-ips参数,说明不开启IP过滤功能,则lvs-ips也可以不设置。
  • event-threads 线程数
    过小无法充分发挥多核CPU的性能,过大造成不必要的线程切换开销,推荐设置为CPU的核数。
  • min-idle-connections 最小空闲连接数(2.x以上版本不需要该项,1.x版本需要)
    过小则在高并发下会有报错,过大虽然不报错但在测试时不容易看出读写分离效果,推荐设置为比客户端的并发峰值稍大,
  • proxy-address:Atlas的工作端口
    proxy-address = 0.0.0.0:1234代表客户端应该使用1234这个端口连接Atlas来发送SQL请求。
  • admin-address:Atlas的管理端口
    admin-address = 0.0.0.0:2345代表DBA应该使用2345这个端口连接Atlas来执行运维管理操作。
  • 管理接口的用户名和密码:admin-username项和admin-password项设置,这两项是用来进入Atlas的管理界面的,与后端连接的MySQL没有关系,所以可以任意设置,不需要MySQL在配置上做任何改动。
  • log-level:日志级别
    message、warning、critical、error、debug五个级别,通常设置为error。
  • log-path:日志路径–如log-path = /usr/local/mysql-proxy/log。

安装配置

下载rpm包并安装

wget https://github.com/Qihoo360/Atlas/releases/download/2.2.1/Atlas-2.2.1.el6.x86_64.rpm
rpm -ivh Atlas-2.2.1.el6.x86_64.rpm 

默认在”/usr/local/mysql-proxy”下给你生成4个文件夹,以及需要配置的文件,如下:

[root@localhost home]# ll /usr/local/mysql-proxy/
total 16
drwxr-xr-x. 2 root root 4096 Dec 28 10:47 bin
drwxr-xr-x. 2 root root 4096 Dec 28 10:47 conf
drwxr-xr-x. 3 root root 4096 Dec 28 10:47 lib
drwxr-xr-x. 2 root root 4096 Dec 17  2014 log
  • bin目录下放的都是可执行文件
    1. “encrypt”是用来生成MySQL密码加密的,在配置的时候会用到
    2. “mysql-proxy”是MySQL自己的读写分离代理
    3. “mysql-proxyd”是360弄出来的,后面有个“d”,服务的启动、重启、停止。都是用他来执行的
  • conf目录下放的是配置文件
    “test.cnf”只有一个文件,用来配置代理的,可以使用vim来编辑
  • lib目录下放的是一些包,以及Atlas的依赖
  • log目录下放的是日志,如报错等错误信息的记录
  1. 进入bin目录,使用encrypt来对数据库的密码进行加密,比如用户名是buck,密码是hello,我需要对密码进行加密
[root@localhost bin]# ./encrypt hello
RePBqJ+5gI4=

得到的结果就是密码加密后的值,写在配置文件admin-password后面

编辑配置文件

#管理接口的用户名
admin-username = user

#管理接口的密码
admin-password = pwd
  • 这是用来登录到Atlas的管理员的账号与密码,与之对应的是“#Atlas监听的管理接口IP和端口”,也就是说需要设置管理员登录的端口,才能进入管理员界面,默认端口是2345,也可以指定IP登录,指定IP后,其他的IP无法访问管理员的命令界面。方便测试,我这里没有指定IP和端口登录。
#Atlas后端连接的MySQL主库的IP和端口,可设置多项,用逗号分隔
proxy-backend-addresses = 192.168.246.134:3306

#Atlas后端连接的MySQL从库的IP和端口,@后面的数字代表权重,用来作负载均衡,若省略则默认为1,可设置多项,用逗号分隔
proxy-read-only-backend-addresses = 192.168.246.135:3306@1
  • 这是用来配置主数据的地址与从数据库的地址,这里配置的主数据库是135,从数据库是134,从库为read-only,实现读写分离
#用户名与其对应的加密过的MySQL密码,密码使用PREFIX/bin目录下的加密程序encrypt加密,下行的user1和user2为示例,将其替换为你的MySQL的用户名和加密密码!
pwds = buck:RePBqJ+5gI4=
  • 这个是用来配置MySQL的账户与密码的,我的MySQL的用户是buck,密码是hello,刚刚使用Atlas提供的工具生成了对应的加密密码
#Atlas监听的工作接口IP和端口
proxy-address = 0.0.0.0:1234

#Atlas监听的管理接口IP和端口
admin-address = 0.0.0.0:2345
  • 这是设置工作接口与管理接口的,如果ip设置的”0.0.0.0”就是说任意IP都可以访问这个接口,当然也可以指定IP和端口,方便测试我这边没有指定,工作接口的用户名密码与MySQL的账户对应的,管理员的用户密码与上面配置的管理员的用户密码对应。

启动Atlas

[root@localhost bin]# ./mysql-proxyd test start
OK: MySQL-Proxy of test is started

注意事项

  1. 自动读写情况下,但有时候写完马上就想读,如果主从同步延迟怎么办?
  • SQL语句前增加 /master/ 就可以将读请求强制发往主库。在mysql命令行测试该功能时,需要加-c选项,以防mysql客户端过滤掉注释信息。
  1. 主库宕机,在Atlas中读操作不受影响,Atlas会将读请求转发到其他还存活的从库上。但此时写请求将会失败,因为主库宕机了。
  2. atlas中检测线程是异步进行检测的,即使有db宕机,也不会阻塞主流程。在Atlas中没有什么异常会让主流程阻塞。

Atlas管理操作

  • 登录管理接口:
mysql -uuser -ppwd -h127.0.0.1 -P2345
  • 查看帮助信息:
mysql> SELECT * FROM help;
  • 查看后端代理库:
mysql> SELECT * FROM backends;
+-------------+----------------+-------+------+
| backend_ndx | address        | state | type |
+-------------+----------------+-------+------+
|           1 | 10.0.0.55:3306 | down  | rw   |
|           2 | 10.0.0.52:3306 | down  | ro   |
|           3 | 10.0.0.53:3306 | up    | ro   |
+-------------+----------------+-------+------+
3 rows in set (0.00 sec)

平滑摘除代理库

mysql> REMOVE BACKEND 2;
Empty set (0.00 sec)
mysql> SELECT * FROM backends;
+-------------+----------------+-------+------+
| backend_ndx | address        | state | type |
+-------------+----------------+-------+------+
|           1 | 10.0.0.55:3306 | down  | rw   |
|           2 | 10.0.0.53:3306 | up    | ro   |
+-------------+----------------+-------+------+
2 rows in set (0.00 sec)
  • 保存配置文件:
mysql> save config;

添加节点

mysql> add slave 10.0.0.52:3306;
Empty set (0.00 sec)
mysql> SELECT * FROM backends;
+-------------+----------------+-------+------+
| backend_ndx | address        | state | type |
+-------------+----------------+-------+------+
|           1 | 10.0.0.55:3306 | down  | rw   |
|           2 | 10.0.0.53:3306 | up    | ro   |
|           3 | 10.0.0.52:3306 | down  | ro   |
+-------------+----------------+-------+------+
3 rows in set (0.00 sec)
mysql> save config;
Empty set (0.01 sec)

数据库查看负载情况

IP 功能
proxy-address = 0.0.0.0:33060 atlas代理的端口
admin-address = 0.0.0.0:2345 atlas管理节点的端口
mysql -umha -pmha -h127.0.0.1 -P33060
mysql>  show variables like "server_id";
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 3     |
+---------------+-------+
1 row in set (0.37 sec)
mysql>  show variables like "server_id";
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 2     |
+---------------+-------+
1 row in set (0.00 sec)
mysql>  show variables like "server_id";
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 3     |
+---------------+-------+
1 row in set (0.00 sec)

你可能感兴趣的:(Atlas)