ToB企服应用市场:ToB评测及商务社交产业平台

标题: 数据库扩容也可以如此丝滑,MySQL千亿级数据生产环境扩容实战 [打印本页]

作者: 盛世宏图    时间: 2022-8-28 16:00
标题: 数据库扩容也可以如此丝滑,MySQL千亿级数据生产环境扩容实战
数据库平滑扩容

目录

1:理解传统扩容实现方案
2:理解平滑扩容双写方案
3:掌握数据库2N扩容方案
4:实现数据库双主同步
5:掌握ShardingJDBC路由以及动态扩容技术
6:掌握KeepAlived+MariaDB数据库高可用方案
1. 扩容方案剖析

1.1  扩容问题

在项目初期,我们部署了三个数据库A、B、C,此时数据库的规模可以满足我们的业务需求。为了将数据做到平均分配,我们在Service服务层使用uid%3进行取模分片,从而将数据平均分配到三个数据库中。
如图所示:

后期随着用户量的增加,用户产生的数据信息被源源不断的添加到数据库中,最终达到数据库的最佳存储容量。如果此时继续向数据库中新增数据,会导致数据库的CRUD等基本操作变慢,进而影响整个服务的响应速度。
这时,我们需要增加新的节点,对数据库进行水平扩容,那么加入新的数据库D后,数据库的规模由原来的3个变为4个。
如图所示:

此时由于分片规则发生了变化(uid%3 变为uid%4),导致大部分的数据,无法命中原有的数据,需要重新进行分配,要做大量的数据迁移处理。
比如之前uid如果是uid=3取模3%3=0, 是分配在A库上,新加入D库后, uid=3取模3%4=3,分配在D库上;

新增一个节点, 大概会有90%的数据需要迁移, 这样会面临大量的数据压力,并且对服务造成极大的不稳定性。
1.2  停机方案


停止服务之后, 能够保证迁移工作的正常进行, 但是服务停止,伤害用户体验, 并造成了时间压力, 必须在指定的时间内完成迁移。
1.3  停写方案


缺点:在数据的复制过程需要消耗大量的时间,停写时间太长,数据需要先复制,再清理冗余数据
1.4  日志方案

核心是通过日志进行数据库的同步迁移, 主要操作步骤如下:


日志记录不用关注新增了哪些信息,修改的数据格式,只需要记录以上数据信息,这样日志格式是固定的, 这样能保证方案的通用性。
服务升级日志记录功能风险较小:
写和修改接口是少数, 改动点少;
升级只是增加了一些日志,采用异步方式实现, 对业务功能没有太多影响。

研发一个日志迁移工具,把上面迁移数据过程中的差异数据追平,处理步骤:
读取log日志,获取具体是哪个库、表和主键发生了变化修改;
把旧库中的主键记录读取出来
根据主键ID,把新库中的记录替换掉
这样可以最大程度的保障数据的一致性。风险分析:
整个过程, 仍然是旧库对线上提供服务;
日志迁移工具实现的复杂度较低;
任何时间发现问题, 可以重新再来,有充分的容错空间;
可以限速重放处理日志, 处理过程不会因为对线上影响造成时间压力。
但是, 日志增量同步完成之后, 还不能切换到新的数据库。
因为日志增量同步过程中,旧库中可能有数据发生变化, 导致数据不一致,所以需要进一步读取日志, 追平数据记录; 日志增量同步过程随时可能会产生新的数据, 新库与旧库的数据追平也会是一个无限逼近的过程。


但是在极限情况下, 即便通过上面的数据校验处理, 也有可能出现99.99%数据一致, 不能保障完全一致,这个时候可以在旧库做一个readonly只读功能, 或者将流量屏蔽降级,等待日志增量同步工具完全追平后, 再进行新库的切换。
至此,完成日志方案的迁移扩容处理, 整个过程能够持续对线上提供服务, 只会短暂的影响服务的可用性。
这种方案的弊端,是操作繁琐,需要适配多个同步处理工具,成本较高, 需要制定个性化业务的同步处理, 不具备普遍性,耗费的时间周期也较长。
1.5  双写方案(中小型数据)


