原文:MySQL Scale Out

简介

MySQL复制中较常见的复制架构有“一主一从”、“一主多从”、“双主”、“多级复制”和“多主环形机构”等,见下图;

最常用,也最灵活的就要数“一主多从”复制架构了,其能满足多种需求,如:

  • 为不同的角色使用不同的备库(例如添加不同的索引或使用不同的存储引擎);

  • 把一台备库当做待用的主库,除了复制没有其它数据传输;

  • 将一台备库放在远程数据中心,用作灾难恢复;

  • 延迟一个或多个备库,以备灾难恢复;

  • 使用其中一个备库,作为备份、培训、开发或者测试使用服务器;

而“双主”复制架构则用于特殊的场景下,如两个处于不同地理位置的办公室,且都需要一份可写的数据拷贝;

这种架构最大的问题是如何解决数据冲突和不一致,尤其当两台服务器同时修改同一行记录,或同时在两台服务器上向一个包含auto_increment列的表里插入数据时;

而通过将一台服务器设置为只读的被动服务器,则可以很好的避免数据写入冲突的问题,这种主动-被动模式下的主-主复制架构使得反复切换主动和被动服务器非常方便,可以实现在不关闭服务器的情况下执行维护、优化表、升级操作系统或其他任务;

配置主动-被动模式的主-主复制架构的一般流程:

  • 确保两台服务器上有相同的数据;

  • 启用二进制日志,选择唯一的服务器ID,并创建复制账号;

  • 启用备库更新的日志记录,这是故障转移和故障恢复的关键;

  • 把被动服务器配置成只读,防止可能与主动服务器上的更新产生冲突;

  • 启动每个服务器的MySQL实例;

  • 将每个主库设置为对方的备库,使用新创建的二进制日志开始工作;

同时为了消除不同地理位置的站点单点故障问题,可以为每个主库增加冗余,即为每一个主库增加一个从库;

而MMM(=Master-Master Replication Manager for MySQL)则是一套脚本集合,用以监控、管理双主复制架构,通过设置一个可写的VIP和多个只读的VIP,完成故障自动转移、读负载分摊等功能;

架构设计

服务器规划

虚IP规划

配置部署

双主复制架构部署

MySQL或MariaDB的安装初始化可详见博客“MySQL架构

利用mysqld_multi在一台主机上启动多个mysqld实例

数据库初始化

  1. # 在主机Host1和Host2上
  2. cd /usr/local/mysql
  3. scripts/mysql_install_db --user=mysql --datadir=/data/mariadb_data_3406/
  4. scripts/mysql_install_db --user=mysql --datadir=/data/mariadb_data_3506/

