Mysql 用中间件atlas进行读写分离(学习笔记十四)
〇 Atlas架构介绍 Atlas是Qihoo360开发的一个中间件,位于Client和MySQL Server中间层,可以作为读写分离,分库分表中间件。 对于MySQL Server而言,Atlas像是个Client,而对于Client而言,Atlas则是一个DB server。 〇 实验结构 OS: CentOS 6.5 64bit MySQL version: 5.6.30 Master:192.168.1.185 Slave:192.168.1.186 proxy(Atlas):192.168.1.187 客户端:192.168.1.192 〇MySQL部分: (主从建立步骤略) 主/从上建立具有增删改查账号: GRANT SELECT, INSERT, UPDATE, DELETE ON *.* TO 'dev'@'192.168.1.187' IDENTIFIED BY 'dev'; FLUSH PRIVILEGES; 从库上可以设置: SET GLOBAL read_only=1; 如果该从库永远不用做master,可以写到配置文件中。 〇Atlas部分: Atlas开发者给出部分建议: 1、Atlas只能运行在64bit的发行版本上 2、若曾经安装过,在新安装时会报错:如“file /usr/local/mysql-proxy/bin/encrypt from install of Atlas-2.0.1-1.x86_64 conflicts with file from package Atlas-1.0.3-1.x86_64”,此时需要sudo rpm –e Atlas-1.0.3-1.x86_64,再执行新的安装。 3、建议使用MySQL 5.6,此外,不宜小于MySQL 5.1 在proxy机上安装Atlas: 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 通过rpm包安装方式,默认的配置文件在 /usr/local/mysql-proxy/conf/test.cnf 首先可以先获取一下之前步骤中,dev@'192.168.1.187'这个用户加密后的密码: # /usr/local/mysql-proxy/bin/encrypt dev A2OS3vFVUmY= 因为之前给dev用户的密码的明文是dev,所以此处也对dev加密,加密后的密码输出在其后,也就是A2OS3vFVUmY=这个密码稍后要添加到Atlas配置文件中。 test.cnf配置文件内容可以参考这个: [mysql-proxy] # 基础设置 # 以守护进程方式启动 daemon = true #设置atlas的运行方式,若为true,则表示多一个monitor,该进程会在woker进程挂掉后将其重启。若为false,则只有一个工作进程woker。 keepalive = true # atlas实例名,便于区分一台机子上的不同atlas instance = test # 工作线程数,atlas开发人员推荐将其设置为CPU个数的2~4倍。 event-threads = 8 # SQL日志的开关,共有三个可选项:OFF、ON、REALTIME,分别为:不记录sql日志、记录sql日志,并等待缓冲区填满后,才会落地到磁盘、记录sql日志并实时写入磁盘。 sql-log = OFF # 等同于客户端连接到mysql-server后输入SET names utf8; charset = utf8 # 如果这样配置,可以通过mysql -h127.0.0.1 -P2345 -uadmin -padmin可以连接到Atlas管理界面 admin-username = admin admin-password = admin # 该参数设置Atlas后台管理地址和端口 admin-address = 192.168.1.187:2345 # 设置主库和从库的地址,其中主库为写库,从库为只读库 # 主库地址 proxy-backend-addresses = 192.168.1.185:3306 # 设置读库地址和端口 proxy-read-only-backend-addresses = 192.168.1.186:3306 # 若配置为主库也分担读请求,并且设置权重为 (主:从)=(1:3),则可以写作 #proxy-read-only-backend-addresses = 192.168.1.185:3306@1, 192.168.1.186:3306@3 # 设置Atlas工作监听的地址和端口,应用程序将连接到这个地址,既然客户端把Atlas当做一个mysql-server,故此处直接写成3306端口 proxy-address = 192.168.1.187:3306 # 设置用户的密码(这个密码为MySQL中dev用户通过Atlas加密程序加密后的密码),多个可以用逗号隔开 pwds = dev:A2OS3vFVUmY= # 设置Atlas日志信息,其中log-level有message、warning、critical、error、debug五个级别 log-level = message # 日志存放的路径,日志名为$instance_name.log,比如$log-path/test.log log-path = /usr/local/mysql-proxy/log # 设置允许连接Atlas的客户端ip,非必须,可以是多个,可以是精准ip也可以是ip段,比如: #client-ips = 127.0.0.1, 192.168.1 #挂接lvs的物理网卡ip,若有lvs结构,且设置了client-ips,则必须设置此项,反之可不设置。 #lvs-ips = 192.168.1.1 配置好后,直接启动就好: /usr/local/mysql-proxy/bin/mysql-proxyd test start 其中test为配置文件中instance的值。 当然可以检查一下是否已经启动成功: /usr/local/mysql-proxy/bin/mysql-proxydteststatus MySQL-Proxyoftestis running(5176) MySQL-Proxyoftestis running(5177) 比如这样就可以连接到Atlas后台界面: mysql -h192.168.1.187 -P2345 -uadmin -padmin 进去之后可以查看当前配置的DBserver和状态。 mysql>SELECT*FROMbackends; +-------------+--------------------+-------+------+ |backend_ndx|address|state|type| +-------------+--------------------+-------+------+ |1 |192.168.1.185:3306|up|rw| |2|192.168.1.186:3306|up|ro| +-------------+--------------------+-------+------+ 2 rowsinset(0.00 sec) 当然更多的选项可以通过SELECT * FROM help;来获取: mysql> SELECT * FROM help; +----------------------------+---------------------------------------------------------+ | command| description| +----------------------------+---------------------------------------------------------+ | SELECT * FROM help| shows this help| | SELECT * FROM backends| lists the backends and their state| | SET OFFLINE $backend_id| offline backend server, $backend_id is backend_ndx's id | | SET ONLINE $backend_id| online backend server, ...| | ADD MASTER $backend| example: "add master 127.0.0.1:3306", ...| | ADD SLAVE $backend| example: "add slave 127.0.0.1:3306", ...| | REMOVE BACKEND $backend_id | example: "remove backend 1", ...| | SELECT * FROM clients| lists the clients| | ADD CLIENT $client| example: "add client 192.168.1.2", ...| | REMOVE CLIENT $client| example: "remove client 192.168.1.2", ...| | SELECT * FROM pwds| lists the pwds| | ADD PWD $pwd | example: "add pwd user:raw_password", ...| | ADD ENPWD $pwd| example: "add enpwd user:encrypted_password", ...| | REMOVE PWD $pwd| example: "remove pwd user", ...| | SAVE CONFIG| save the backends to config file| | SELECT VERSION| display the version of Atlas| +----------------------------+---------------------------------------------------------+ 其他参数: sql-log-slow=10 # 类似于mysql的long_query_time,如果设置了该选项,则日志只记录超过该值的日志记录,若没有添加这个参数选项,则表示全部记录,单位为ms wait-timeout=10 # Atlas会关闭超过该时间之后一直未活跃的连接,单位s tables=db_name.table_name.user_id.100 # 分表设置,其中格式为:【库名.表名.分表字段.子表数量】,若设置多项则用逗号分隔。注,子表必须已经存在,其中子表命名规则为:【表名_数字】,范围为【0,子表数量-1】,即百表为table_name_0 table_name_1...table_name_99。 〇测试: 为了方便看到请求是否读写分离,可以先在master & slave两个实例上打开general_log,并放入表中: SETGLOBAL log_output='TABLE'; SETGLOBAL general_log=on; master上创建一张测试表: master>CREATETABLEtest.a(idint); Query OK,0 rows affected(0.03 sec) 然后再到客户端(192.168.1.192)尝试对Atlas(192.168.1.187)发起增删改查请求: 此处写了一个php脚本来模拟请求: <?php $con=mysql_connect("192.168.1.187","dev","dev"); if(!$con){ die('connect error: '.mysql_error()); } mysql_select_db("my_db",$con); mysql_query("INSERT INTO test.a SELECT 1;"); mysql_query("UPDATE test.a SET id=222 WHERE id=1;"); mysql_query("DELETE FROM test.a WHERE id=222;"); mysql_query("INSERT INTO test.a SELECT 123456;"); mysql_query("SELECT count(1) FROM test.a;"); mysql_close($con); ?> 此处可以通过yum install -y php php-mysql来安装一下php相关依赖。 执行这个php脚本后,可以分别检查一下master(192.168.1.185)和从库(192.168.1.186)的general log: master>SELECTuser_host,argument ->FROM mysql.general_log ->WHERE user_host='dev[dev] @ [192.168.1.187]'; +-----------------------------+-------------------------------------+ |user_host|argument| +-----------------------------+-------------------------------------+ |dev[dev]@[192.168.1.187] |INSERTINTOtest.a SELECT 1| |dev[dev]@[192.168.1.187]|UPDATEtest.a SET id=222 WHERE id=1| |dev[dev]@[192.168.1.187]|DELETE FROMtest.a WHERE id=222 | |dev[dev]@[192.168.1.187]|INSERTINTOtest.a SELECT 123456 | +-----------------------------+-------------------------------------+ 4 rowsinset(0.00 sec) slave>SELECT user_host,argument ->FROM mysql.general_log ->WHERE user_host='dev[dev] @ [192.168.1.187]'; +-----------------------------+-----------------------------+ |user_host|argument| +-----------------------------+-----------------------------+ |dev[dev]@[192.168.1.187]|SELECT count(1)FROMtest.a| +-----------------------------+-----------------------------+ 1 rowsinset(0.00 sec) 最后再检查一下跑完这个php脚本后的test.a表的数据,是否和预期的一致: slave> SELECT * FROM test.a; +--------+ | id | +--------+ | 123456 | +--------+ 1 row in set (0.00 sec) 当然,显然是与预期一致。 显然Atlas作为proxy,已经将写请求提交给master(192.168.1.185),将读请求提交给slave(192.168.1.186)。 对于客户端和开发人员,只需要获取一个Atlas的服务器地址、端口、用户名及密码便可使用读写分离。 Atlas也可以实现分表功能,此处可自行翻阅Atlas Home。