双写方案可通过canal或mq做实现。
1.6  平滑2N方案(大数据量)




由于之前uid%2的数据是分配在2个库里面,扩容之后需要分布到4个库中,但由于旧数据仍存在(uid%4=0的节点,还有一半uid%4=2的数据),所以需要对冗余数据做一次清理。
这个清理,并不会影响线上数据的一致性,可以随时随地进行。

2.  平滑2N扩容方案实践

2.1  实现应用服务级别的动态扩容

扩容前部署架构:

2.1.1 MariaDB服务安装

2.1.2 MariaDB双主同步

2.1.3 KeepAlived安装与高可用配置

2.1.4 搭建应用服务工程


2.2  实现数据库的秒级平滑2N扩容

扩容部署架构:

2.2.1 新增数据库VIP

2.2.2 应用服务增加动态数据源

2.2.3 解除原双主同步

mysql -uroot -p654321
2.2.4 安装MariaDB扩容服务器

2.2.5 增加KeepAlived服务实现高可用

2.2.6 清理数据并验证

3.keepalived高可用配置大全

在Server1(192.168.116.140)中执行:
  1. MariaDB [(none)]> change master to master_host='192.168.116.141',master_user='replica', master_password='replica', master_port=3306, master_log_file='mysql-bin.000005', master_log_pos=3207, master_connect_retry=30;
复制代码
在Server2(192.168.116.141)中执行:
  1. MariaDB [(none)]> change master to master_host='192.168.116.140',master_user='replica', master_password='replica', master_port=3306, master_log_file='mysql-bin.000012', master_log_pos=1951, master_connect_retry=30;
复制代码
在Server3(192.168.116.142)中执行:
  1. MariaDB [(none)]> change master to master_host='192.168.116.140',master_user='replica', master_password='replica', master_port=3306, master_log_file='mysql-bin.000013', master_log_pos=2781, master_connect_retry=30;
  2. Query OK, 0 rows affected (0.01 sec)
复制代码
在Server4(192.168.116.143)中执行:
  1. MariaDB [(none)]> change master to master_host='192.168.116.141',master_user='replica', master_password='replica', master_port=3306, master_log_file='mysql-bin.000005', master_log_pos=7358, master_connect_retry=30;
  2. Query OK, 0 rows affected (0.01 sec)
复制代码
Server1和Server2双主关系

Server1: keepalived.conf

vi /etc/keepalived/keepalived.conf
  1. global_defs {
  2.    router_id vip1
  3. }
  4. vrrp_instance VI_1 {
  5.     state BACKUP
  6.     interface ens33
  7.     virtual_router_id 111
  8.     priority 100
  9.     advert_int 1
  10.     authentication {
  11.         auth_type PASS
  12.         auth_pass 6666
  13.     }
  14.     virtual_ipaddress {
  15.         192.168.116.150
  16.     }
  17. }
  18. virtual_server 192.168.116.150 3306 {
  19.     delay_loop 6
  20.     lb_algo rr
  21.     lb_kind DR // NAT|DR|TUN
  22.     persistence_timeout 0
  23.     protocol TCP
  24.     real_server 192.168.116.140 3306 {
  25.     notify_down /usr/local/shell/mariadb.sh
  26.     weight 1
  27.     TCP_CHECK {
  28.        connect_timeout 10
  29.        retry 3
  30.        delay_before_retry 3
  31.        connect_port 3306
  32.        }
  33.     }
  34. }
复制代码
Server2:keepalived.conf

