您的位置:首页 > 数据库 > MySQL

mysql group replication 搭建详解

2017-09-18 15:04 417 查看
原理
MySQL异步复制及semi-sync半同步复制,它们都基于MySQL binlog,原生复制是完全异步的,master不需要保证slave接收并执行了binlog,能够保证master最大性能,但是slave可能存在延迟,主备数据无法保证一致性,在不停服务的前提下如果master宕机,提升slave为新的主库,就会丢失数据。
semi-sync在异步复制基础上增加了数据保护的考虑,这样一来master必须确认slave收到binlog后(但不保证slave执行了事务)才能最终提交事务,若再结合MHA(Master High Availability)高可用架构,此时master挂掉之后,slave可以在apply完所有relay
log后切换成master提供读写服务。

相对于MySQL源生复制和semi-sync半同步复制,Group Replication全同步复制的差异是:

全同步复制,主备无延迟,一个节点宕机后其他两个节点可以立即提供服务,而semi-sync需要应用(执行)完所有relay log,并依赖第三方高可用软件实现数据不丢失;

事务冲突检测保证数据一致性,多个节点可以同时读写数据,可以极大简化数据访问;

行级别并行复制,MySQL 5.7/MariaDB 10.0之前slave sql线程只有一个,这个长期饱受诟病,是导致slave落后master的主要原因。
1
Group Replication的工作原理

当客户端发起commit命令时(此时仍然没有发生真正的commit),所有本事务内对数据库的更改行的主键都会被搜集到一个写入集(writeset)中,该写入集随后会被复制到其他节点,该写入集会在每个节点上使用搜索到的主键进行确认性认证测试来判断该写入集是否可以被应用。如果认证测试失败,写入集会被丢弃并且原始事务会被回滚;如果认证成功,事务会被提交并且写入集会被在剩余节点进行应用。最终,这意味着所有服务器以相同的顺序接收同一组事务。
其他节点只要验证成功了,就会返回成功的信号,即使当前数据并没有真正的写入当前节点,固这里的全同步复制,其实是虚拟的全同步复制。这段时间内,数据是有延迟的,但很小,如果应用程序访问的是远端节点,读到的数据是未改变之前的旧数据。固在生产环境里,对数据延迟要求很苛刻的情况下,建议在一个主节点上读写,避免造成数据不一致的情况发生。
(注:Galera通过设置参数wsrep_causal_reads = ON可以避免,这种情况下需要等待远端节点应用完事务后,才返回客户端读取请求,这将增加读取的响应时间。Group Replication未发现相关参数,如有朋友知道也请告知。)
而真正意义上的全同步复制,是要等所有节点事务都提交落地,才成功返回客户端。因此虚拟全同步复制的性能会更好一些。
Group Replication内部实现了flow control限流措施,作用就是协调各个节点,保证所有节点执行事务的速度大于队列增长速度,从而避免丢失事务。实现原理和简单:整个Group Replication集群中,同时只有一个节点可以广播消息(数据),每个节点都会获得广播消息的机会(获得机会后也可以不广播),当慢节点的待执行队列超过一定长度后,它会广播一个FC_PAUSE消息,所以节点收到消息后都会暂缓广播消息并不提供写操作,直到该慢节点的待执行队列长度减小到一定长度后,Group
Replication数据同步又开始恢复。
变量参数:
group_replication_flow_control_applier_threshold = 25000
group_replication_flow_control_certifier_threshold = 25000
待执行队列长度超过该值时,flow control被触发,默认是25000。
2
Group Replication的特性和注意事项

全同步复制,事务要么在所有节点都提交,要么都回滚;

多主复制,可以在任意节点进行写操作;

在从服务器上并行应用事件,真正意义上的并行复制;

节点自动配置--故障节点自动从集群中移除,当故障节点再次加入集群,无需手工备份当前数据库并拷贝至故障节点;

应用程序的兼容性:无需更改应用程序,原生的MySQL接口;

生产环境上集群推荐配置3个节点;

每个节点都包含完整的数据副本;

各个节点的同步复制,通过GTID binlog ROW实现。
优点:

真正的多主架构,任何节点都可以进行读写,无需进行读写分离;
(注:生产环境建议只在一台机器上写,由于集群是乐观锁并发控制,事务冲突的情况会在commit阶段发生。如果有两个事务在集群中不同的节点上对同一行写入并提交,失败的节点将回滚,客户端返回报错,作为DBA你不想被一群开发投诉的话,还是默默的开启Single-Primary写入模式)

无集中管理,可以在任何时间点失去任何一个节点,集群将正常工作不受影响;

