千家信息网

搭建高可用的Replication集群归档大量的冷数据

发表于:2024-11-22 作者:千家信息网编辑
千家信息网最后更新 2024年11月22日,冷热数据分离业务不断地在增长,集群分片中的数据也会随着时间的推移而增加,其中有相当一部分的数据是很少被使用的,例如几年前的订单记录、交易记录、商品评论等数据。这部分数据就称之为冷数据,与之相反经常被使
千家信息网最后更新 2024年11月22日搭建高可用的Replication集群归档大量的冷数据

冷热数据分离

业务不断地在增长,集群分片中的数据也会随着时间的推移而增加,其中有相当一部分的数据是很少被使用的,例如几年前的订单记录、交易记录、商品评论等数据。这部分数据就称之为冷数据,与之相反经常被使用的数据则称之为热数据。

我们都知道当MySQL的单表数据量超过两千万时,读写性能就会急剧下降。如果其中存储的大部分都是高价值的热数据还好说,可以花费资金去扩展集群分片,因为这些数据可以带来收益。但如果是低价值的冷数据,就没必要去花这个钱了。

所以我们要将冷数据从集群分片中剥离出来,存储至专门的归档数据库中,以腾出存储空间、减轻集群分片的存储压力。让集群分片尽量只存储热数据,维持一个较好的读写性能,而不必浪费存储空间在冷数据上:

在归档数据库上不适合使用InnoDB引擎,因为InnoDB的瞬时写入性能不高。通常会采用Percona出品的TokuDB作为归档数据库的存储引擎。因为该引擎具有如下特点:

  • 高压缩比,高写入性能
  • 可以在线创建索引和字段
  • 支持事务特性
  • 支持主从同步

搭建Replication集群

上一小节介绍了冷热数据分离的概念,本小节我们来搭建一个用于归档冷数据的高可用Replication集群。虽然是归档库,但也得让其具有高可用性,毕竟在实际的企业中是不允许数据库出现单点故障的。而且归档库中的数据也不是不会被使用到,只不过是使用几率不高而已。

本文中的Replication集群架构设计如下:

所谓Replication集群就是我们常说的主从架构,在Replication集群中,节点分为Master和Slave两种角色。Master主要是提供写服务,Slave则提供读服务,并且通常Slave会被设置为read_only

主从节点之间的数据同步是异步进行的,Slave使用一个线程监听Master节点的binlog日志,当Master的binlog日志发生变化时,该线程就会读取Master的binlog日志内容并写入到本地的relay_log中。然后mysql进程会定时读取relay_log并将数据写入到本地的binlog文件,这样就实现了主从之间的数据同步。如下图所示:

为了保证Replication集群的高可用,我们需要让两个数据库节点之间互为主从关系,实现双向的数据同步。这样才能在主节点挂掉时进行主从切换,否则主节点在恢复后不会向从节点同步数据,会导致节点之间的数据不一致:

准备工作

接下来开始准备集群搭建的前置环境,首先需要创建4台虚拟机,其中两台安装Percona Server做Replication集群,两台安装Haproxy和Keepalived做负载均衡和双机热备:

角色HostIP
Haproxy+KeepalivedHA-01192.168.190.135
Haproxy+KeepalivedHA-02192.168.190.143
Percona Servernode-A192.168.190.142
Percona Servernode-B192.168.190.131

每台虚拟机的配置如下:

环境版本说明:

  • 操作系统:CentOS 8
  • Percona Server:8.0.18
  • TokuDB:8.0.18
  • Haproxy:1.8.15-5.el8
  • Keepalived:2.0.10-4.el8_0.2

安装TokuDB

之前说了InnoDB因为其特性不适合作为归档数据库的存储引擎,而应采用TokuDB。TokuDB可以安装在任意MySQL的衍生版本上,本文采用的是Percona Server这个MySQL衍生版作为演示。

我这里已经事先在192.168.190.142192.168.190.131两个虚拟机上安装好了Percona Server,如不了解其安装方式的话,可参考:安装Percona Server数据库(in CentOS 8)。接下来,我们就开始为Percona Server安装TokuDB。

首先,在安装TokuDB前确保系统中已有jemalloc库,没有的话可以使用如下命令安装:

[root@node-A ~]# yum install -y jemalloc[root@node-A ~]# ls /usr/lib64/ |grep jemalloc  # 库文件所在路径libjemalloc.so.1[root@node-A ~]#

在配置文件中添加jemalloc库文件所在路径的配置:

