从单机到集群
单机问题
- 容量有限,难以扩容
- 读写压力,QPS过大,特别是分析类需求会影响业务事务
- OLTP OnLineTransactionProcessing 联机事务处理,处理一线业务
- OLAP OnLineAnalyticalProcessing 联机分析处理,分析决策
-
技术演进
主从复制
原理
主库写binlog
- 从库relaylog,分离IO和SQL线程
- 后面引入了半同步和MGR
binlog格式
- ROW
- 记录详细但日志量会比较大
- Statement
- 只是记录SQL,记录简单
- 没有查询语句
Mixed
# 查看binlogmysqlbinlog -vv mysql-bin.000005
0异步复制
传统的主从复制即PrimarySecondaryReplication
- 异步复制:网络或机器故障,会造成数据不一致
- 局限性
- 主从延时问题
- 只能数据分片,把数据量做小
- 应用侧需要配合读写分离框架
- 不解决高可用问题
- 主从延时问题
1半同步复制
- 需要启用插件
- 保证source和replica最终一致性
- 半同步是指至少有一个从库收到了log主库才能commit
2组复制
- MGR(MySQLGroupReplication)
- 基于分布式Paxos协议实现,保证数据一致性
演示
### 主从复制演示[TOC]#### 准备两个MySQL服务实例> windows上可以用压缩版本,例如mysql-5.7.31-winx64.zip,解压文件夹再复制一份,添加my.ini配置文件。假设一个叫mysql-5.7.31-winx64,一个叫mysql-5.7.31-winx64-2,以为分别配置其为主和从。>> Mac和Linux环境,自己想办法,也可以用docker#### 修改主mysql-5.7.31-winx64的my.ini
basedir = ./ datadir = ./data port = 3306 server_id = 1
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES log_bin=mysql-bin binlog-format=Row
#### 修改从mysql-5.7.31-winx64-2的my.ini
basedir = ./ datadir = ./data port = 3316 server_id = 2
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES log_bin=mysql-bin binlog-format=Row
#### 初始化和启动数据库
空数据库需要执行mysqld --initialize-insecure 进行初始化。
分别启动主和从,在命令行下直接执行mysqld或start mysqld命令即可。
#### 配置主节点
mysql命令登录到主节点:mysql -uroot -P3306
mysql> CREATE USER ‘repl’@’%’ IDENTIFIED BY ‘123456’; Query OK, 0 rows affected (0.11 sec)
mysql> GRANT REPLICATION SLAVE ON . TO ‘repl’@’%’; Query OK, 0 rows affected (0.12 sec)
mysql> flush privileges; Query OK, 0 rows affected (0.10 sec)
mysql> show master status; +—————————+—————+———————+—————————+—————————-+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +—————————+—————+———————+—————————+—————————-+ | mysql-bin.000003 | 305 | | | | +—————————+—————+———————+—————————+—————————-+ 1 row in set (0.00 sec)
创建数据库:create schema db;
#### 配置从节点
mysql命令登录到从节点:mysql -uroot -P3316
CHANGE MASTER TO
MASTER_HOST=’localhost’,
MASTER_PORT = 3306,
MASTER_USER=’repl’,
MASTER_PASSWORD=’123456’,
MASTER_LOG_FILE=’mysql-bin.000003’,
MASTER_LOG_POS=305;
//MASTER_AUTO_POSITION = 1;
创建数据库:create schema db;
#### 验证操作
在主库执行:
mysql> use db Database changed mysql> create table t1(id int); Query OK, 0 rows affected (0.17 sec)
mysql> mysql> mysql> insert into t1(id) values(1),(2); Query OK, 2 rows affected (0.04 sec)
在从库查看数据同步情况
mysql> use db Database changed mysql> mysql> mysql> show tables; +———————+ | Tables_in_db | +———————+ | t1 | +———————+ 1 row in set (0.00 sec)
mysql> mysql> mysql> select * from t1; +———+ | id | +———+ | 1 | | 2 | +———+ 2 rows in set (0.00 sec)
#### 查看命令
可以通过show master status\G, show slave status\G 查看状态
可以能改过stop slave; start slave;来停止复制。
#### 其他
GTID与复制:
https://blog.51cto.com/13540167/2086045
https://www.cnblogs.com/zping/p/10789151.html
半同步复制:
https://www.cnblogs.com/zero-gg/p/9057092.html
组复制:
https://www.cnblogs.com/lvxqxin/p/9407080.html
相关命令
show master status\G;
show slave status\G;
stop slave;
drop table t1;
CHANGE MASTER TO
MASTER_HOST='localhost',
MASTER_PORT = 3306,
MASTER_USER='repl',
MASTER_PASSWORD='123456',
MASTER_LOG_FILE='mysql-bin.000003',
MASTER_LOG_POS=305;
show tables;
start slave;
create table t3 like test.t2; // 拷贝表结构
show create table t3; //查看表创建语句
show plugins;// 查看插件,半同步和组复制都是插件
读写分离
动态切换数据源版本1.0
- 基于Spring,配置多个数据源(例如两个,master和slave)
根据具体的service方法是否会操作数据,注入不同的数据源
改进1.1
基于操作AbstractRoutingDataSource和自定义注解类readOnly之类的,简化自动切换数据源
改进1.2
-
改进1.3
-
不足
侵入性比较强
-
数据库框架版本2.0
ShardingSphere-jdbc的master-slave功能
- SQL解析和事务管理,自动实现读写分离
解决“写完读”不一致的问题(遇到写操作后后面的所有操作都走主库)
不足
对业务系统还是有侵入
- 对已存在的旧系统改造不友好
数据库中间件版本3.0
- MyCat/ShardingSphere-Proxy的master/slave功能
- 需要部署一个中间件,规则配置在中间件,中间件完全替换原来的数据库
- 模拟一个MySQL服务器,对业务系统无侵入
-
高可用
为什么要高可用
读写分离,提升读的处理能力
- 故障转移,提供failover能力
业务侧连接池的心跳重试,实现断线重连,业务不间断,降低RTO和RPO
常见策略
多个实例不在一个主机/机架上
- 跨机房和可用区部署
-
MySQL高可用0:主从手动切换
实现
- 如果主节点挂掉,手动将某个从改成主
- 重新配置其他从节点
- 修改应用数据源配置
问题
实现
- 用LVS+Keepalived实现多个节点的探活+请求路由
- 配置VIP或DNS实现配置不变更
问题
实现
- MasterHighAvailability
- 相对成熟的高可用解决方案
- 基于Perl语言开发,一般能在30s内实现主从切换
- 切换时直接通过SSH复制主节点的日志
问题
实现
- 如果主节点挂掉,将自动选择某个从改成主
- 无需人工干预,基于组复制实现的分布式Paxos协议,保证数据一致性
- 支持单主模式和多主模式
问题
实现
实现
- 高可用和管理工具
- 提供web界面
- 检测异常可自动/手动修复