节点宕机不会导致数据丢失;

对应用透明。
缺点:

加入新节点,开销大,需要复制完整的数据。

不能有效的解决写扩展问题,磁盘空间满了,无法自动扩容,不能像MongoDB分片那样自动移动chunk做balance

有多少个节点就有多少份重复的数据

由于事务提交需要跨节点通讯(分布式事务),写入会比主从复制慢

对网络要求非常高,如果网络出现波动或机房被ARP攻击,造成两个节点失联,Group Replication集群发生脑裂,服务将不可用。
下面是官方集群节点投票示意图,如果是3个节点,必须满足大多数节点2个投票,这里很像MongoDB副本集的算法吧^_^
集群自身不提供VIP机制,也没有像MongoDB副本集那样提供JAVA/PHP客户端API接口实现故障切换(需要开发自己写,成本较高),需要结合第三方HaProxy软件(建议2块网卡做bond0)+自定义脚本实现秒级故障切换,另通过代理方式,性能会降低,因为多了一层网络转发。
局限性:

目前的复制仅仅支持InnoDB存储引擎;

每张表必须有主键;

只支持ipv4网络;

集群最大支持9个节点;

不支持Savepoints;

不支持SERIALIZABLE隔离级别在Multi-Primary多主模式;

不支持外键在Multi-Primary多主模式;

整个集群的写入吞吐量是由最弱的节点限制,如果有一个节点变得缓慢,比如硬盘故障(RAID10坏了一块盘),那么整个集群将是缓慢的。为了稳定的高性能要求,所有的节点应使用统一的硬件。

安装
公司本地服务器1: ssh
root@192.168.1.122
root /root
公司虚拟机:192.168.1.180-184
192.168.1.171-172
192.168.1.195
root/root

SELECT * FROM performance_schema.replication_group_members;//查看状态

service iptables stop
vi /etc/selinux/config 文件
//将SELINUX=enforcing改为SELINUX=disabled
//重启机器即可

//如果没有mysql5.7下载5.7
rpm -ivh
https://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm
//修改安装版本
mysql-community.repo
yum repolist enabled | grep mysql
sudo yum install mysql-community-server
sudo service mysqld start
sudo grep 'temporary password' /var/log/mysqld.log

mysql -uroot -p

//配置mysql
vi /etc/my.cnf
//主节点的配置:
validate-password=OFF
server_id=104gtid_mode=ONenforce_gtid_consistency=ONmaster_info_repository    = table #复制元数据存入系统表
relay_log_info_repository = table #复制元数据存入系统表
binlog_checksum = none #禁用二进制日志事件校验和log_slave_updates=ONlog_bin=binlogbinlog_format=ROW
expire_logs_days = 7 # 只保留 7 天的日志文件

transaction_write_set_extraction=XXHASH64loose-group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"loose-group_replication_start_on_boot=off #插件在server启动时不自动启动组复制loose-group_replication_local_address=
"192.168.1.104:33061"#loose-group_replication_group_seeds= "192.168.1.104:33061,123.207.175.33:33061"loose-group_replication_bootstrap_group= off #插件不自动引导组
loose-group_replication_single_primary_mode=off   ###本次搭建的是mutil_mode多主模式

//所有节点都需要建用户
SET SQL_LOG_BIN=0;//防止产生binlog日志
//创建GR用户
CREATE USER rpl_user@'%' IDENTIFIED BY 'rpl_pass';GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%';FLUSH PRIVILEGES;SET SQL_LOG_BIN=1;

//使用change master命令配置server,在下次需要从其他成员恢复其状态时,使用group_replication_recovery复制通道的给定凭据
CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='rpl_pass' FOR CHANNEL 'group_replication_recovery';
//安装复制组插件
INSTALL PLUGIN group_replication SONAME 'group_replication.so';

//主节点的开启方式(配置引导组,此引导应仅有单个server独立完成,该server启动组并且只启动一次)(如果整个组复制挂掉需要重新启动)
SET GLOBAL group_replication_bootstrap_group=ON;
START GROUP_REPLICATION;
SELECT * FROM performance_schema.replication_group_members;
SET GLOBAL group_replication_bootstrap_group=OFF;
//从节点的开启方式
START GROUP_REPLICATION;

