MySQL Scale Out
简介
MySQL复制中较常见的复制架构有“一主一从”、“一主多从”、“双主”、“多级复制”和“多主环形机构”等,见下图;
最常用,也最灵活的就要数“一主多从”复制架构了,其能满足多种需求,如:
为不同的角色使用不同的备库(例如添加不同的索引或使用不同的存储引擎);
把一台备库当做待用的主库,除了复制没有其它数据传输;
将一台备库放在远程数据中心,用作灾难恢复;
延迟一个或多个备库,以备灾难恢复;
使用其中一个备库,作为备份、培训、开发或者测试使用服务器;
而“双主”复制架构则用于特殊的场景下,如两个处于不同地理位置的办公室,且都需要一份可写的数据拷贝;
这种架构最大的问题是如何解决数据冲突和不一致,尤其当两台服务器同时修改同一行记录,或同时在两台服务器上向一个包含auto_increment列的表里插入数据时;
而通过将一台服务器设置为只读的被动服务器,则可以很好的避免数据写入冲突的问题,这种主动-被动模式下的主-主复制架构使得反复切换主动和被动服务器非常方便,可以实现在不关闭服务器的情况下执行维护、优化表、升级操作系统或其他任务;
配置主动-被动模式的主-主复制架构的一般流程:
确保两台服务器上有相同的数据;
启用二进制日志,选择唯一的服务器ID,并创建复制账号;
启用备库更新的日志记录,这是故障转移和故障恢复的关键;
把被动服务器配置成只读,防止可能与主动服务器上的更新产生冲突;
启动每个服务器的MySQL实例;
将每个主库设置为对方的备库,使用新创建的二进制日志开始工作;
同时为了消除不同地理位置的站点单点故障问题,可以为每个主库增加冗余,即为每一个主库增加一个从库;
而MMM(=Master-Master Replication Manager for MySQL)则是一套脚本集合,用以监控、管理双主复制架构,通过设置一个可写的VIP和多个只读的VIP,完成故障自动转移、读负载分摊等功能;
架构设计
服务器规划
虚IP规划
配置部署
双主复制架构部署
MySQL或MariaDB的安装初始化可详见博客“MySQL架构”
利用mysqld_multi在一台主机上启动多个mysqld实例
数据库初始化
# 在主机Host1和Host2上
cd /usr/local/mysql
scripts/mysql_install_db --user=mysql --datadir=/data/mariadb_data_3406/
scripts/mysql_install_db --user=mysql --datadir=/data/mariadb_data_3506/
数据库配置
# 在主机Host1上
vi /etc/my.cnf
[mysqld_multi]
mysqld = /usr/local/mysql/bin/mysqld_safe
mysqladmin = /usr/local/mysql/bin/mysqladmin
[mysqld1]
port =
socket = /tmp/mysql3406.sock
skip-external-locking
key_buffer_size = 256M
max_allowed_packet = 1M
table_open_cache =
sort_buffer_size = 1M
read_buffer_size = 1M
read_rnd_buffer_size = 4M
myisam_sort_buffer_size = 64M
thread_cache_size =
query_cache_size= 16M
thread_concurrency =
datadir = /data/mariadb_data_3406
innodb_file_per_table =
default_storage_engine = InnoDB
log-bin=mysql-bin
relay-log=/data/relaylogs_3406/relay-bin # 指定中继日志路径
log_slave_updates= # 开启从库更新操作写入二进制日志功能
auto_increment_increment= # 双主复制中自增长字段的步长
auto_increment_offset= # 双主复制中自增长字段的起始值,此为1
sync_binlog = # 可保证事务日志及时写入磁盘文件
binlog_format=row
server-id = # 注意server-id的唯一性
[mysqld2]
port =
socket = /tmp/mysql3506.sock
skip-external-locking
key_buffer_size = 256M
max_allowed_packet = 1M
table_open_cache =
sort_buffer_size = 1M
read_buffer_size = 1M
read_rnd_buffer_size = 4M
myisam_sort_buffer_size = 64M
thread_cache_size =
query_cache_size= 16M
thread_concurrency =
datadir = /data/mariadb_data_3506
innodb_file_per_table =
default_storage_engine = InnoDB
log-bin=mysql-bin
relay-log=/data/relaylogs_3506/relay-bin
log_slave_updates=
sync_binlog =
binlog_format=row
server-id =
# 在主机Host2上
vi /etc/my.cnf
[mysqld_multi]
mysqld = /usr/local/mysql/bin/mysqld_safe
mysqladmin = /usr/local/mysql/bin/mysqladmin
[mysqld1]
port =
socket = /tmp/mysql3406.sock
skip-external-locking
key_buffer_size = 256M
max_allowed_packet = 1M
table_open_cache =
sort_buffer_size = 1M
read_buffer_size = 1M
read_rnd_buffer_size = 4M
myisam_sort_buffer_size = 64M
thread_cache_size =
query_cache_size= 16M
thread_concurrency =
datadir = /data/mariadb_data_3406
innodb_file_per_table =
default_storage_engine = InnoDB
log-bin=mysql-bin
relay-log=/data/relaylogs_3406/relay-bin
log_slave_updates=
auto_increment_increment= # # 双主复制中自增长字段的步长
auto_increment_offset= # 双主复制中自增长字段的起始值,此为2
sync_binlog =
binlog_format=row
server-id =
[mysqld2]
port =
socket = /tmp/mysql3506.sock
skip-external-locking
key_buffer_size = 256M
max_allowed_packet = 1M
table_open_cache =
sort_buffer_size = 1M
read_buffer_size = 1M
read_rnd_buffer_size = 4M
myisam_sort_buffer_size = 64M
thread_cache_size =
query_cache_size= 16M
thread_concurrency =
datadir = /data/mariadb_data_3506
innodb_file_per_table =
default_storage_engine = InnoDB
log-bin=mysql-bin
relay-log=/data/relaylogs_3506/relay-bin
log_slave_updates=
sync_binlog =
binlog_format=row
server-id =
启动数据库实例
# 在主机Host1和Host2上
/etc/init.d/mysqld_multi start # 停止服务操作是/etc/init.d/mysqld_multi stop
/etc/init.d/mysqld_multi start # 停止服务操作是/etc/init.d/mysqld_multi stop
登录数据库
# 在主机Host1和Host2上
mysql -S /tmp/mysql3406.sock # 登录master1或master2
mysql -S /tmp/mysql3506.sock # 登录slave1或slave2
创建所需账户(在Master1实例上)
grant replication client on *.* to '3m_moni'@'192.168.0.%' identified by '3m_12345'; # 创建MMM的监控账户
grant super,replication client,process on *.* to '3m_agen'@'192.168.0.%' identified by '3m_12345'; # 创建MMM的代理账户
grant replication slave on *.* to '3m_repl'@'192.168.0.%' identified by '3m_12345'; # 创建复制账户
配置数据同步
# 每次从库连接主库前,需先查询对应主库的二进制日志文件及其事件位置,即在主库上执行show master status即可,据此决定从库连接时的master_log_file和master_log_pos参数;
# slave1实例上
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=;
# master2实例上
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=;
# slave2实例上
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=;
# master1实例上
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=;
查看同步状态
# 重点检查Slave_IO_Running、Slave_SQL_Running和Master_Server_Id等参数
MariaDB [(none)]> show slave status\G
*************************** . row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.0.45
Master_User: 3m_repl
Master_Port:
Connect_Retry:
Master_Log_File: mysql-bin.
Read_Master_Log_Pos:
Relay_Log_File: relay-bin.
Relay_Log_Pos:
Relay_Master_Log_File: mysql-bin.
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Master_Server_Id:
MMM安装部署
Host1主机上:部署agent和monitor
yum -y install mysql-mmm-*
# 配置公共设置
vi /etc/mysql-mmm/mmm_common.conf
active_master_role writer
<host default>
cluster_interface eth0
pid_path /var/run/mysql-mmm/mmm_agentd.pid
bin_path /usr/libexec/mysql-mmm/
replication_user 3m_repl# 复制账户
replication_password 3m_12345# 复制账户密码
agent_user 3m_agen# agent账户
agent_password 3m_12345# agent账户密码
</host>
<host db1>
ip 192.168.0.45
mysql_port # 可指定需连接的mysqld的端口
mode master
peer db2# peer表示db1、db2是同等级别的
</host>
<host db2>
ip 192.168.0.46
mysql_port
mode master
peer db1
</host>
<host db3>
ip 192.168.0.45
mysql_port
mode slave
</host>
<host db4>
ip 192.168.0.46
mysql_port
mode slave
</host>
<role writer>
hosts db1, db2
ips 192.168.0.11# 可写VIP只配置一个
mode exclusive# 表示排它
</role>
<role reader>
hosts db1, db2,db3,db4
ips 192.168.0.12,192.168.0.13,192.168.0.14,192.168.0.15 # 只读VIP可配置多个
mode balanced# 表示可以共用
</role>
==========
scp mmm_common.conf 192.168.0.46:/etc/mysql-mmm/ # 将公共配置文件拷贝至其它主机
==========
# 配置监控设置
vi /etc/mysql-mmm/mmm_mon.conf
include mmm_common.conf
<monitor>
ip 127.0.0.1
pid_path /var/run/mysql-mmm/mmm_mond.pid
bin_path /usr/libexec/mysql-mmm
status_path /var/lib/mysql-mmm/mmm_mond.status
ping_ips 192.168.0.45,192.168.0.46# 健康监测时需ping的主机IP,不是VIP哦
auto_set_online
</monitor>
<host default>
monitor_user 3m_moni# 监控账户
monitor_password 3m_12345 # 监控账户密码
</host>
debug
# 配置agent设置
vi /etc/mysql-mmm/mmm_agent.conf
include mmm_common.conf
this db1# 因为在一台主机上启用了2个mysqld实例,故可配置2个this参数哦
this db3
Host2主机上:只需部署agent
yum -y install mysql-mmm-agent
# 配置agent设置
vi /etc/mysql-mmm/mmm_agent.conf
include mmm_common.conf
this db2
this db4
服务启动
# 在主机Host1上
[root@mysql mysql-mmm]# mmm_control show
db1(192.168.0.45) master/ONLINE. Roles: reader(192.168.0.14), writer(192.168.0.11)
db2(192.168.0.46) master/ONLINE. Roles: reader(192.168.0.13)
db3(192.168.0.45) slave/ONLINE. Roles: reader(192.168.0.15)
db4(192.168.0.46) slave/ONLINE. Roles: reader(192.168.0.12)
测试验证
查看双主复制架构中基于MMM实现的状态信息:
# 在主机Host1上
[root@mysql mysql-mmm]# mmm_control show
db1(192.168.0.45) master/ONLINE. Roles: reader(192.168.0.14), writer(192.168.0.11)
db2(192.168.0.46) master/ONLINE. Roles: reader(192.168.0.13)
db3(192.168.0.45) slave/ONLINE. Roles: reader(192.168.0.15)
db4(192.168.0.46) slave/ONLINE. Roles: reader(192.168.0.12)
手动进行各节点的健康监测
# 在主机Host1上
[root@mysql mysql-mmm]# mmm_control checks
db4 ping [last change: // ::] OK
db4 mysql [last change: // ::] OK
db4 rep_threads [last change: // ::] OK
db4 rep_backlog [last change: // ::] OK: Backlog is null
db2 ping [last change: // ::] OK
db2 mysql [last change: // ::] OK
db2 rep_threads [last change: // ::] OK
db2 rep_backlog [last change: // ::] OK: Backlog is null
db3 ping [last change: // ::] OK
db3 mysql [last change: // ::] OK
db3 rep_threads [last change: // ::] OK
db3 rep_backlog [last change: // ::] OK: Backlog is null
db1 ping [last change: // ::] OK
db1 mysql [last change: // ::] OK
db1 rep_threads [last change: // ::] OK
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的更多相关文章
- (转)使用Amoeba 实现MySQL DB 读写分离
Amoeba(变形虫)项目是一个开源框架,于2008年开始发布一款 Amoeba for Mysql软件: 这个软件致力于MySQL的分布式数据库前端代理层,它主要在应用层访问MySQL的时候充当SQ ...
- 使用Amoeba 实现MySQL DB 读写分离
Amoeba(变形虫)项目是一个开源框架,于2008年开始发布一款 Amoeba for Mysql软件: 这个软件致力于MySQL的分布式数据库前端代理层,它主要在应用层访问MySQL的时候充当SQ ...
- Amoeba是一个类似MySQL Proxy的分布式数据库中间代理层软件,是由陈思儒开发的一个开源的java项目
http://www.cnblogs.com/xiaocen/p/3736095.html amoeba实现mysql读写分离 application shang 2年前 (2013-03-28) ...
- Kubernetes 中部署 MySQL 集群
文章转载自:https://www.cnblogs.com/ludongguoa/p/15319861.html 一般情况下 Kubernetes 可以通过 ReplicaSet 以一个 Pod 模板 ...
- 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 ...
- 交付Dubbo微服务到kubernetes集群
1.基础架构 1.1.架构图 Zookeeper是Dubbo微服务集群的注册中心 它的高可用机制和k8s的etcd集群一致 java编写,需要jdk环境 1.2.节点规划 主机名 角色 ip hdss ...
- CSS动画划入划出酷炫
HTML插入 <!DOCTYPE html> <html class="no-js iarouse"> <head> <meta char ...
- [转载]大型网站应用中 MySQL 的架构演变史
没有什么东西是一成不变的,包含我们的理想和生活!MySQL作为一个免费的开源的关系型数据库,深受大家喜爱,从最初的无人问津到当下的去IOE,都体现出了MySQL举足轻重的作用.今天我们就从淘宝的发展来 ...
- MySQL的数据模型
MySQL的数据类型主要分为三大类: 数值型(Numeric Type) 日期与时间型(Date and Time Type) 字符串类型(String Type) 1. 数值 MySQL的数值类型按 ...
随机推荐
- 【原创】leetCodeOj --- Majority Element 解题报告(脍炙人口的找n个元素数组中最少重复n/2次的元素)
题目地址: https://oj.leetcode.com/problems/majority-element/ 题目内容: Given an array of size n, find the ma ...
- openGL研究钞四 : 关于颜色, 尺寸, 虚线, 多边形逆转, 空洞, 使用位图
转载请保留源,,,,hushuai1992http://blog.csdn.net/u013642494/article/category/2675731 额. 这个标题我都不知道该怎么起了. 假设没 ...
- sails 相关文章
Node 框架之sails http://cnodejs.org/topic/555c3c82e684c4c8088a0ca1
- Android复制iPhone日期和时间选择器
看效果图 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGluZ2xvbmd4aW4yNA==/font/5a6L5L2T/fontsize/400/fi ...
- Apple Watch 1.0 开发介绍 1.1 简介 开发苹果手表
使用Apple Watch,用户可以使用一种不显眼的方式查看信息.不用把iPhone从口袋里拿出来,就可以通过看一下手表快速获得重要信息. 作为Apple Watch的第三方app开发者,应该通过使用 ...
- 笔试题&面试题:输入一个维度,逆时针打印出一个指定矩阵
称号:考虑到用户层面.打印出指定的矩阵,例如,一个给定的用户10,例如,下面的输出应被视为在图: 程序如下所示: #include <stdio.h> #include <mallo ...
- SpringMVC源码解析- HandlerAdapter - ModelFactory(转)
ModelFactory主要是两个职责: 1. 初始化model 2. 处理器执行后将modle中相应参数设置到SessionAttributes中 我们来看看具体的处理逻辑(直接充当分析目录): 1 ...
- MapReduce源代码分析MapTask分析
前言 MapReduce该分析是基于源代码Hadoop1.2.1代码分析进行的基础上. 该章节会分析在MapTask端的详细处理流程以及MapOutputCollector是怎样处理map之后的col ...
- CSS 之 光进入光
一个.概念 css,层叠样式表(英语:Cascading Style Sheets.简写CSS).又称串样式列表.层次结构式样式表文件,一 种用来为结构化文档(如HTML文档或XML应用)加入样式(字 ...
- Apple Watch开发了一些细节和总结
本文旨在总结最近Watch在发展中遇到的问题和细节 1.左右Watch真机调试问题 一般的情况下,你为IOS主应用创建了一个extention,比方说Today Extension .Xcode都会自 ...