vi /etc/keepalived/keepalived.conf
  1. global_defs {
  2.    router_id vip2
  3. }
  4. vrrp_instance VI_1 {
  5.     state BACKUP
  6.     interface ens33
  7.     virtual_router_id 111
  8.     priority 98
  9.     advert_int 1
  10.     authentication {
  11.         auth_type PASS
  12.         auth_pass 6666
  13.     }
  14.     virtual_ipaddress {
  15.         192.168.116.150
  16.     }
  17. }
  18. virtual_server 192.168.116.150 3306 {
  19.     delay_loop 6
  20.     lb_algo rr
  21.     lb_kind DR
  22.     persistence_timeout 0
  23.     protocol TCP
  24.     real_server 192.168.116.141 3306{
  25.     notify_down /usr/local/shell/mariadb.sh
  26.     weight 1
  27.     TCP_CHECK {
  28.        connect_timeout 10
  29.        retry 3
  30.        delay_before_retry 3
  31.        connect_port 3306
  32.        }
  33.     }
  34. }
复制代码
新增数据库VIP

Server2:keepalived.conf

vi /etc/keepalived/keepalived.conf
  1. global_defs {
  2.    router_id vip2
  3. }
  4. vrrp_instance VI_1 {
  5.     state BACKUP
  6.     interface ens33
  7.     virtual_router_id 112
  8.     priority 100
  9.     advert_int 1
  10.     authentication {
  11.         auth_type PASS
  12.         auth_pass 6666
  13.     }
  14.     virtual_ipaddress {
  15.         192.168.116.151
  16.     }
  17. }
  18. virtual_server 192.168.116.151 3306 {
  19.     delay_loop 6
  20.     persistence_timeout 0
  21.     protocol TCP
  22.     real_server 192.168.116.141 3306{
  23.     notify_down /usr/local/shell/mariadb.sh
  24.     weight 1
  25.     TCP_CHECK {
  26.        connect_timeout 10
  27.        retry 3
  28.        delay_before_retry 3
  29.        connect_port 3306
  30.        }
  31.     }
  32. }
复制代码
Server1和Server3双主关系

Server3: keepalived.conf

vi /etc/keepalived/keepalived.conf
  1. global_defs {
  2.    router_id vip3
  3. }
  4. vrrp_instance VI_1 {
  5.     state BACKUP
  6.     interface ens33
  7.     virtual_router_id 111
  8.     priority 98
  9.     advert_int 1
  10.     authentication {
  11.         auth_type PASS
  12.         auth_pass 6666
  13.     }
  14.     virtual_ipaddress {
  15.         192.168.116.150
  16.     }
  17. }
  18. virtual_server 192.168.116.150 3306 {
  19.     delay_loop 6
  20.     lb_algo rr
  21.     lb_kind DR
  22.     persistence_timeout 0
  23.     protocol TCP
  24.     real_server 192.168.116.142 3306 {
  25.     notify_down /usr/local/shell/mariadb.sh
  26.     weight 1
  27.     TCP_CHECK {
  28.        connect_timeout 10
  29.        retry 3
  30.        delay_before_retry 3
  31.        connect_port 3306
  32.        }
  33.     }
  34. }
复制代码
Server2和Server4双主关系

Server4: keepalived.conf

vi /etc/keepalived/keepalived.conf
  1. global_defs {
  2.    router_id vip4
  3. }
  4. vrrp_instance VI_1 {
  5.     state BACKUP
  6.     interface ens33
  7.     virtual_router_id 112
  8.     priority 98
  9.     advert_int 1
  10.     authentication {
  11.         auth_type PASS
  12.         auth_pass 6666
  13.     }
  14.     virtual_ipaddress {
  15.         192.168.116.151
  16.     }
  17. }
  18. virtual_server 192.168.116.151 3306 {
  19.     delay_loop 6
  20.     lb_algo rr
  21.     lb_kind DR
  22.     persistence_timeout 0
  23.     protocol TCP
  24.     real_server 192.168.116.143 3306{
  25.     notify_down /usr/local/shell/mariadb.sh
  26.     weight 1
  27.     TCP_CHECK {
  28.        connect_timeout 10
  29.        retry 3
  30.        delay_before_retry 3
  31.        connect_port 3306
  32.        }
  33.     }
  34. }
复制代码
本文由传智教育博学谷 - 狂野架构师教研团队发布
如果本文对您有帮助,欢迎关注和点赞;如果您有任何建议也可留言评论或私信,您的支持是我坚持创作的动力
转载请注明出处!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4