[root@node-A ~]# vim /etc/my.cnf...[mysql_safe]malloc-lib=/usr/lib64/libjemalloc.so.1

完成配置文件的修改后,重启数据库服务:

[root@node-A ~]# systemctl restart mysqld

为了保证TokuDB的写入性能,我们需要调整一下Linux系统的大页内存管理的设置,命令如下:

# 采用动态分配内存而不是预先分配内存[root@node-A ~]# echo never > /sys/kernel/mm/transparent_hugepage/enabled# 开启内存的碎片整理[root@node-A ~]# echo never > /sys/kernel/mm/transparent_hugepage/defrag

通过官方提供的yum仓库安装TokuDB引擎:

[root@node-A ~]# yum install -y https://repo.percona.com/yum/percona-release-latest.noarch.rpm[root@node-A ~]# percona-release setup ps80[root@node-A ~]# yum install -y percona-server-tokudb.x86_64

接着使用ps-admin命令将TokuDB引擎安装到MySQL上:

[root@node-A ~]# ps-admin --enable-tokudb -uroot -p

重启数据库服务:

[root@node-A ~]# systemctl restart mysqld

数据库重启完成后,再执行一次ps-admin命令以激活TokuDB引擎:

[root@node-A ~]# ps-admin --enable-tokudb -uroot -p

最后使用show engines;语句验证一下MySQL上是否已成功安装了TokuDB引擎:


配置主从关系

首先在两个节点上分别创建用于同步的数据库账户:

create user 'backup'@'%' identified by 'Abc_123456';grant super, reload, replication slave on *.* to 'backup'@'%';flush privileges;
  • Tips:创建好账户后,需要使用该账户在两个节点互相登录一下,以确保账户是可用的

然后修改MySQL配置文件:

[root@node-A ~]# vim /etc/my.cnf[mysqld]# 设置节点的idserver_id=101# 开启binloglog_bin=mysql_bin# 开启relay_logrelay_log=relay_bin

另外一个节点也是同样的配置,只不过server_id不能是一样的:

[root@node-B ~]# vim /etc/my.cnf[mysqld]server_id=102log_bin=mysql_binrelay_log=relay_bin

修改完配置文件后,重启MySQL服务:

[root@node-A ~]# systemctl restart mysqld[root@node-B ~]# systemctl restart mysqld

配置node-Bnode-A的主从关系

进入node-B的MySQL命令行终端,分别执行如下语句:

mysql> stop slave;  -- 停止主从同步mysql> change master to master_host='192.168.190.142', master_port=3306, master_user='backup', master_password='Abc_123456';  -- 配置Master节点的连接信息mysql> start slave;  -- 启动主从同步

使用show slave status\G;语句查看主从同步状态,Slave_IO_RunningSlave_SQL_Running的值均为Yes才能表示主从同步状态是正常的:


配置node-Anode-B的主从关系

为了实现双向同步,node-Anode-B需要互为主从关系,所以还需要配置node-Anode-B的主从关系。进入node-A的MySQL命令行终端,分别执行如下语句,注意这里的master_host需要为node-B的ip:

mysql> stop slave;  -- 停止主从同步mysql> change master to master_host='192.168.190.131', master_port=3306, master_user='backup', master_password='Abc_123456';  -- 配置Master节点的连接信息mysql> start slave;  -- 启动主从同步

同样配置完成后,使用show slave status\G;语句查看主从同步状态,Slave_IO_RunningSlave_SQL_Running的值均为Yes才能表示主从同步状态是正常的:


测试主从同步

配置好两个节点的主从同步关系之后,我们就算是完成了Replication集群的搭建。接下来我们在任意一个节点创建一张归档表,看看两个节点之间是否能正常同步数据。具体的建表SQL如下:

create table t_purchase_201909 (    id int unsigned primary key,    purchase_price decimal(10, 2) not null comment '进货价格',    purchase_num int unsigned not null comment '进货数量',    purchase_sum decimal(10, 2) not null comment '进货总价',    purchase_buyer int unsigned not null comment '采购者',    purchase_date timestamp not null default current_timestamp comment '采购日期',    company_id int unsigned not null comment '进货企业的id',    goods_id int unsigned not null comment '商品id',    key idx_company_id(company_id),    key idx_goods_id(goods_id)) engine=TokuDB comment '2019年9月的进货数据归档表';

我这里是能够正常进行同步的,如图两个节点都能看到这张表:


安装Haproxy

