前言
在给自己做着玩的一个项目准备数据库集群,顺带自己大致系统复习并记录一下。
单节点mysql存在的常见问题
- 当数据量和并发量上去后,单节点数据库无法满足大并发时性能上的要求。
- 单节点的MySQL无法满足高可用,数据库宕机或者意外中断等故障后,业务服务被迫中断。
- 当数据量和并发量上去后,单节点 MySQL无法承载巨大的业务量,数据库负载巨大。
mysql集群的好处
针对上面单节点mysql存在的常见问题对应,mysql集群有以下几点好处:
- 高可用性:故障检测及迁移,多节点备份。 如果数据库发生了宕机或者意外中断等故障,能可能快的恢复数据库的使用,保证业务服务不会因为数据库的故障而中断。
- 可伸缩性:方便新增数据库节点扩容。
- 负载均衡:当数据量和并发量上去后,分摊原先只访问单个节点的数据库压力,分担压力到多个节点上。
- 当然谈到集群,就不得不提集群普遍存在的风险之一,脑裂,因为半数机制,所以还是尽可能的使用奇数个节点。
主从架构
集群高可用有了主从节点划分,所以有了保证数据一致性的问题,这个就是涉及到了主从架构与数据复制方式,
- 主从架构可分为:一主一从、一主多从、双主多从、多主多从;
- 数据复制方式可分为:异步复制、全同步复制、半同步复制、组复制、共享存储;
- MySQL主从复制原理
- 客户端在master上执行DDL、DML操作,将数据变更记录到 binlog(二进制日志);
- 从库 slave 的I/O线程连接上master,请求读取指定位置 position 的日志内容;
- master 收到从库 slave 请求后,将指定位置 position 之后的日志内容和主库binlog文件的名称以及在日志中的位置推送给从库slave。
- ① 通过 show master status 可以查看最新的 binlog 日志文件名称和位置等信息;
- ② 定位一个logEvent 需要通过 binlog filename + binlog position进行定位。
- slave 的I/O线程接收到数据后,将接收到的日志内容依次写入到 relay log(中继日志)文件的最末端,并将读取到的主库 binlog 文件名和位置 position 记录到 master info 文件中,方便下一次读取的时候能够清楚的告诉
master“我需要从某个binlog日志的某个位置开始往后的日志内容”。
- slave 的 sql 线程检测到 relay log 中的内容更新后,读取日志并解析成可执行的 sql 语句进行重做。
- 异步复制(Asynchronous replication)
MySQL默认的复制即是异步的,主库将事务 Binlog 事件写入到 Binlog 文件中,此时主库只会通知一下 Dump 线程发送这些新的
Binlog,然后主库就会继续处理提交操作,而此时不会保证这些 Binlog 传到任何一个从库节点上。
- 在Slave 服务器上执行sart slave命令开启主从复制开关,开始进行主从复制。
- 此时,Slave服务器的IO线程会通过在master上已经授权的复制用户权限请求连接master服务器,并请求从执行binlog日志文件的指定位置(日志文件名和位置就是在配置主从复制服务时执行change
master命令指定的)之后开始发送binlog日志内容。
- Master服务器接收到来自Slave服务器的IO线程的请求后,其上负责复制的IO线程会根据Slave服务器的IO线程请求的信息分批读取指定binlog日志文件指定位置之后的binlog日志信息,然后返回给Slave端的IO线程。返回的信息中除了binlog日志内容外,还有在Master服务器端记录的IO线程。返回的信息中除了binlog中的下一个指定更新位置。
- 当Slave服务器的IO线程获取到Master服务器上IO线程发送的日志内容、日志文件及位置点后,会将binlog日志内容依次写到Slave端自身的Relay
Log(即中继日志)文件(Mysql-relay-bin.xxx)的最末端,并将新的binlog文件名和位置记录到master-info文件中,以便下一次读取master端新binlog日志时能告诉Master服务器从新binlog日志的指定文件及位置开始读取新的binlog日志内容。
- Slave服务器端的SQL线程会实时检测本地Relay Log 中IO线程新增的日志内容,然后及时把Relay LOG 文件中的内容解析成sql语句,并在自身Slave服务器上按解析SQL语句的位置顺序执行应用这样sql语句,并在relay-log.info中记录当前应用中继日志的文件名和位置点。
- 全同步复制(Fully synchronous replication)
主库执行完一个事务,所有的从库都执行了该事务才返回给客户端,然后主库线程才能继续做后续操作。因为需要等待所有从库执行完该事务才能返回,所以全同步复制的性能必然会收到严重的影响。
- 半同步复制(Semisynchronous replication)
介于全同步复制与全异步复制之间的一种,主库只需要等待至少一个从库节点收到并且 Flush Binlog 到 Relay Log文件即可,主库不需要等待所有从库给主库反馈。同时,这里只是一个收到的反馈,而不是已经完全完成并且提交的反馈,如此,节省了很多时间。相对于异步复制,半同步复制提高了数据的安全性,同时它也造成了一定程度的延迟,这个延迟最少是一个TCP/IP往返的时间。所以,半同步复制最好在低延时的网络中使用。
- master将每个事务写入binlog(sync_binlog=1),
- 传递到slave刷新到磁盘(sync_relay=1),
- 同时主库提交事务(commit)。
- master等待slave反馈收到relay log,只有收到ACK后master才将commit OK结果反馈给客户端。
组复制
- 组复制不同于异步复制和半同步复制的主从模式,而是多主模式,是一种 share-nothing 的复制方案,其中每个 master server 都有完整的数据副本。
- share-nothing:每一个cpu都有私有内存区域和私有磁盘空间,而且2个cpu不能访问相同磁盘空间,cpu之间的通讯通过网络连接。
- 复制组是一个通过消息传递相互交互的 server 集群。通信层提供了原子消息和完全有 序信息交互等保障机制。MySQL 组复制以这些功能和架构为基础,实现了基于复制协议的多 主更新。复制组由多个 server 成员构成,并且组中的每个 server 成员可以独立地执行事务。 对于任何 RW 事务,提交操作并不是由始发 server 单向决定的,而是由组来决定是否提交。 最终,所有 server 成员以相同的顺序接收同一组事务,所有 server 成员以相同的顺序应用 相同的更改,以确保组内一致。
- 引入组复制,主要是为了解决传统异步复制和半同步复制可能产生数据不一致的问题。 组复制依靠分布式一致性协议 Paxos 协议,实现了分布式下数据的最终一致性,提供了真正 的数据高可用方案(是否真正高可用还有待商榷)。其提供的多写方案,给我们实现多活方案 带来了希望。
共享存储(shared storage)
- SAN 共享存储 SAN 的概念是允许存储设备和处理器(服务器)之间建立直接的高速网络(与 LAN 相 比)连接,通过这种连接实现数据的集中式存储。
- DRBD 磁盘复制, DRBD 是一种基于软件、基于网络的块复制存储解决方案,主要用于对服务器之间的磁 盘、分区、逻辑卷等进行数据镜像,当用户将数据写入本地磁盘时,还会将数据发送到网络中另一台主机的磁盘上,这样的本地主机(主节点)与远程主机(备节点)的数据就可以保证实时同步。
mysql集群方案
- mysql官方提供的方案
- MySQL Replication [一主多从,异步复制]
- MySQL Fabric [一主多从,异步复制]
- MySQL NDB Cluster [多主多从,原生复制及组复制]
- MGR(MySQL Group Replication)[多主多从,原生复制及组复制]
- 基于硬件
- 心跳检测+SAN共享存储 (heartbeat + SAN)
- 心跳检测+DRDB磁盘复制(heartbeat + DRBD)
- 基于第三方
- MMM (Master Replication Manager for MySQL) [双主多从,主主复制]
- MHA (Master High Availability)[多个一主多从,异步/半同步复制]
- Lvs+Keepalived+ MySQL [双主多从,主主复制]
- HaProxy+Keepalived+ MySQL [双主多从,主主复制]
- Galera Cluster (MariaDB Galera Cluster / Mysql Galera Cluster / Percona XtraDB Cluster 简称PXC) [多主多从]
- RadonDB
MySQL Replication
主要目的是实现数据的多点备份,没有故障自动转移和负载均衡。
- 一主多从,异步复制。
- 主从复制是通过重放binlog实现主库数据的异步复制。即当主库执行了一条sql命令,那么从库要从binlog获取数据并重放,从而达到主从复制的效果。
- 对主库与从库之间的网络延迟要求较高,若网络延迟太高,将加重上述的滞后,造成最终数据的不一致。
- 热备时:可以在某个从数据库中暂时中断复制进程,来备份数据,从而不影响主数据的对外服务(如果在master上执行backup,需要让master处于readonly状态,这也意味这所有的write请求需要阻塞)。
- 数据被删除,可以从binlog日志中恢复。
- 单点故障问题:单一的主节点挂了,将不能对外提供写服务。
MySQL Fabric
在MySQL Replication的基础上,增加了故障检测与转移,自动数据分片功能。
MySQL Fabric只有一个主节点,区别是当该主节点挂了以后,会从从节点中选择一个来当主节点。
- 一主多从,异步复制。
- 主从复制是通过重放binlog实现主库数据的异步复制。即当主库执行了一条sql命令,那么从库要从binlog获取数据并重放,从而达到主从复制的效果。
- 对主库与从库之间的网络延迟要求较高,若网络延迟太高,将加重上述的滞后,造成最终数据的不一致。
- 事务及查询只支持在同一个分片内,事务中更新的数据不能跨分片,查询语句返回的数据也不能跨分片。
- 分区:分区则是把一张表的数据分成 N 多个区块,这些区块可以在同一个磁盘上,也可以在不同的磁盘上。
- 分片:分片可以简单定义为将大数据库分布到多个物理节点上的一个分区方案。每一个分区包含数据库的某一部分,称为一个片。
- 数据被删除,可以从binlog日志中恢复。
- 单点故障问题:主节点挂了以后,能够自动从从节点中选择一个来当主节点,不影响持续对外提供写服务。节点故障恢复30秒或更长(采用InnoDB存储引擎的都这样)。
MySQL NDB Cluster
通过使用 NDB 存储引擎实时备份冗余数据,实现数据库的高可用性和数据一致性。
- 多主多从。
- 负载均衡优秀,可同时用于读操作、写操作都都密集的应用,也可以使用SQL和NOSQL接口访问数据。
- 多个主节点,没有单点故障的问题,节点故障恢复通常小于1秒。
- 高可用性和可伸缩性。
- 可以自动切分数据,方便数据库的水平拓展。
- 能跨节点冗余数据:其数据集并不是存储某个特定的MySQL实例上,而是被分布在多个Data Nodes中,即一个table的数据可能被分散在多个物理节点上,任何数据都会在多个Data
Nodes上冗余备份。任何一个数据变更操作,都将在一组Data Nodes上同步,以保证数据的一致性。- 只能使用存储引擎 NDB ,与平常使用的InnoDB 有很多明显的差距,可能会导致日常开发出现意外。
- 事务:其事务隔离级别只支持Read Committed,即一个事务在提交前,查询不到在事务内所做的修改。
- 外键:虽然最新的NDB 存储引擎已经支持外键,但性能有问题,因为外键所关联的记录可能在别的分片节点。
- 表限制。
- 对节点之间的内部互联网络带宽要求高。
- 对内存要求大:Data Node数据会被尽量放在内存中,对内存要求大,而且重启的时候,数据节点将数据load到内存需要很长时间。
由于 MySQL Cluster 架构复杂,部署费时,通常需要 DBA 几个小时的时间才能完成搭建,而依靠 MySQL Cluster Manager 只需一个命令即可完成,但 MySQL Cluster Manager 是 收费的。并且业内资深人士认为 NDB 不适合大多数业务场景,而且有安全问题。因此,使用的人数较少。
MGR(MySQL Group Replication)
基于原生复制及 paxos 协议的组复制技术,并以插件的方式提供,提供一致数据安全保证。
- MGR提供了single-primary 和 multi-primary两种模式。
- single-primary模式下,组内只有一 个节点负责写入,读可以从任意一个节点读取,组内数据保持最终一致。
- multi-primary模式即为多写方案,即写操作会下发到组内所有节点,组内所有节点同时可读可写,该模式也是能够保证组内数据最终一致性。
- 多主模式,即多写,没有选择新 primary 的概念(无需进行选举),group 内的所有机器 都是 primary 节点,同时可以进行读写操作,并且数据是最终一致的。
心跳检测+SAN共享存储 (heartbeat + SAN)
SAN(Storage Area Network):共享存储,主库从库用的一个存储。SAN的概念是允许存储设施和解决器(服务器)之间建立直接的高速连接,通过这种连接实现数据的集中式存储。
- 保证数据的强一致性;
- 与mysql解耦,不会由于mysql的逻辑错误发生数据不一致的情况;
- 需要考虑共享存储的高可用;
- SAN价格昂贵;
心跳检测+DRDB磁盘复制(heartbeat + DRBD)
DRBD(Distributed Replicated Block Device):是一个用软件实现的、无共享的、服务器之间镜像块设备内容的存储复制解决方案。
DRDB磁盘复制:这是linux内核板块实现的块级别的同步复制技术。 通过各主机之间的网络,复制对方磁盘的内容。
- 采用 Heartbeat 双机热备软件来保证数据库的高稳定性和连续性,数据的一致性 由 DRBD 这个工具来保证。
- 默认情况下只有一台 mysql 在工作,当主 mysql 服务器出现问题 后,系统将自动切换到备机上继续提供服务,当主数据库修复完毕,又将服务切回继续由主 mysql 提供服务。
- 相比于SAN储存网络,价格低廉;
- 保证数据的强一致性;
- 与mysql解耦,不会由于mysql的逻辑错误发生数据不一致的情况;
- 对io性能影响较大;
- 从库不提供读操作;
MMM (Master Replication Manager for MySQL)
MMM是在MySQL Replication的基础上,对其进行优化。
MMM是一套支持双主故障切换和双主日常管理的脚本程序,主要用来监控mysql主主复制并做失败转移。
这里的双主节点,虽然叫做双主复制,但是业务上同一时刻只允许对一个主进行写入,另一台备选主上提供部分读服务,其他的 slave 提供读服务,以加速在主主切换时刻备选主的预热。
- 双主多从结构,主主复制,双主复制。
- 多个从节点读的负载均衡。
- 自动的主主故障转移切换,一般3s以内切换备机。
- 无法完全保证数据的一致性。如主1挂了,MMM monitor已经切换到主2上来了,而若此时双主复制中,主2数据落后于主1(即还未完全复制完毕),那么此时的主2已经成为主节点,对外提供写服务,从而导致数据不一。
- 由于是使用虚拟IP浮动技术,类似Keepalived,故RIP(真实IP)要和VIP(虚拟IP)在同一网段。如果是在不同网段也可以,需要用到虚拟路由技术。但是绝对要在同一个IDC机房,不可跨IDC机房组建集群。
MMM 是 Google 技术团队开发的一款比较老的高可用产品,在业内使用的并不多,社区也不活跃, Google 很早就不再维护 MMM 的代码分支。
MHA (Master High Availability)
MHA是在MySQL Replication的基础上,对其进行优化。
MHA(Master High Availability)在 MySQL 高可用方面是一个相对成熟的解决方案,是一 套优秀的作为 MySQL 高可用性环境下故障切换和主从提升的高可用软件。在 MySQL 故障切 换过程中,MHA 能在最大程度上保证数据的一致性,以达到真正意义上的高可用。
提供更多的主节点,但是缺少VIP(虚拟IP),需要配合keepalived等一起使用。
要搭建MHA,要求一个复制集群中必须最少有三台数据库服务器,一主二从,即一台充当master,一台充当备用master,另外一台充当从库。
- 多主多从。
- 各 MySQL Master 之间没有数据共享,为不同业务数据库。
- 可以进行故障的自动检测和转移。
- 具备自动数据补偿能力,在主库异常崩溃时能够最大程度的保证数据的一致性。
- 需要在各个节点间打通ssh信任。
- 高可用依赖于vip的方案,譬如采用keepalive来达到vip的切换,但是keepalive会限制切换的主机必须在一个网段,对于跨机房不在一个网段的服务器来说,就无法支持了。在大规模为每个MySQL集群安排一个vip也是难以实现的。keepalive在一个网段内,部署多套也会互相影响。
- MHA架构实现读写分离,最佳实践是在应用开发设计时提前规划读写分离事宜,在使用时设置两个连接池,即读连接池与写连接池,也可以选择折中方案即引入SQL Proxy。但无论如何都需要改动代码;关于读负载均衡可以使用F5、LVS、HAPROXY或者SQL Proxy等工具,只要能实现负载均衡、故障检查及备升级为主后的读写剥离功能即可。
Lvs+Keepalived+ MySQL
MySQL 主主复制是集群的基础,每个节点都是 Master,均可对外提供服务。
Lvs服务器提供了负载均衡的作用,将用户请求分发到Real Server,一台 Real Server故障并不会影响整个集群的。Keepalived搭建主备Lvs服务器,避免了Lvs服务器的单点故障,出现故障时可以自动切换到正常的节点。
- LVS在企业应用中抗负载能力很强,但存在不足,LVS不支持正则处理,不能实现动静分离;对于大型网站,LVS的实施配置复杂,维护成本相对较高;
HaProxy+Keepalived+ MySQL
Haproxy是一款可提供高可用性、负载均衡、及基于TCP和HTTP应用的代理的软件,适用于负载大的Web站点;运行在硬件上可支持数以万计的并发连接的连接请求;
haproxy+keepalived优点:
- 1.可靠性和稳定性非常好,可以和硬件级的负载均衡设备F5相媲美。
- 2.最高可同时维护40000-50000个并发连接,单位时间内处理的最大请求数为20000个。
- 3.支持8种负载均衡算法,支持回话保持;支持虚拟主机功能;支持连接拒绝,全透明代理并且有一个功能强大的服务器状态监控界面。
- 4.拥有功能强大的ACL支持。
- 5.用haproxy构建群集的时候,比如后方代理两个http,如果haproxy宕机,后方的http正常运行网站也是瘫痪状态,这就造成了单点故障。
这时keepalived就登场了,keepalived基于vrrp协议,两台主机之间生成一个虚拟的ip,我们称漂移ip,漂移ip由主服务器承担,一但主服务器宕机,备份服务器就会抢占漂移ip,继续工作,有效的解决了群集中的单点故障。两者相结合,可靠稳定。
Galera Cluster
Galera Cluster是集成了Galera插件的 MySQL 集群,是一种新型的,数据不共享的,高度冗余的高可用方案。Galera 本身具有多主特性,所以 Galera Cluster 也就是 Multi-Master 的 集群结构。
基于Galera的高可用方案主要有MariaDB Galera Cluster, Mysql Galera Cluster 和 Percona XtraDB Cluster(简称PXC),目前PXC用的会比较多一些。
图中有三个实例,组成了一个集群,而这三个节点与普通主从架构不同,都可作为主节点,三个节点对等,这种一般称为 Multi-Master 架构,当有客户端要写入或读取数据时,随便连接哪个实例都一样,读到的数据相同,写入某一节点后,集群自己会将新数据同步到其他节点上,这种架构不共享任何数据,是一种高冗余架构。
PXC优点:
- 服务高可用。
- 数据同步复制(并发复制),几乎无延迟。
- 多个可同时读写节点,可实现写扩展,不过最好事先进行分库分表,让各个节点分别写不同的表或者库,避免让galera解决数据冲突。
- 新节点可以自动部署,部署操作简单。
- 数据严格一致性,尤其适合电商类应用。
- 完全兼容MySQL。
PXC缺点:
- 只支持InnoDB引擎。
- 所有表都要有主键。
- 不支持LOCK TABLE等显式锁操作。
- 加入新节点,开销大。需要复制完整的数据。
- 所有的写操作都将发生在所有节点上。
- 有多少个节点就有多少重复的数据。
- 不支持XA分布式事务协议。
关于PXC这边不做详细说明,因为比较我常用,所以打算另外开篇进行说明,并结合实际部署操作。