2台主机极致实现双主复制架构及MMM

本文详细介绍了在2台主机上实现MySQL双主复制架构的过程,以及使用MMM进行管理和故障转移的方法。通过配置主动-被动模式,解决了数据冲突问题,并探讨了在不同地理位置的办公室中使用双主复制的优势。同时,提到了MMM如何提供故障自动转移和读负载分摊功能,以及在实际应用中需要注意的前端连接和读写分离器的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 简介

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

    wKioL1NpEgORcF2XAATJgegMOXY343.jpg

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

       

      架构设计

      wKioL1NpEpCy3ACaAANLNO70Ry8648.jpg

      服务器规划

      wKiom1NpEumSkjTxAANRsHszrDg860.jpg

      虚IP规划

      wKioL1NpEtqCa90KAAKmQ02Oj3k481.jpg

       

      配置部署

      双主复制架构部署

      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/

      数据库配置

       

      001. # 在主机Host1上
      002. vi /etc/my.cnf
      003. [mysqld_multi]
      004. mysqld = /usr/local/mysql/bin/mysqld_safe
      005. mysqladmin = /usr/local/mysql/bin/mysqladmin
      006. [mysqld1]
      007. port = 3406
      008. socket = /tmp/mysql3406.sock
      009. skip-external-locking
      010. key_buffer_size = 256M
      011. max_allowed_packet = 1M
      012. table_open_cache = 256
      013. sort_buffer_size = 1M
      014. read_buffer_size = 1M
      015. read_rnd_buffer_size = 4M
      016. myisam_sort_buffer_size = 64M
      017. thread_cache_size = 8
      018. query_cache_size= 16M
      019. thread_concurrency = 2
      020. datadir = /data/mariadb_data_3406
      021. innodb_file_per_table = 1
      022. default_storage_engine = InnoDB
      023. log-bin=mysql-bin
      024. relay-log=/data/relaylogs_3406/relay-bin # 指定中继日志路径
      025. log_slave_updates=1 # 开启从库更新操作写入二进制日志功能
      026. auto_increment_increment=2 # 双主复制中自增长字段的步长
      027. auto_increment_offset=1 # 双主复制中自增长字段的起始值,此为1
      028. sync_binlog = 1 # 可保证事务日志及时写入磁盘文件
      029. binlog_format=row
      030. server-id = 11  # 注意server-id的唯一性
      031. [mysqld2]
      032. port = 3506
      033. socket = /tmp/mysql3506.sock
      034. skip-external-locking
      035. key_buffer_size = 256M
      036. max_allowed_packet = 1M
      037. table_open_cache = 256
      038. sort_buffer_size = 1M
      039. read_buffer_size = 1M
      040. read_rnd_buffer_size = 4M
      041. myisam_sort_buffer_size = 64M
      042. thread_cache_size = 8
      043. query_cache_size= 16M
      044. thread_concurrency = 2
      045. datadir = /data/mariadb_data_3506
      046. innodb_file_per_table = 1
      047. default_storage_engine = InnoDB
      048. log-bin=mysql-bin
      049. relay-log=/data/relaylogs_3506/relay-bin
      050. log_slave_updates=1
      051. sync_binlog = 1
      052. binlog_format=row
      053. server-id = 12
      054. # 在主机Host2上
      055. vi /etc/my.cnf
      056. [mysqld_multi]
      057. mysqld = /usr/local/mysql/bin/mysqld_safe
      058. mysqladmin = /usr/local/mysql/bin/mysqladmin
      059. [mysqld1]
      060. port = 3406
      061. socket = /tmp/mysql3406.sock
      062. skip-external-locking
      063. key_buffer_size = 256M
      064. max_allowed_packet = 1M
      065. table_open_cache = 256
      066. sort_buffer_size = 1M
      067. read_buffer_size = 1M
      068. read_rnd_buffer_size = 4M
      069. myisam_sort_buffer_size = 64M
      070. thread_cache_size = 8
      071. query_cache_size= 16M
      072. thread_concurrency = 2
      073. datadir = /data/mariadb_data_3406
      074. innodb_file_per_table = 1
      075. default_storage_engine = InnoDB
      076. log-bin=mysql-bin
      077. relay-log=/data/relaylogs_3406/relay-bin
      078. log_slave_updates=1
      079. auto_increment_increment=2 # # 双主复制中自增长字段的步长
      080. auto_increment_offset=2 # 双主复制中自增长字段的起始值,此为2
      081. sync_binlog = 1
      082. binlog_format=row
      083. server-id = 21
      084. [mysqld2]
      085. port = 3506
      086. socket = /tmp/mysql3506.sock
      087. skip-external-locking
      088. key_buffer_size = 256M
      089. max_allowed_packet = 1M
      090. table_open_cache = 256
      091. sort_buffer_size = 1M
      092. read_buffer_size = 1M
      093. read_rnd_buffer_size = 4M
      094. myisam_sort_buffer_size = 64M
      095. thread_cache_size = 8
      096. query_cache_size= 16M
      097. thread_concurrency = 2
      098. datadir = /data/mariadb_data_3506
      099. innodb_file_per_table = 1
      100. default_storage_engine = InnoDB
      101. log-bin=mysql-bin
      102. relay-log=/data/relaylogs_3506/relay-bin
      103. log_slave_updates=1
      104. sync_binlog = 1
      105. binlog_format=row
      106. server-id = 22

      启动数据库实例

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

      登录数据库

      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'; # 创建复制账户

      配置数据同步

      01. # 每次从库连接主库前,需先查询对应主库的二进制日志文件及其事件位置,即在主库上执行show master status即可,据此决定从库连接时的master_log_file和master_log_pos参数;
      02. # slave1实例上
      03. change master to master_host='192.168.0.45',master_port=3406,master_user='3m_repl',master_pass<a href="http://www.it165.net/edu/ebg/" target="_blank"class="keylink">word</a>='3m_12345',master_log_file='mysql-bin.000001',master_log_pos=2448;
      04. # master2实例上
      05. change master to master_host='192.168.0.45',master_port=3406,master_user='3m_repl',master_pass<a href="http://www.it165.net/edu/ebg/" target="_blank"class="keylink">word</a>='3m_12345',master_log_file='mysql-bin.000002',master_log_pos=365;
      06. # slave2实例上
      07. change master to master_host='192.168.0.46',master_port=3406,master_user='3m_repl',master_password='3m_12345',master_log_file='mysql-bin.000004',master_log_pos=342;
      08. # master1实例上
      09. change master to master_host='192.168.0.46',master_port=3406,master_user='3m_repl',master_password='3m_12345',master_log_file='mysql-bin.000004',master_log_pos=342;

      查看同步状态

      01. # 重点检查Slave_IO_Running、Slave_SQL_Running和Master_Server_Id等参数
      02. MariaDB [(none)]&gt; show slave status\G
      03. *************************** 1. row ***************************
      04. Slave_IO_State: Waiting for master to send event
      05. Master_Host: 192.168.0.45
      06. Master_User: 3m_repl
      07. Master_Port: 3406
      08. Connect_Retry: 60
      09. Master_Log_File: mysql-bin.000005
      10. Read_Master_Log_Pos: 326
      11. Relay_Log_File: relay-bin.000010
      12. Relay_Log_Pos: 613
      13. Relay_Master_Log_File: mysql-bin.000005
      14. Slave_IO_Running: Yes
      15. Slave_SQL_Running: Yes
      16. Master_Server_Id: 11

       

      MMM安装部署

      Host1主机上:部署agent和monitor

       

       

      01. yum -y install mysql-mmm-*
      02. # 配置公共设置
      03. vi /etc/mysql-mmm/mmm_common.conf
      04. active_master_role      writer
      05. &lt;host default&gt;
      06. cluster_interface       eth0
      07. pid_path                /var/run/mysql-mmm/mmm_agentd.pid
      08. bin_path                /usr/libexec/mysql-mmm/
      09. replication_user        3m_repl# 复制账户
      10. replication_password    3m_12345# 复制账户密码
      11. agent_user              3m_agen# agent账户
      12. agent_password          3m_12345# agent账户密码
      13. &lt;/host&gt;
      14. &lt;host db1&gt;
      15. ip      192.168.0.45
      16. mysql_port 3406# 可指定需连接的mysqld的端口
      17. mode    master
      18. peer    db2# peer表示db1、db2是同等级别的
      19. &lt;/host&gt;
      20. &lt;host db2&gt;
      21. ip      192.168.0.46
      22. mysql_port 3406
      23. mode    master
      24. peer    db1
      25. &lt;/host&gt;
      26. &lt;host db3&gt;
      27. ip      192.168.0.45
      28. mysql_port 3506
      29. mode    slave
      30. &lt;/host&gt;
      31. &lt;host db4&gt;
      32. ip      192.168.0.46
      33. mysql_port 3506
      34. mode    slave
      35. &lt;/host&gt;
      36. &lt;role writer&gt;
      37. hosts   db1, db2
      38. ips     192.168.0.11# 可写VIP只配置一个
      39. mode    exclusive# 表示排它
      40. &lt;/role&gt;
      41. &lt;role reader&gt;
      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. &lt;/role&gt;
      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. &lt;monitor&gt;
      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     60
      59. &lt;/monitor&gt;
      60. &lt;host default&gt;
      61. monitor_user        3m_moni# 监控账户
      62. monitor_password    3m_12345 # 监控账户密码
      63. &lt;/host&gt;
      64. debug 0
      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. # Host2主机上
      2. service mysql-mmm-agent start # 启动agent代理程序
      3. # Host1主机上
      4. service mysql-mmm-agent start
      5. service mysql-mmm-monitor start # 启动监控程序

       

      测试验证

      查看双主复制架构中基于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)

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

      01. # 在主机Host1上
      02. [root@mysql mysql-mmm]# mmm_control checks
      03. db4  ping         [last change: 2014/05/06 22:38:27]  OK
      04. db4  mysql        [last change: 2014/05/06 22:38:27]  OK
      05. db4  rep_threads  [last change: 2014/05/06 22:38:27]  OK
      06. db4  rep_backlog  [last change: 2014/05/06 22:38:27]  OK: Backlog is null
      07. db2  ping         [last change: 2014/05/06 22:38:27]  OK
      08. db2  mysql        [last change: 2014/05/06 22:38:27]  OK
      09. db2  rep_threads  [last change: 2014/05/06 22:38:27]  OK
      10. db2  rep_backlog  [last change: 2014/05/06 22:38:27]  OK: Backlog is null
      11. db3  ping         [last change: 2014/05/06 22:38:27]  OK
      12. db3  mysql        [last change: 2014/05/06 22:38:27]  OK
      13. db3  rep_threads  [last change: 2014/05/06 22:38:27]  OK
      14. db3  rep_backlog  [last change: 2014/05/06 22:38:27]  OK: Backlog is null
      15. db1  ping         [last change: 2014/05/06 22:38:27]  OK
      16. db1  mysql        [last change: 2014/05/06 22:38:27]  OK
      17. db1  rep_threads  [last change: 2014/05/06 22:38:27]  OK
      18. db1  rep_backlog  [last change: 2014/05/06 22:38:27]  OK: Backlog is null

       

      补充说明

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

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

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

      • 本博客作者:杨乐平   QQ:359559774@qq.com

      • 原文转自:http://www.it165.net/database/html/201405/6340.html  版权所属

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值