到此为止,我们就完成了Replication集群的搭建及测试。接下来就是得让Replication集群具有高可用的特性,这就轮到Haproxy上场了。Haproxy是一款提供高可用性、负载均衡以及基于TCP(第四层)和HTTP(第七层)应用的代理软件。使用Haproxy可以对MySQL集群进行负载均衡,赋予集群高可用性并发挥集群的性能。

Haproxy由于是老牌的负载均衡组件了,所以CentOS的yum仓库中自带有该组件的安装包,安装起来就非常简单。安装命令如下:

[root@HA-01 ~]# yum install -y haproxy

安装完成后,编辑Haproxy的配置文件,添加监控界面及需要代理的数据库节点配置:

[root@HA-01 ~]# vim /etc/haproxy/haproxy.cfg# 在文件的末尾添加如下配置项# 监控界面配置listen admin_stats    # 绑定的ip及监听的端口    bind 0.0.0.0:4001    # 访问协议    mode http    # URI 相对地址    stats uri /dbs    # 统计报告格式    stats realm Global\ statistics    # 用于登录监控界面的账户密码    stats auth admin:abc123456# 数据库负载均衡配置listen proxy-mysql    # 绑定的ip及监听的端口    bind 0.0.0.0:3306    # 访问协议    mode tcp    # 负载均衡算法    # roundrobin:轮询    # static-rr:权重    # leastconn:最少连接    # source:请求源ip    balance roundrobin    # 日志格式    option tcplog    # 需要被负载均衡的主机    server node-A 192.168.190.142:3306 check port 3306 weight 1 maxconn 2000    server node-B 192.168.190.131:3306 check port 3306 weight 1 maxconn 2000    # 使用keepalive检测死链    option tcpka

由于配置了3306端口用于TCP转发,以及4001作为Haproxy监控界面的访问端口,所以在防火墙上需要开放这两个端口:

[root@HA-01 ~]# firewall-cmd --zone=public --add-port=3306/tcp --permanent[root@HA-01 ~]# firewall-cmd --zone=public --add-port=4001/tcp --permanent[root@HA-01 ~]# firewall-cmd --reload

完成以上步骤后,启动Haproxy服务:

[root@HA-01 ~]# systemctl start haproxy

然后使用浏览器访问Haproxy的监控界面,初次访问会要求输入用户名密码,这里的用户名密码就是配置文件中所配置的:

登录成功后,就会看到如下页面:

Haproxy的监控界面提供的监控信息也比较全面,在该界面下,我们可以看到每个主机的连接信息及其自身状态。当主机无法连接时,Status一栏会显示DOWN,并且背景色也会变为红色。正常状态下的值则为UP,背景色为绿色。

另一个Haproxy节点也是使用以上的步骤进行安装和配置,这里就不再重复了。


测试Haproxy

Haproxy服务搭建起来后,我们来使用远程工具测试一下能否通过Haproxy正常连接到数据库。如下:

连接成功后,在Haproxy上执行一些SQL语句,看看能否正常插入数据和查询数据:

我们搭建Haproxy是为了让Replication集群具备高可用的,所以最后测试一下Replication集群是否已具备有高可用性,首先将其中一个节点给停掉:

[root@node-B ~]# systemctl stop mysqld

此时,从Haproxy的监控界面中,可以看到node-B这个节点已经处于下线状态了:

现在集群中还剩一个节点,然后我们到Haproxy上执行一些SQL语句,看看是否还能正常插入数据和查询数据:

从测试结果可以看到,插入和查询语句依旧是能正常执行的。也就是说即便此时关掉一个节点整个数据库集群还能够正常使用,说明现在Replication集群是具有高可用性了。


利用Keepalived实现Haproxy的高可用

实现了Replication集群的高可用之后,我们还得实现Haproxy的高可用,因为Haproxy作为一个负责接收客户端请求,并将请求转发到后端数据库集群的入口,不可避免的需要具备高可用性。否则Haproxy出现单点故障,就无法访问被Haproxy代理的所有数据库集群节点了,这对整个系统的影响是十分巨大的。

在同一时间只需要存在一个可用的Haproxy,否则客户端就不知道该连哪个Haproxy了。这也是为什么要采用Keepalived的虚拟IP的原因,这种机制能让多个节点互相接替时依旧使用同一个IP,客户端至始至终只需要连接这个虚拟IP。所以实现Haproxy的高可用就要轮到Keepalived出场了,在安装Keepalived之前需要开启防火墙的VRRP协议:

[root@HA-01 ~]# firewall-cmd --direct --permanent --add-rule ipv4 filter INPUT 0 --protocol vrrp -j ACCEPT[root@HA-01 ~]# firewall-cmd --reload

然后就可以使用yum命令安装Keepalived了:

[root@HA-01 ~]# yum install -y keepalived

安装完成后,编辑keepalived的配置文件:

[root@HA-01 ~]# mv /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.bak  # 不使用自带的配置文件[root@HA-01 ~]# vim /etc/keepalived/keepalived.confvrrp_instance VI_1 {   state MASTER   interface ens32   virtual_router_id 51   priority 100   advert_int 1   authentication {         auth_type PASS       auth_pass 123456   }   virtual_ipaddress {       192.168.190.101   }}

配置说明:

  • state MASTER:定义节点角色为master,当角色为master时,该节点无需争抢就能获取到VIP。集群内允许有多个master,当存在多个master时,master之间就需要争抢VIP。为其他角色时,只有master下线才能获取到VIP
  • interface ens32:定义可用于外部通信的网卡名称,网卡名称可以通过ip addr命令查看
  • virtual_router_id 51:定义虚拟路由的id,取值在0-255,每个节点的值需要唯一,也就是不能配置成一样的
  • priority 100:定义权重,权重越高就越优先获取到VIP
  • advert_int 1:定义检测间隔时间为1秒
  • authentication:定义心跳检查时所使用的认证信息
    • auth_type PASS:定义认证类型为密码
    • auth_pass 123456:定义具体的密码
  • virtual_ipaddress:定义虚拟IP(VIP),需要为同一网段下的IP,并且每个节点需要一致

完成以上配置后,启动keepalived服务:

[root@HA-01 ~]# systemctl start keepalived

当keepalived服务启动成功,使用ip addr命令可以查看到网卡绑定的虚拟IP:

另一个节点也是使用以上的步骤进行安装和配置,这里就不再重复了。不过要注意virtual_router_id不能配置成一样的,而virtual_ipaddress则必须配置成同一个虚拟ip。


测试Keepalived

以上我们完成了Keepalived的安装与配置,最后我们来测试Keepalived服务是否正常可用,以及测试Haproxy是否已具有高可用性。

首先,在其他节点上测试虚拟IP能否正常ping通,如果不能ping通就需要检查配置了。如图,我这里是能正常ping通的:

常见的虚拟IP ping不通的情况:

  • 防火墙配置有误,没有正确开启VRRP协议
  • 配置的虚拟IP与其他节点的IP不处于同一网段
  • Keepalived配置有误,或Keepalived根本没启动成功

确认能够从外部ping通Keepalived的虚拟IP后,使用Navicat测试能否通过虚拟IP连接到数据库:

连接成功后,执行一些语句测试能否正常插入、查询数据:

到此就基本没什么问题了,最后测试一下Haproxy的高可用性,将其中一个Haproxy节点上的Keepalived和Haproxy服务给关掉:

[root@HA-01 ~]# systemctl stop keepalived[root@HA-01 ~]# systemctl stop haproxy

然后再次执行执行一些语句测试能否正常插入、查询数据,如下能正常执行代表Haproxy节点已具有高可用性:

最后将所有的服务恢复成运行状态,验证停止的节点恢复之后数据是否是一致的。如下,我这里两个Replication节点的数据都是一致的:


实践数据归档

到此为止,我们就完成了高可用Replication集群的搭建。接下来就是实践如何将大量的冷数据从PXC集群分片中剥离出来并归档到Replication集群中,我这里有两个PXC集群分片:

  • 关于PXC集群的内容可以参考另一篇文章:为PXC集群引入Mycat并构建完整的高可用集群架构

每个分片里都有一张t_purchase表,其建表SQL如下。

create table t_purchase (    id int unsigned primary key,    purchase_price decimal(10, 2) not null comment '进货价格',    purchase_num int unsigned not null comment '进货数量',    purchase_sum decimal(10, 2) not null comment '进货总价',    purchase_buyer int unsigned not null comment '采购者',    purchase_date timestamp not null default current_timestamp comment '采购日期',    company_id int unsigned not null comment '进货企业的id',    goods_id int unsigned not null comment '商品id',    key idx_company_id(company_id),    key idx_goods_id(goods_id)) comment '进货表';

每个分片合计共存储了100w条进货数据:

其中有60w条进货数据的采购日期都是2019-11-01之前的:

现在的需求是将2019-11-01之前的数据都剥离出来进行归档,这要如何实现呢?自己写代码肯定是比较麻烦的,好在Percona工具包里提供了一个用于归档数据的工具:pt-archiver,使用该工具可以很轻松的完成数据归档,免除了自己写归档程序的麻烦。pt-archiver主要有两个用途:

  • 将线上数据导出到线下做数据处理
  • 清理过期数据,并把数据归档到本地归档表中,或者远程归档服务器

想要使用pt-archiver首先得安装Percona工具包:

[root@node-A ~]# yum install -y https://repo.percona.com/yum/percona-release-latest.noarch.rpm[root@node-A ~]# percona-release enable ps-80 release[root@node-A ~]# yum install -y percona-toolkit

安装完成后,验证pt-archiver命令是否可用:

[root@node-A ~]# pt-archiver --versionpt-archiver 3.1.0[root@node-A ~]# 

接着就可以使用pt-archiver命令进行数据的归档了,首先需要在Replication集群中创建一张归档表,表名以归档的数据日期为后缀,存储引擎使用TokuDB。具体的建表SQL如下:

create table t_purchase_201910 (    id int unsigned primary key,    purchase_price decimal(10, 2) not null comment '进货价格',    purchase_num int unsigned not null comment '进货数量',    purchase_sum decimal(10, 2) not null comment '进货总价',    purchase_buyer int unsigned not null comment '采购者',    purchase_date timestamp not null default current_timestamp comment '采购日期',    company_id int unsigned not null comment '进货企业的id',    goods_id int unsigned not null comment '商品id',    key idx_company_id(company_id),    key idx_goods_id(goods_id)) engine=TokuDB comment '2019年10月的进货数据归档表';

然后使用pt-archiver命令完成数据归档,如下示例:

[root@node-A ~]# pt-archiver --source h=192.168.190.100,P=3306,u=admin,p=Abc_123456,D=test,t=t_purchase --dest h=192.168.190.101,P=3306,u=archive,p=Abc_123456,D=test,t=t_purchase_201910 --no-check-charset --where 'purchase_date < "2019-11-01 0:0:0"' --progress 50000 --bulk-delete --bulk-insert --limit=100000 --statistics
  • Tips:pt-archiver命令是使用load data语句进行数据导入的,所以要确保MySQL开启了local_infile。如果没有开启的话归档数据会失败,可以使用set global local_infile = 'ON';语句来开启local_infile

命令参数说明:

  • --source:指定从哪个数据库读取数据
  • --dest:指定将数据归档至哪个数据库
  • --no-check-charset:不检查数据的字符集
  • --where:指定将哪些数据进行归档,在本例中就是将2019-09-11之前的数据进行归档
  • --progress:指定当归档完多少条数据时打印一次状态信息
  • --bulk-delete:指定批量删除归档数据。数据的删除有事务保证,不会出现未归档成功就将数据删除了的情况
  • --bulk-insert:指定批量写入归档数据
  • --limit:指定每次归档多少条数据
  • --statistics:归档数据完成后打印统计信息

等待大约15分钟左右数据就归档完成了,输出的统计信息如下:

此时在Replication集群上可以看到那60w数据都已经存储到了归档表中:

而原本的PXC集群中就只剩40w数据了:

如此一来我们就完成了冷热数据分离,并将大量的冷数据存储至指定的归档数据库中。


总结

  • 将冷热数据分离,低价值的冷数据存储至归档库,维持热数据的读写效率
  • 使用TokuDB引擎保存归档数据,拥有高速写入特性
  • 使用双机热备方案搭建归档库,具备高可用性
  • 使用pt-archiver可以导出大量数据并归档存储,且简便易行
数据 集群 节点 配置 主从 数据库 同步 命令 存储 测试 服务 语句 两个 可用性 引擎 文件 状态 信息 界面 监控 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 网络安全手抄报漂亮的视频 上海统一软件开发推广 做软件开发去哪些城市 如何在数据库中输入数据库 互联网科技在商标注册哪类 网络安全服务需要哪些资质 求生之路2 组服务器 郑大有软件开发专业吗 网络安全管理员权限等级是多少 传统软件开发的常用技术 河北金拓互联网科技有限公司 爱可生 数据库服务 数据库技术主要研究问题 网络安全艺术字立体简单 数据库加密工具 无锡专业软件开发价格多少 轻薄本适合不适合软件开发 sql是什么数据库 山西数字化城管软件开发系统 新媒体运营和软件开发 学校公物租借数据库 服务器上不把服务器放网上 软件开发前后端的配合协作 软件开发实名认证 数据库地址是域名 网络安全普法宣传具体举措 网络安全应急处置预案制度 深圳市路特斯网络技术 计算机网络技术实践课程报告册 法律与实现网络安全
0