数据库配置

  1. # 在主机Host1上
  2. vi /etc/my.cnf
  3. [mysqld_multi]
  4. mysqld = /usr/local/mysql/bin/mysqld_safe
  5. mysqladmin = /usr/local/mysql/bin/mysqladmin
  6. [mysqld1]
  7. port =
  8. socket = /tmp/mysql3406.sock
  9. skip-external-locking
  10. key_buffer_size = 256M
  11. max_allowed_packet = 1M
  12. table_open_cache =
  13. sort_buffer_size = 1M
  14. read_buffer_size = 1M
  15. read_rnd_buffer_size = 4M
  16. myisam_sort_buffer_size = 64M
  17. thread_cache_size =
  18. query_cache_size= 16M
  19. thread_concurrency =
  20. datadir = /data/mariadb_data_3406
  21. innodb_file_per_table =
  22. default_storage_engine = InnoDB
  23. log-bin=mysql-bin
  24. relay-log=/data/relaylogs_3406/relay-bin # 指定中继日志路径
  25. log_slave_updates= # 开启从库更新操作写入二进制日志功能
  26. auto_increment_increment= # 双主复制中自增长字段的步长
  27. auto_increment_offset= # 双主复制中自增长字段的起始值,此为1
  28. sync_binlog = # 可保证事务日志及时写入磁盘文件
  29. binlog_format=row
  30. server-id = # 注意server-id的唯一性
  31. [mysqld2]
  32. port =
  33. socket = /tmp/mysql3506.sock
  34. skip-external-locking
  35. key_buffer_size = 256M
  36. max_allowed_packet = 1M
  37. table_open_cache =
  38. sort_buffer_size = 1M
  39. read_buffer_size = 1M
  40. read_rnd_buffer_size = 4M
  41. myisam_sort_buffer_size = 64M
  42. thread_cache_size =
  43. query_cache_size= 16M
  44. thread_concurrency =
  45. datadir = /data/mariadb_data_3506
  46. innodb_file_per_table =
  47. default_storage_engine = InnoDB
  48. log-bin=mysql-bin
  49. relay-log=/data/relaylogs_3506/relay-bin
  50. log_slave_updates=
  51. sync_binlog =
  52. binlog_format=row
  53. server-id =
  54. # 在主机Host2上
  55. vi /etc/my.cnf
  56. [mysqld_multi]
  57. mysqld = /usr/local/mysql/bin/mysqld_safe
  58. mysqladmin = /usr/local/mysql/bin/mysqladmin
  59. [mysqld1]
  60. port =
  61. socket = /tmp/mysql3406.sock
  62. skip-external-locking
  63. key_buffer_size = 256M
  64. max_allowed_packet = 1M
  65. table_open_cache =
  66. sort_buffer_size = 1M
  67. read_buffer_size = 1M
  68. read_rnd_buffer_size = 4M
  69. myisam_sort_buffer_size = 64M
  70. thread_cache_size =
  71. query_cache_size= 16M
  72. thread_concurrency =
  73. datadir = /data/mariadb_data_3406
  74. innodb_file_per_table =
  75. default_storage_engine = InnoDB
  76. log-bin=mysql-bin
  77. relay-log=/data/relaylogs_3406/relay-bin
  78. log_slave_updates=
  79. auto_increment_increment= # # 双主复制中自增长字段的步长
  80. auto_increment_offset= # 双主复制中自增长字段的起始值,此为2
  81. sync_binlog =
  82. binlog_format=row
  83. server-id =
  84. [mysqld2]
  85. port =
  86. socket = /tmp/mysql3506.sock
  87. skip-external-locking
  88. key_buffer_size = 256M
  89. max_allowed_packet = 1M
  90. table_open_cache =
  91. sort_buffer_size = 1M
  92. read_buffer_size = 1M
  93. read_rnd_buffer_size = 4M
  94. myisam_sort_buffer_size = 64M
  95. thread_cache_size =
  96. query_cache_size= 16M
  97. thread_concurrency =
  98. datadir = /data/mariadb_data_3506
  99. innodb_file_per_table =
  100. default_storage_engine = InnoDB
  101. log-bin=mysql-bin
  102. relay-log=/data/relaylogs_3506/relay-bin
  103. log_slave_updates=
  104. sync_binlog =
  105. binlog_format=row
  106. server-id =

启动数据库实例

  1. # 在主机Host1和Host2上
  2. /etc/init.d/mysqld_multi start # 停止服务操作是/etc/init.d/mysqld_multi stop
  3. /etc/init.d/mysqld_multi start # 停止服务操作是/etc/init.d/mysqld_multi stop

登录数据库

  1. # 在主机Host1和Host2上
  2. mysql -S /tmp/mysql3406.sock # 登录master1或master2
  3. mysql -S /tmp/mysql3506.sock # 登录slave1或slave2

创建所需账户(在Master1实例上)

  1. grant replication client on *.* to '3m_moni'@'192.168.0.%' identified by '3m_12345'; # 创建MMM的监控账户
  2. grant super,replication client,process on *.* to '3m_agen'@'192.168.0.%' identified by '3m_12345'; # 创建MMM的代理账户
  3. grant replication slave on *.* to '3m_repl'@'192.168.0.%' identified by '3m_12345'; # 创建复制账户

配置数据同步

  1. # 每次从库连接主库前,需先查询对应主库的二进制日志文件及其事件位置,即在主库上执行show master status即可,据此决定从库连接时的master_log_file和master_log_pos参数;
  2. # slave1实例上
  3. change master to master_host='192.168.0.45',master_port=,master_user='3m_repl',master_password='3m_12345',master_log_file='mysql-bin.000001',master_log_pos=;
  4. # master2实例上
  5. change master to master_host='192.168.0.45',master_port=,master_user='3m_repl',master_password='3m_12345',master_log_file='mysql-bin.000002',master_log_pos=;
  6. # slave2实例上
  7. change master to master_host='192.168.0.46',master_port=,master_user='3m_repl',master_password='3m_12345',master_log_file='mysql-bin.000004',master_log_pos=;
  8. # master1实例上
  9. change master to master_host='192.168.0.46',master_port=,master_user='3m_repl',master_password='3m_12345',master_log_file='mysql-bin.000004',master_log_pos=;

查看同步状态

  1. # 重点检查Slave_IO_Running、Slave_SQL_Running和Master_Server_Id等参数
  2. MariaDB [(none)]> show slave status\G
  3. *************************** . row ***************************
  4. Slave_IO_State: Waiting for master to send event
  5. Master_Host: 192.168.0.45
  6. Master_User: 3m_repl
  7. Master_Port:
  8. Connect_Retry:
  9. Master_Log_File: mysql-bin.
  10. Read_Master_Log_Pos:
  11. Relay_Log_File: relay-bin.
  12. Relay_Log_Pos:
  13. Relay_Master_Log_File: mysql-bin.
  14. Slave_IO_Running: Yes
  15. Slave_SQL_Running: Yes
  16. Master_Server_Id:

MMM安装部署

Host1主机上:部署agent和monitor

  1. yum -y install mysql-mmm-*
  2. # 配置公共设置
  3. vi /etc/mysql-mmm/mmm_common.conf
  4. active_master_role writer
  5. <host default>
  6. cluster_interface eth0
  7. pid_path /var/run/mysql-mmm/mmm_agentd.pid
  8. bin_path /usr/libexec/mysql-mmm/
  9. replication_user 3m_repl# 复制账户
  10. replication_password 3m_12345# 复制账户密码
  11. agent_user 3m_agen# agent账户
  12. agent_password 3m_12345# agent账户密码
  13. </host>
  14. <host db1>
  15. ip 192.168.0.45
  16. mysql_port # 可指定需连接的mysqld的端口
  17. mode master
  18. peer db2# peer表示db1、db2是同等级别的
  19. </host>
  20. <host db2>
  21. ip 192.168.0.46
  22. mysql_port
  23. mode master
  24. peer db1
  25. </host>
  26. <host db3>
  27. ip 192.168.0.45
  28. mysql_port
  29. mode slave
  30. </host>
  31. <host db4>
  32. ip 192.168.0.46
  33. mysql_port
  34. mode slave
  35. </host>
  36. <role writer>
  37. hosts db1, db2
  38. ips 192.168.0.11# 可写VIP只配置一个
  39. mode exclusive# 表示排它
  40. </role>
  41. <role reader>
  42. hosts db1, db2,db3,db4
  43. ips 192.168.0.12,192.168.0.13,192.168.0.14,192.168.0.15 # 只读VIP可配置多个
  44. mode balanced# 表示可以共用
  45. </role>
  46. ==========
  47. scp mmm_common.conf 192.168.0.46:/etc/mysql-mmm/ # 将公共配置文件拷贝至其它主机
  48. ==========
  49. # 配置监控设置
  50. vi /etc/mysql-mmm/mmm_mon.conf
  51. include mmm_common.conf
  52. <monitor>
  53. ip 127.0.0.1
  54. pid_path /var/run/mysql-mmm/mmm_mond.pid
  55. bin_path /usr/libexec/mysql-mmm
  56. status_path /var/lib/mysql-mmm/mmm_mond.status
  57. ping_ips 192.168.0.45,192.168.0.46# 健康监测时需ping的主机IP,不是VIP哦
  58. auto_set_online
  59. </monitor>
  60. <host default>
  61. monitor_user 3m_moni# 监控账户
  62. monitor_password 3m_12345 # 监控账户密码
  63. </host>
  64. debug
  65. # 配置agent设置
  66. vi /etc/mysql-mmm/mmm_agent.conf
  67. include mmm_common.conf
  68. this db1# 因为在一台主机上启用了2个mysqld实例,故可配置2个this参数哦
  69. this db3