//验证server确实在组中
mysql> create database test;
Query OK, 1 row affected (0.02 sec)
mysql> use test;
Database changed
mysql> create table t1(c1 int primary key,c2 text not null);
Query OK, 0 rows affected (0.07 sec)
mysql> insert into t1 values(1,'Lily');
Query OK, 1 row affected (0.02 sec)
mysql> select * from t1;
+----+------+
| c1 | c2   |
+----+------+
|  1 | Lily |
+----+------+
1 row in set (0.00 sec)
mysql> show binlog events;
+------------------+-----+----------------+-----------+-------------+-------------------------------------------------------------------+
| Log_name         | Pos | Event_type     | Server_id | End_log_pos | Info                                                              |
+------------------+-----+----------------+-----------+-------------+-------------------------------------------------------------------+
| mysql-bin.000001 |   4 | Format_desc    |         1 |         123 | Server ver: 5.7.18-log, Binlog ver: 4                             |
| mysql-bin.000001 | 123 | Previous_gtids |         1 |         150 |                                                                   |
| mysql-bin.000001 | 150 | Gtid           |         1 |         211 | SET @@SESSION.GTID_NEXT= '7e29f043-2317-11e7-9594-fa163e98778e:1' |
| mysql-bin.000001 | 211 | Query          |         1 |         278 | BEGIN                                                             |
| mysql-bin.000001 | 278 | Table_map      |         1 |         329 | table_id: 62 (mysql.plugin)                                       |
| mysql-bin.000001 | 329 | Write_rows     |         1 |         401 | table_id: 62 flags: STMT_END_F                                    |
| mysql-bin.000001 | 401 | Xid            |         1 |         428 | COMMIT /* xid=3941 */                                             |
| mysql-bin.000001 | 428 | Stop           |         1 |         447 |                                                                   |
+------------------+-----+----------------+-----------+-------------+-------------------------------------------------------------------+

//以下方式是在从节点的配置
validate-password=OFF
server_id=183gtid_mode=ONenforce_gtid_consistency=ONmaster_info_repository=TABLErelay_log_info_repository=TABLEbinlog_checksum=NONElog_slave_updates=ONlog_bin=binlogbinlog_format=ROWexpire_logs_days
= 7 # 只保留 7 天的日志文件transaction_write_set_extraction=XXHASH64loose-group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"loose-group_replication_start_on_boot=offloose-group_replication_local_address= "192.168.1.183:33061"loose-group_replication_group_seeds=
"192.168.1.180:33061,192.168.1.181:33061,192.168.1.182:33061,"loose-group_replication_bootstrap_group= off
loose-group_replication_single_primary_mode= off   ###本次搭建的是mutil_mode
.安装组复制插件并启动它。
INSTALL PLUGIN group_replication SONAME 'group_replication.so';START GROUP_REPLICATION;

如果发生了复制错误建议删除相关数据
如果操作之前没有关闭binlog建议reset master; # 清空所有 binlog 文件
或者purge master logs to 'mysql-bin.000009'; # 我们可以在 master 中执行这条指令 , 将 binlog 文件删除至 mysql-bin.000009 前
或者purge master logs before '2014-11-18 00:00:00'; # 将 binlog 文件删除至此日期前

假如Secondary节点宕机,重启后由于种种原因加入集群失败,现需要重新恢复,步骤如下:
关闭所有节点groupreplication功能
stop group_replication;
清除binlog日志
resetmaster;
用主节点开启
SET GLOBAL
group_replication_bootstrap_group=ON;
start
GROUP_REPLICATION;
SELECT
*
FROM
performance_schema.replication_group_members;
SET GLOBAL
group_replication_bootstrap_group=OFF;
其他节点
CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='rpl_pass' FOR CHANNEL 'group_replication_recovery';
START GROUP_REPLICATION;

FLUSH TABLES WITH READ LOCK;
导出master所有数据
mysqldump
--all-databases
--master-data -uroot -p
> /tmp/dbdump.db
等待startslave后解锁:
UNLOCK TABLES;
2、导入进去
再执行下面的语句即可
stop group_replication;
CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='rpl_pass' FOR CHANNEL 'group_replication_recovery';
START GROUP_REPLICATION;(这个表示数据库没有GR状态的时候恢复执行获取凭证)
SELECT * FROM performance_schema.replication_group_members;

1、在另一台Secondary节点上mysqldump全量
mysqldump -uroot -proot -q --single-transaction
--master-data=2 -B yourDB > /root/yourDB.sql
这一步会自动在yourDB.sql里生成
SET @@GLOBAL.GTID_PURGED='23e510dc-d30b-11e6-a4c6-b82a72d18b06:1,4d1fd6ec-d2fd-11e6-ae4b-549f3503ab31:1-1543112:2003786-2003789:3003787,e4e34dd3-d2fa-11e6-984b-b82a72d18b06:1';
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: