MySQL高可用架构
# 主从集群
如果数据库的访问压力没有那么大,那读写分离不一定是必须要做的,但是主从架构和高可用架构则是必须要搭建的。
# 用途
数据安全
读写分离
故障转移-高可用
对于高可用架构,主从数据的同步也只是实现故障转移的一个前提条件,要实现 MySQL主从切换,还需要依靠一些其他的中间件来实现。比如MMM、MHA、 MGR。
# 原理
MySQL服务的主从架构一般都是通过binlog日志文件来进行的。我们通常对MySQL做的读写分离配置就必须基于主从架构来搭建。
# 过程
- 即在主服务上打开binlog记录每一步的数据库操作
- 从服务上会有一个IO线程,负责跟主服务建立一个TCP连接,请求主服务将binlog传输过来。
- 这时,主库上会有一个IO dump线程,负责通过这个TCP连接把Binlog日志传输给从库的IO线程。
- 接着从服务的IO线程会把读取到的binlog日志数据写入自己的relay日志文件中。
- 然后从服务上另外一个SQL线程会读取relay日志里的内容,进行操作重演,达到还原数据的目 的。
- 总结: binlog -> relaylog -> 重演
# 要求
- 双方MySQL必须版本一致。至少需要主服务的版本低于从服务
- 两节点间的时间需要同步。
# 操作过程
# 主节点
- 打开binlog日志并指定日志文件名,指定severId
- 重启MySQL服务
- 给连接的用户分配replication slave的权限。
# 从节点
- 配置server-id、relay-log、log-bin
- 启动mysqls的服务
- 设置他的主节点同步状态
- 设置主节点的ip/port/user/password等等
- 开启slave
- set global read_only=1; 限制普通用户写入
# 部分库同步
- Master : 配置可以忽略的库
- Slave : 配置备份库与主服务的库的对应关系
# 注意
- 默认所有的dml操作都会同步过去,除了select以外。
- 默认是针对所有库。
- 默认主从集群是单向的,主->从
- 默认是异步的
# 半同步复制
# 背景
默认是异步复制的,这意味着有可能会丢数据。
- 具体情况 : 主服务在向客户端反馈执行结果时,是不知道binlog是否同步成功了的。这时候如果主服务宕机了,而从服务还没有备份到 新执行的binlog,那就有可能会丢数据。
# 介绍
半同步复制机制是一种介于异步复制和全同步复制之前的机制。
这种半同步复制相比异步复制,能够有效的提高数据的安全性。
# 过程
主库在执行完客户端提交的事务后,并不是立即返回客户端响应,而是等待至少一个从库接收并写 到relay log中,才会返回给客户端。
MySQL在等待确认时,默认会等10秒,如果超 过10秒没有收到ack,就会降级成为异步复制。
# 操作
- 再主库 安装 semisync_master , 从库安装semisync_slave
- 配置相关参数
- 开启开关
# 问题
- 他只保证事务提交后的binlog至少传输到了一个从库,并且并不保证从库应用这个事务的binlog是成功的。 也可能丢数据,就是从库挂了
- 半同步复制机制也会造成一定程度的延迟,这个延迟时间最少是一个TCP/IP请求往返的时间。整个服务的性能是会有所下降的。
- 最严重的问题:: 当从服务出现问题时,主服务需要等待的时间就会更长,要等到 从服务的服务恢复或者请求超时(默认10s)才能给用户响应。
# 数据延迟问题
面向业务的主服务数据都是多线程并发写入的,而从服务是单个线程慢慢拉取binlog,这中间就会有个效率差。
# 解决方案
所以解决这个问题的关键是要让从服务也用多线程并行复制binlog数据。
MySQL自5.7版本后就已经支持并行复制了。
# 操作
从服务上设置slave_parallel_workers为一个大于0的数,然后把slave_parallel_type参数设置为 LOGICAL_CLOCK,这就可以了。
# 扩容注意事项
新加一个从节点,只需要增加一个binlog复制就行了。
但是需要注意的是,之前的数据没办法从binlog来恢复了,需要用mysqldump全量导出一份数据出来再做操作。
# GTID同步集群
这种模式是从MySQL5.6版本引入的。
# 背景
避免了由于偏移量的问题造成数据不一致。
# 原理
本质也是基于Binlog来实现主从同步,只是他会基于一个全局的事务ID来 标识同步进度
GTID即全局事务ID,全局唯一并且趋势递增,他可以保证为每一个 在主节点上提交的事务在复制集群中可以生成一个唯一的ID。
# 过程
- 从服务器会告诉主服务器已经在从服务器执行完了哪 些事务的GTID值
- 然后主库会有把所有没有在从库上执行的事务,发送到从库上进行执行
- 并且使用GTID的复制可以保证同一个事务只在指定的从库上执行一次。
# 设置
再主从上都开启 enforce_gtid_consistency = on
# 其他集群
# 一主一从
# 一主多从
可以减轻从库的读压力
# 多级从
可以减轻主节点进行数据同步的压力
# 多主
为了提高整个集群的高可用能力,一个主节点挂了也没关系。
# 互为主从
主库也是从库,从库也是主库。 实现MySQL多活部署。
互相配置主从,就是2个主节点。一个节点挂了,还有另外一个主节点可以写,并且他们的数据是一致的。
# 环形主从
实现MySQL多活部署。
环装(循环)的主从节点,多主多从。
# 高可用方案
# 背景
mysql自带的主从有些问题:
- Master节点挂了,怎么自动感知??
- Master节点挂了,能不能自动切换或者迁移。
- 重新切换了Master节点,对应的从节点是不是也要切换???
# 共性解决
对主从复制集群中的Master节点进行监控
自动的对Master进行迁移,通过VIP(虚拟ip)。
重新配置集群中的其它slave对新的Master进行同步
# MMM
- 他通过VIP(虚拟IP)的机制来保证集群的高可用
- 缺少维护,不支持基于GTID的复制,基本不再使用.
# MHA
- 能够在30秒内实现故障切换,并能在故障切换过程中,最大程度的保证数据一致性。
- 在淘宝内部,也有一个相似的TMHA产品。
# 功能
- 当发现master节点 故障时,会提升其中拥有新数据的slave节点成为新的master节点。
- MHA会通过其他从节点获取额外的信息来避免数据一致性方面的问题。
- 还提 供了mater节点的在线切换功能,即按需切换master-slave节点
- MHA除了支持日志点的复制还支持GTID的方式。
# 原理
Master High Availability Manager and Tools for MySQL。是由日本人开发的一 个基于Perl脚本写的工具。这个工具专门用于监控主库的状态,当发现master节点 故障时,会提升其中拥有新数据的slave节点成为新的master节点,在此期间, MHA会通过其他从节点获取额外的信息来避免数据一致性方面的问题。MHA还提 供了mater节点的在线切换功能,即按需切换master-slave节点。MHA能够在30秒 内实现故障切换,并能在故障切换过程中,最大程度的保证数据一致性。在淘宝内 部,也有一个相似的TMHA产品。
# 优点
MHA除了支持日志点的复制还支持GTID的方式
同MMM相比,MHA会尝试从旧的Master中恢复旧的二进制日志,只是未必每 次都能成功。
# 缺点
- MHA只监控Master的状态,未监控Slave的状态
# 业务场景
如果希望更少的数据丢失场景,建议使用MHA架构。
# MGR(MySQL Group Replication)
- 主要是解决传统异步复制和半同步复制的数据一致性问题。
- 由若干个节点共同组成一个复制组,一个事务提交后,必须经过超过半数节点的决议并通过后,才可以提交。引入组复制,主要是为了解决传统异步复制和半同步复 制可能产生数据不一致的问题。
- 支持多主模式,但官方推荐单主模式;多主模式下,客户端可以随机向MySQL节点写入数据;单主模式下,MGR集群会选出primary节点负责写请求,primary节点与其它节点都可以进行读请求处理
# 优点
- 基本无延迟,延迟比异步的小很多
- 支持多写模式,但是目前还不是很成熟
- 数据的强一致性,可以保证数据事务不丢失
# 缺点
- 仅支持innodb,且每个表必须提供主键。
- 只能用在GTID模式下,且日志格式为row格式。
# 业务场景
- 对主从延迟比较敏感
- 希望对对写服务提供高可用,又不想安装第三方软件
- 数据强一致的场景
# 数据虚拟共享
上云之后可以做数据虚拟共享出来供其他的节点使用(压根不需要管)
# 读写分离
应用做读写分离 ,mysql只是主从同步。
而对于MySQL集群,数据主从同步是实现 读写分离的一个必要前提条件。
# 分库分表
- 分库分表的一整套逻辑全部是由客户端自行实现的。
- 分库分表包含分库和分表 两个部分,而这两个部分可以统称为数据分片,其目的都 是将数据拆分成不同的存储单元。
# 作用
1、加大存储,2、提升查询效率,3、提升数据库的并发能力
解决由于数据量过大而导致数据库性能降低的问题,将原来独立 的数据库拆分成若干数据库组成 ,将数据大表拆分成若干数据表组成,使得单一数据库、单一数据表的数据量变 小,从而达到提升数据库性能的目的。
数据太大,插入和修改操作巨慢,引发的超时,导致数据添加失败。
# 形式
- 垂直分片 : 按照业务来对数据进行分片,比如用户系统表和订单系统表。 单表中的数据超过节点所能承载,则需要水平分片。
- 水平分片 : 通过某个字段(或某几个字段),根据某种规则将数据分散至多个库或表中,这样就突破了单机数据量处理的瓶颈,并且扩展相对自由。
设计定业务拆分做垂直分库 -> 中期优化做缓存、读写分离、索引技术 -> 后期再做水平分库水平分表。
在系统设计阶段就应该根据业务耦合松紧来确定垂直分库,垂直分表方案,在数据量及访问压力不是特别大的情况,首先考虑缓存、读写分离、索引技 术等方案。若数据量极大,且持续增长,再考虑水平分库水平分表方案
# 分片策略
- 取余\取模 : 优点均匀存放数据,缺点 扩容非常麻烦
- 按照范围分片 : 比较好扩容, 数据分布不够均匀
- 按照时间分片 : 比较容易将热点数据区分出来。
- 按照枚举值分片 : 例如按地区分片
- 按照目标字段前缀指定进行分区:自定义业务规则分片
# 缺点
- 事务一致性问题
- 跨节点关联查询问题
- 跨节点分页、排序函数
- 主键避重问题
- 公共表处理
- 运维工作量
- 其他问题: 比如: 数据迁移、扩缩容、公共表、读写分离、配置往注册中心集中配置。
# 时机
- MySQL单表记录如果达到500W这个级别, 或者单表容量达到2GB,建议进行分库分表
- 一般可以按照三年左右的业 务量来预估使用人数,按照标准预设好分库分表的方案
- 对业务持续增长的分(比如订单),对业务增长到一定程度就不增长的不发(比如用户)。
# 注意事项
- 【强制】只针对最核心的表,需要分的表,而不是所有表都要分。
- 【强制】分库分表后,对表的查询必须足够简单,不要有跨表,跨库的复杂查询。
- 【建议】分库和分表尽量同时进行,分库可以分担网络压力。
- 【建议】因为中途改造涉及面广,系统设计之初就详细考虑好分库分表的方案
- 【建议】在设计分库分表方案时,要尽量兼顾业务场景和数据分布。
- 【建议】在支持业务场景的前提下,尽量保证数据能够分得更均匀
- 【建议】因为一些操作就算分了也提高不了性能,尽量在分库分表的同时,再补充设计一个降级方案,比如把一些数据存到其他的库去。
- 【建议】因为分库分表的后期扩容麻烦,尽量根据情况,多分一些表。最好是计算一下数据增量,永远不用增加更多的表
# 思考
主从数据不一致问题?? 大部分都是再从库里面做了DML操作,而主库是无法感知导致的。从库配置普通用户只读。
如何解决mysql主从读写延迟的问题??
主服务开启半同步。
如果主库写频繁,从服务开启多线程复制binlog数据。
如果一主多从,可以采用MGR,保证半数以上同步。
有其他的分布式数据库,为什么还要用分库分表
cap理论中 要不cp、要不ap 、要不ca.
因为关系型数据库保证了CA、事务,其他数据库强保证事务,所以其他的分布式数据库大多用做副本。