Host2主机上:只需部署agent

  1. yum -y install mysql-mmm-agent
  2. # 配置agent设置
  3. vi /etc/mysql-mmm/mmm_agent.conf
  4. include mmm_common.conf
  5. this db2
  6. this db4

服务启动

  1. # 在主机Host1上
  2. [root@mysql mysql-mmm]# mmm_control show
  3. db1(192.168.0.45) master/ONLINE. Roles: reader(192.168.0.14), writer(192.168.0.11)
  4. db2(192.168.0.46) master/ONLINE. Roles: reader(192.168.0.13)
  5. db3(192.168.0.45) slave/ONLINE. Roles: reader(192.168.0.15)
  6. db4(192.168.0.46) slave/ONLINE. Roles: reader(192.168.0.12)

测试验证

查看双主复制架构中基于MMM实现的状态信息

  1. # 在主机Host1上
  2. [root@mysql mysql-mmm]# mmm_control show
  3. db1(192.168.0.45) master/ONLINE. Roles: reader(192.168.0.14), writer(192.168.0.11)
  4. db2(192.168.0.46) master/ONLINE. Roles: reader(192.168.0.13)
  5. db3(192.168.0.45) slave/ONLINE. Roles: reader(192.168.0.15)
  6. db4(192.168.0.46) slave/ONLINE. Roles: reader(192.168.0.12)

手动进行各节点的健康监测

  1. # 在主机Host1上
  2. [root@mysql mysql-mmm]# mmm_control checks
  3. db4 ping [last change: // ::] OK
  4. db4 mysql [last change: // ::] OK
  5. db4 rep_threads [last change: // ::] OK
  6. db4 rep_backlog [last change: // ::] OK: Backlog is null
  7. db2 ping [last change: // ::] OK
  8. db2 mysql [last change: // ::] OK
  9. db2 rep_threads [last change: // ::] OK
  10. db2 rep_backlog [last change: // ::] OK: Backlog is null
  11. db3 ping [last change: // ::] OK
  12. db3 mysql [last change: // ::] OK
  13. db3 rep_threads [last change: // ::] OK
  14. db3 rep_backlog [last change: // ::] OK: Backlog is null
  15. db1 ping [last change: // ::] OK
  16. db1 mysql [last change: // ::] OK
  17. db1 rep_threads [last change: // ::] OK
  18. db1 rep_backlog [last change: // ::] OK: Backlog is null 

补充说明

  • 在本篇的演示案例中,前端程序若要与MySQL通信,则写库需连接192.168.0.11:3406,读库可连接192.168.0.12-15中的一个或多个,端口可能是3406或3506;

  • 在只读VIP漂移时,会导致前端程序连接的mysqld端口发生变化,所以生产环境下还是统一使用3306端口为宜;

  • 利用MMM实现了双主复制架构中的故障自动转移后,mysql并非直接与前端程序通信,还需配合使用读写分离器(如Ameoba),以统一对外的连接地址,由读写分离器负责读写的向下分配;

MySQL Scale Out的更多相关文章

  1. (转)使用Amoeba 实现MySQL DB 读写分离

    Amoeba(变形虫)项目是一个开源框架,于2008年开始发布一款 Amoeba for Mysql软件: 这个软件致力于MySQL的分布式数据库前端代理层,它主要在应用层访问MySQL的时候充当SQ ...

  2. 使用Amoeba 实现MySQL DB 读写分离

    Amoeba(变形虫)项目是一个开源框架,于2008年开始发布一款 Amoeba for Mysql软件: 这个软件致力于MySQL的分布式数据库前端代理层,它主要在应用层访问MySQL的时候充当SQ ...

  3. Amoeba是一个类似MySQL Proxy的分布式数据库中间代理层软件,是由陈思儒开发的一个开源的java项目

    http://www.cnblogs.com/xiaocen/p/3736095.html amoeba实现mysql读写分离 application  shang  2年前 (2013-03-28) ...

  4. Kubernetes 中部署 MySQL 集群

    文章转载自:https://www.cnblogs.com/ludongguoa/p/15319861.html 一般情况下 Kubernetes 可以通过 ReplicaSet 以一个 Pod 模板 ...

  5. most queries (more than 90 percent) never hit the database at all but only touch the cache layer

    https://gigaom.com/2011/12/06/facebook-shares-some-secrets-on-making-mysql-scale/ Facebook shares so ...

  6. 交付Dubbo微服务到kubernetes集群

    1.基础架构 1.1.架构图 Zookeeper是Dubbo微服务集群的注册中心 它的高可用机制和k8s的etcd集群一致 java编写,需要jdk环境 1.2.节点规划 主机名 角色 ip hdss ...

  7. CSS动画划入划出酷炫

    HTML插入 <!DOCTYPE html> <html class="no-js iarouse"> <head> <meta char ...

  8. [转载]大型网站应用中 MySQL 的架构演变史

    没有什么东西是一成不变的,包含我们的理想和生活!MySQL作为一个免费的开源的关系型数据库,深受大家喜爱,从最初的无人问津到当下的去IOE,都体现出了MySQL举足轻重的作用.今天我们就从淘宝的发展来 ...

  9. MySQL的数据模型

    MySQL的数据类型主要分为三大类: 数值型(Numeric Type) 日期与时间型(Date and Time Type) 字符串类型(String Type) 1. 数值 MySQL的数值类型按 ...

随机推荐

  1. MySql语句大全:创建、授权、查询、修改等(转)

    林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 一.用户创建.权限.删除 1.连接MySql操作 连接:mysql -h 主机地址 -u 用户 ...

  2. 转: 第二章 IoC Annotation注入

    http://blog.csdn.net/p_3er/article/details/9231307 1.命名空间 使用Annotation的方式,需要在spring的配置文件中配置命名空间.命名空间 ...

  3. Android 省市县 三级联动(android-wheel的使用)

    转载请注明出处:http://blog.csdn.net/lmj623565791/article/details/23382805 今天没事跟群里面侃大山,有个哥们说道Android Wheel这个 ...

  4. [站点部署_01]wordpress建站网页响应速度慢

    最近可能非常多人发现站点打开速度变慢.这里分享一下该问题的定位方法. 我在本地部署了一个wordpress站点,近几天突然发现站点訪问速度奇慢,实在不能忍.于是採用例如以下方法攻克了这个问题: 1)使 ...

  5. 高仿淘宝送货地址暴走漫画系列(附demo)

    演讲: 我是个程序员,一天我坐在路边一边喝水一边苦苦检查bug. 这时一个乞丐在我边上坐下了,開始要饭,我认为可怜.就给了他1块钱. 然后接着调试程序.他可能生意不好,就无聊的看看我在干什么.然后过了 ...

  6. 《Javascript权威指南》13号学习笔记:使用日期和时间

    一.创Date示例 1.Date类的方法和属性是非常不静,故,申请书Date属性和方法之前.必须创建Date类的实例. var date = new Date();  //以当前日期和时间创建实例. ...

  7. Mac OS温馨提示17:七彩花哨的输入

    OSX Mavericks中国的文字输入功能,色于windows,甚至提供了强大的手写输入功能和语音输入功能,而且发展到如今,已经有非常多种第三方输入法支持Mac了. 一.主要的输入法        ...

  8. 物理卷操作命令:pvcreate,pvscan,pvdisplay.卷组操作命令:vgcreate,vgdisplay. (转)

    新硬盘创建LVM系统过程. 物理卷操作命令:pvcreate,pvscan,pvdisplay. 卷组操作命令:vgcreate,vgdisplay. 逻辑卷操作命令:lvcreate,lvdispl ...

  9. POJ3090_Visible Lattice Points【欧拉函数】

    Visible Lattice Points Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 5653 Accepted: 333 ...

  10. Ajax基础知识(一)

    随便在百度谷歌上输入Ajax都会出现一大堆的搜索结果,这已经不再是什么新奇的技术了.但若从一开始就学习了ASP.Net,使用功能齐全的Visual Studio集成开发工具,或许未必能对访问一个动态网 ...