zoukankan      html  css  js  c++  java
  • 数据切分——Atlas读写分离Mysql集群的搭建

            关于数据切分的原理可以参见博客:

            http://blog.csdn.net/jhq0113/article/details/44226789

           

            关于Atlas的介绍可以参见博客:

            http://blog.csdn.net/jhq0113/article/details/44239823


                     Atlas源代码用C语言编写,它对于Web Server相当于是DB,相对于DB相当于是Client,如果把Atlas的逻辑放到Web Server程序里去处理,这样会大大增加Web Server程序的复杂度,同时Web Server和DB之间的耦合度也相当高,因为只要DB增加/减少服务,Web Server就有可能要发生代码改变,若代码不改变,就得通过中间关系表与心跳机制来维护Server之间的关系,这样会带来性能的损耗,而Atlas是架设在Web Server与DB之间的一个中间件,Web Server与DB之间的耦合关系放到了Atlas来处理,既做到了灵活也保留了性能,这也是Atlas存在的价值。


            Atlas支持表的水平切分,支持读写分离,对数据实时性要求较高的项目可以在select语句前增加/*master*/强制读主库,主从MySql数据库之间数据的同步需要自己配置,主从MySql数据库数据主从复制的配置方法参见博客:

            http://blog.csdn.net/jhq0113/article/details/44263367

             

            1.安装

             注意:只能安装在64位的Linux操作系统上,CentOS官方建议rpm安装方式

             获取地址:https://github.com/Qihoo360/Atlas/releases

             目前最新的版本为:

              Atlas-2.2.1.el5.x86_64.rpm                      CentOS 5.*  版本

              Atlas-2.2.1.el6.x86_64.rpm                      CentOS 6.*  版本

              

             我的环境是CentOS 6.6 Basic Server x86_64

              

             安装命令:

             [root@jhq0229 src]# rpm -i Atlas-2.2.1.el6.x86_64.rpm

             

             安装位置:

             /usr/local/mysql-proxy

             配置文件:

             /usr/local/mysql-proxy/conf/test.cnf

            

             重要配置文件详解:

             (1)线程数

             event-threads项设置,过小无法充分发挥多核CPU的性能,过大造成不必要的线程切换开销,推荐设置为CPU的核数。

          (2)最小空闲连接数(2.x以上版本不需要该项,1.x版本需要)

             min-idle-connections项设置,过小则在高并发下会有报错,过大虽然不报错但在测试时不容易看出读写分离效果,推荐设置为比客户端的并发峰值稍大,详见《配置参数详解》。上面的配置范例是针对Atlas 2.X版本,没有该选项。对于Atlas 1.X版本的配置文件,需要加入该配置选项

          (3)Atlas的工作端口

             proxy-address项配置,例如proxy-address = 0.0.0.0:1234代表客户端应该使用1234这个端口连接Atlas来发送SQL请求。

         (4)Atlas的管理端口

             admin-address项配置,例如admin-address = 0.0.0.0:2345代表DBA应该使用2345这个端口连接Atlas来执行运维管理操作。

        (5)管理接口的用户名和密码

            admin-username项和admin-password项设置,这两项是用来进入Atlas的管理界面的,与后端连接的MySQL没有关系,所以可以任意设置,不需要MySQL在配置上做任何改动。

       (6)日志级别

            以log-level项配置,分为message、warning、critical、error、debug五个级别。

       (7)日志路径

           以log-path项配置,如log-path = /usr/local/mysql-proxy/log。

       (8)主库的IP和端口

           proxy-backend-addresses = 192.168.0.12:3306

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

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

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

          pwds = myuser: HJBoxfRsjeI=,myuser2:HJBoxfRsjeI=

     (11)分表设置,此例中person为库名,mt为表名,id为分表字段,3为子表数量,可设置多项,以逗号分隔,若不分表则不需要设置该项,子表需要事先建好,子表名称为表名_数字,数字范围为[0,子表数-1],如本例里,子表名称为mt_0、mt_1、mt_2

        tables = person.mt.id.3


       我的配置:

       

    [plain] view plain copy
     print?在CODE上查看代码片派生到我的代码片
    1. [mysql-proxy]  
    2.   
    3. #管理接口的用户名  
    4. admin-username = user  
    5.   
    6. #管理接口的密码  
    7. admin-password = pwd  
    8.   
    9. #Atlas后端连接的MySQL主库的IP和端口,可设置多项,用逗号分隔  
    10. proxy-backend-addresses = 192.168.1.18:3306  
    11.   
    12. #从库  
    13. proxy-read-only-backend-addresses = 192.168.1.16:3306@1  
    14. #用户名和密码配置项,需要和主从复制配置的用户名和密码配置一样  
    15. #pwds = user1:+jKsgB3YAG8=, user2:GS+tr4TPgqc=  
    16. pwds = mastt:/iZxz+0GRoA=  
    17.   
    18. #后台运行  
    19. daemon = true  
    20.   
    21. keepalive = true  
    22.   
    23. #工作线程数,对Atlas的性能有很大影响,可根据情况适当设置  
    24. event-threads = 8  
    25.   
    26. #日志级别,分为message、warning、critical、error、debug五个级别  
    27. log-level = message  
    28.   
    29. #日志存放的路径  
    30. log-path = /usr/local/mysql-proxy/log  
    31.   
    32. #SQL日志的开关,可设置为OFF、ON、REALTIME,OFF代表不记录SQL日志,ON代表记录SQL日志,REALTIME代表记录SQL日>志且实时写入磁盘,默认为OFF  
    33. #sql-log = OFF  
    34.   
    35. #慢日志输出设置。当设置了该参数时,则日志只输出执行时间超过sql-log-slow(单位:ms)的日志记录。不设置该参数  
    36. 则输出全部日志。  
    37. #sql-log-slow = 10  
    38.   
    39. #实例名称,用于同一台机器上多个Atlas实例间的区分  
    40. #instance = test  
    41.   
    42. #Atlas监听的工作接口IP和端口  
    43. proxy-address = 192.168.1.18:8060  
    44.   
    45. #Atlas监听的管理接口IP和端口  
    46. admin-address = 192.168.1.18:2345  
    47.   
    48. #分表设置,此例中person为库名,mt为表名,id为分表字段,3为子表数量,可设置多项,以逗号分隔,若不分表则不需  
    49. 要设置该项  
    50. #tables = person.mt.id.3  
    51. tables=orders.my_orders.year.2015  
    52.   
    53. #默认字符集,设置该项后客户端不再需要执行SET NAMES语句  
    54. charset = utf8  
    55.   
    56. #允许连接Atlas的客户端的IP,可以是精确IP,也可以是IP段,以逗号分隔,若不设置该项则允许所有IP连接,否则只允  
    57. 许列表中的IP连接  
    58. #client-ips = 127.0.0.1, 192.168.1  
    59.   
    60. #Atlas前面挂接的LVS的物理网卡的IP(注意不是虚IP),若有LVS且设置了client-ips则此项必须设置,否则可以不设置  
    61. #lvs-ips = 192.168.1.1  


    从以上配置可以清楚看到:

    主库:192.168.1.18:3306

    从库:192.168.1.16:3306    权重为1

    注意:主从复制需要自行配置。

     

    Atlas Proxy的ip和端口为:192.168.1.18:8060

    主从复制的用户和密码为:mastt     123456,以上的pwds的密码是经过加密处理的

    若用Navicat登陆,就用Atlas Proxy的ip和端口,用户名和密码用主从复制的,主从复制的账户需要设置可以在Navicat上登陆。


    分表配置项:

    [plain] view plain copy
     print?在CODE上查看代码片派生到我的代码片
    1. tables=orders.my_orders.year.2015  

    我的主从库名称是orders,里有三张表,分别是my_orders_0,my_orders_1,my_orders_2,按year字段进行分表,虽然分了2015张表,但是你的数据库里不一定有这么多张表,这里的2015只是取模的一个基数,按照此规律去找到相应的表,例如year=2015,数据请求会发送到my_orders_0表。


    编写简单Atlas的启动脚本:

    [root@jhq0229 ~]# vim /etc/init.d/atlas


    内容如下:

    [plain] view plain copy
     print?在CODE上查看代码片派生到我的代码片
    1. #!/bin/sh  
    2. #  
    3. #atlas:    Atlas Daemon  
    4. #  
    5. # chkconfig:    - 90 25  
    6. # description:  Atlas Daemon  
    7. #  
    8. # Source function library.  
    9. start()  
    10. {  
    11.         echo -n $"Starting atlas: "  
    12.         /usr/local/mysql-proxy/bin/mysql-proxyd test start  
    13.         echo   
    14. }  
    15. stop()  
    16. {  
    17.         echo -n $"Shutting down atlas: "  
    18.         /usr/local/mysql-proxy/bin/mysql-proxyd test stop  
    19.         echo  
    20. }  
    21. ATLAS="/usr/local/mysql-proxy/bin/mysql-proxyd"  
    22. [ -f $ATLAS ] || exit 1  
    23. # See how we were called.  
    24. case "$1" in  
    25.         start)  
    26.                 start  
    27.                 ;;  
    28.         stop)  
    29.                 stop  
    30.                 ;;  
    31.         restart)  
    32.                 stop  
    33.                 sleep 3  
    34.                 start  
    35.                 ;;  
    36.         *)  
    37.                 echo $"Usage: $0 {start|stop|restart}"  
    38.                 exit 1  
    39. esac  
    40. exit 0  

    授权并加入开机启动

    [root@jhq0229 ~]# chmod +x /etc/init.d/atlas
    [root@jhq0229 ~]# chkconfig atlas on


    启动atlas服务

    [root@jhq0229 ~]# service atlas start


    2.功能测试:

    1).利用mastt用户123456密码Navicat登陆到192.168.1.18:8060查看数据库表,开始数据库中没有数据。

    表结构如下:

    1. CREATE TABLE `my_orders_0` (  
    2.   `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '表主键',  
    3.   `pid` int(10) unsigned NOT NULL COMMENT '产品ID',  
    4.   `price` decimal(15,2) NOT NULL COMMENT '单价',  
    5.   `num` int(11) NOT NULL COMMENT '购买数量',  
    6.   `person` varchar(255) NOT NULL COMMENT '客户姓名',  
    7.   `atime` int(10) unsigned NOT NULL COMMENT '下单时间',  
    8.   `utime` int(10) unsigned NOT NULL COMMENT '修改时间',  
    9.   `isdel` tinyint(4) NOT NULL DEFAULT '0' COMMENT '软删除标识',  
    10.   `yearsmallint(5) unsigned NOT NULL COMMENT '年',  
    11.   PRIMARY KEY (`id`)  
    12. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;  

    插入数据

    1. INSERT INTO `my_orders`(`pid`,`price`,`num`,`person`,`atime`,`utime`,`year`) VALUES ('1''123.54''1''周润发''1426335606''1426335606','2015');  
    2. INSERT INTO `my_orders`(`pid`,`price`,`num`,`person`,`atime`,`utime`,`year`) VALUES ('3''13.67''4''周迅''1426338765''1426338765''2016');  
    3. INSERT INTO `my_orders`(`pid`,`price`,`num`,`person`,`atime`,`utime`,`year`) VALUES ('4''44.44''4''郭敬明''1426754324''1426754324','2017');  

    此时我们会看到my_orders_0,1,2表中分别有一条数据,15年的在0表,16年在1表,17年的在2表。


    查询测试,如果不指定表的全名,查询时需要year字段作为where条件,否则不会通过,测试结果如下图:

           


    读写分离测试,为了达到测试效果,我们在从库的my_orders_0表手动添加一条数据,语句如下:

    1. INSERT INTO `my_orders_0`(`pid`,`price`,`num`,`person`,`atime`,`utime`,`year`) VALUES ('2''212.54''1''梁朝伟''1426335606''1426335606','2015');  

    此时,主库的0表只有一条数据,从表里有两条数据,如果我们执行查询语句

    SELECT * FROM my_orders WHERE `year`=2015出现一条结果,则都的是主库,若出现两条则为从库,结果如下图:

            


    证明已经读的是从库。


    测试强制读主库,若执行语句/*master*/ SELECT * FROM my_orders WHERE `year`=2015有两条记录则读的是从库,如果是一条记录都的是主库,测试结果只有周润发一条记录。


    至此,Atlas的配置完毕,如果将Atlas与Mysql表的分区联合使用可以大大提高大数据的处理能力,希望可以帮助到你。


  • 相关阅读:
    轻重搭配
    EF的优缺点
    使用bootstrap-select有时显示“Nothing selected”
    IIS发布 HTTP 错误 500.21
    js添加的元素无法触发click事件
    sql server查看表是否死锁
    sql server把一个库表的某个字段更新到另一张表的相同字段
    SQLSERVER排查CPU占用高的情况
    SQL server中如何按照某一字段中的分割符将记录拆成多条
    LINQ to Entities does not recognize the method 'System.DateTime AddDays(Double)' method, and this method cannot be translated into a store expression.
  • 原文地址:https://www.cnblogs.com/duyinqiang/p/5696356.html
Copyright © 2011-2022 走看看