vlambda博客
学习文章列表

干货!教你搭建两种MySQL集群

    

    

    随着业务的并发量不断扩大,程序往往会出现性能瓶颈,而造成性能瓶颈的主要原因往往是数据库。


    在业务初期,使用单节点数据库没有任何问题,毕竟此时没有什么并发量;但达到一定规模后,并发量上来了,那单节点数据库大概率满足不了需求了。


    数据库集群相比于单节点,在高并发场景下有很大的优势,具体体现在以下两个方面:


    【1】在读写速度性能方面,低并发情况下单节点优于数据库集群,高并发情况下数据库集群优于单节点;

    【2】在高可用方面,单节点数据库没有冗余设计无法满足高可用。


    至此,我们知道为什么要搭建数据库集群了:为了满足高并发、高可用。


|集群方案介绍



    常见的MySQL集群方案有PXC集群和Replication集群。PXC集群适合用来保存少量高价值数据,Replication集群适合用来保存大量数据。


    Replication集群方案其实就是读写分离方案,一个主节点,若干个从节点。写入数据时,只能将数据写入到主节点。读取数据时,可从集群中任意节点中读取(一般不从主节点读取,主节点只负责写入)。主从节点之间的数据同步采用异步传输,保证了数据写入的性能,但也可能会带来数据不一致的问题。Replication读写分离方案适用于读多写少且非重要数据的业务场景。

    

    Replication集群异步传输,即使同步不成功,也能正常提交数据到主节点:

干货!教你搭建两种MySQL集群

    PXC集群方案是强一致的解决了读写不一致的问题,只有同步成功了,才算成功。PXC集群各节点之间的数据同步是同步传输的,这也就带来了写速度慢的问题。因此,PXC集群只适合保存少量、重要的数据。


  PXC集群同步传输,同步不成功,不能正常提交数据:

干货!教你搭建两种MySQL集群


    Replication集群使用的是MySQL自带的同步机制,从节点通过读取、执行主节点的bin_log日志进行数据同步。如果人为的向从节点写入数据,将破坏从节点的bin_log日志,从而导致主从同步失败的问题,使该节点丧失主从同步功能。


    

干货!教你搭建两种MySQL集群


    Replication集群数据同步是单向的:


干货!教你搭建两种MySQL集群


    PXC集群只有在启动时有主从节点之分(第一个启动的节点为主节点,负责初始化PXC集群,在集群启动完成后,没有主从节点之分。PXC集群可以在任意节点写入数据,也可以在任意节点读取数据,数据同步是强一致且双向的。

    

干货!教你搭建两种MySQL集群

    

    PXC集群和Replication集群之间不是冲突的关系,而是互补的关系,在项目中,可以共用这两个集群。至于怎么共用,答案是使用MyCat中间件。


|要实现的最终效果



    我将会在本篇文章中讲解如何搭建PXC集群和Replication集群。会搭建2个PXC集群,通过Mycat做PXC集群的数据分片;也会搭建2个Replication集群,使用Mycat做Replication集群的数据分片。换句话说最后会搭建4个集群,用Mycat统一管理,将这4个数据库集群用到一个项目中。在本篇文章中只会讲这4个集群的搭建,Mycat的配置会单独拿出一篇文章进行说明。

 

最终实现的效果图(点击看大图):

    

干货!教你搭建两种MySQL集群



    PXC集群和Replication集群我将使用Docker进行搭建。


|前置知识



    鉴于篇幅有限,我不会把每个细节都讲到位,有些内容我会一概而过。集群的搭建我将会在虚拟机里进行,使用Docker快速搭建集群。需要有以下前置知识:

    【1】虚拟机安装centos7并配置桥接网络、配置静态IP

    【2】Linux常用命令

    【3】Docker基本命令、Docker swarm集群相关知识


  

|虚拟机安装及配置



    虚拟机安装Centos在这里不做说明,不懂的可以百度。考虑虚拟机对性能的消耗,在这里不推荐安装图形界面,所有的操作都通过ssh客户端连接进虚拟机进行操作。在本例中需要安装4个虚拟机。每个虚拟机都需要配置桥接网络并设置静态IP。


安装好的4个不带图形界面的虚拟机:


干货!教你搭建两种MySQL集群

    

虚拟机网络配置成桥接:


干货!教你搭建两种MySQL集群


虚拟机配置静态IP:


干货!教你搭建两种MySQL集群


各个虚拟机名称以及IP列表:


干货!教你搭建两种MySQL集群


|Docker安装



Docker安装非常简单,在centos上只需要一条命令:


yum install -y docker


安装完之后需要设置镜像加速,否则镜像的下载会极其缓慢,执行以下命令,命令执行完后重启Docker


curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://f1361db2.m.daocloud.io



    执行完上面的命令后需要手动编辑文件/etc/docker/daemon.json,去掉结尾的逗号


干货!教你搭建两种MySQL集群


docker启动/停止/重启命令:


service docker startservice docker stopservice docker restart


|Docker swarm集群



    在本例中我将用4台主机搭建Docker集群,数据库集群用Docker进行部署。因为我们要利用Docker环境搭建数据库集群,如果把所有的MySQL节点都部署在同一个Docker虚拟机之内,要是宿主机宕机,那么Docker里面所有的容器都不能使用了,数据库集群就彻底瘫痪了。所以我们应该采用分布式部署的方案,把MySQL节点部署在不同的Docker虚拟机之上。

    使用Docker swarm集群的目的在于将各个独立的主机虚拟化到一个局域网中,从而可以相互访问。

干货!教你搭建两种MySQL集群


    在使用Docker swarm之前,需要先在防火墙开启2377、7946、4789三个端口。
firewall-cmd --zone=public --add-port=2377/tcp --permanentfirewall-cmd --zone=public --add-port=7946/tcp --permanentfirewall-cmd --zone=public --add-port=7946/udp --permanentfirewall-cmd --zone=public --add-port=4789/tcp --permanentfirewall-cmd --zone=public --add-port=4789/udp --permanentfirewall-cmd --reload


开启防火墙端口后,需要重启一下Docker服务

service docker restart


|创建 swarm主节点



swarm节点初始化


docker swarm主节点的创建非常简单,只需要在想要当swarm主节点的主机上执行命令 docker swarm init即可

 docker swarm init


本例将使用Docker主机1(192.168.1.81)当作swarm集群的主节点。


干货!教你搭建两种MySQL集群


集群初始化、集群管理相关命令


#创建Swarm集群(该节点自动变成管理节点)docker swarm init#查看Swarm集群中的Docker节点(管理节点上执行)docker node ls#删除Swarm集群的Docker节点(管理节点上执行)docker node rm 节点ID -f#退出Swarm集群(Workd节点上执行)docker swarm leave#退出Swarm集群(管理节点上执行)docker swarm leave -f


虚拟网络相关命令


#查看虚拟网络docker network ls#创建虚拟网络docker network create -d overlay --attachable 虚拟网络名称#删除虚拟网络(先删除该网络上部署的容器)docker network rm 虚拟网络名称


创建虚拟网络


    在这里需要创建一个虚拟网络swarm_mysql,后面创建的PXC集群和Replication集群都需要加入到此虚拟网络中来。


docker network create -d overlay --attachable swarm_mysql


干货!教你搭建两种MySQL集群


|swarm从节点加入主节点




    使用创建swarm节点时给出的命令来加入主节点即可,在Dokcer主机2、3、4分别执行以下命令加入swarm集群。


干货!教你搭建两种MySQL集群


docker swarm join \ --token SWMTKN-1-267irlubjbj82v786jn25b24tckh235iraohk7qefl8xoxj39v-7hc5j3hlab9yldccruhb5bb9k \    192.168.1.81:2377


通过docker node ls命令查看集群中的节点


干货!教你搭建两种MySQL集群


|创建PXC集群



  • Pecona XtraDB Cluster 是业界主流的MySQL集群方案

  • PXC集群的数据同步具有强一致性的特点

  • PXC集群只支持InnoDB引擎

  • PXC集群中MySQL节点的数量最好不要超过15个,集群规模越大,读写速度越慢


下载镜像

docker pull percona/percona-xtradb-cluster:5.7.21docker tag percona/percona-xtradb-cluster:5.7.21 pxcdocker rmi percona/percona-xtradb-cluster:5.7.21


创建主节点容器


  • 第一个启动的PXC节点是主节点,它要初始化PXC集群

  • PXC启动之后,就没有主节点的角色了

  • PXC集群中任何节点都是可以读写数据


在Docker主机1上执行以下命令创建主节点

docker run -d -p 9001:3306 -e MYSQL_ROOT_PASSWORD=abc123456 -e CLUSTER_NAME=PXC1 -e XTRABACKUP_PASSWORD=abc123456 -v pnv1:/var/lib/mysql --privileged --name=pn1 --net=swarm_mysql pxc


主节点创建完后,需要等待一会儿才能正常连接,此时再创建从节点。


创建从节点容器


在Docker主机2上执行以下命令创建从节点

docker run -d -p 9001:3306 -e MYSQL_ROOT_PASSWORD=abc123456 -e CLUSTER_NAME=PXC1 -e XTRABACKUP_PASSWORD=abc123456 -e CLUSTER_JOIN=pn1 -v pnv2:/var/lib/mysql --privileged --name=pn2 --net=swarm_mysql pxc


    Docker主机3、4所执行的命令跟上面类似,只需要相应的修改一下名字即可。


docker run -d -p 9001:3306 -e MYSQL_ROOT_PASSWORD=abc123456 -e CLUSTER_NAME=PXC1 -e XTRABACKUP_PASSWORD=abc123456 -e CLUSTER_JOIN=pn1 -v pnv3:/var/lib/mysql --privileged --name=pn3 --net=swarm_mysql pxcdocker run -d -p 9001:3306 -e MYSQL_ROOT_PASSWORD=abc123456 -e CLUSTER_NAME=PXC1 -e XTRABACKUP_PASSWORD=abc123456 -e CLUSTER_JOIN=pn1 -v pnv4:/var/lib/mysql --privileged --name=pn4 --net=swarm_mysql pxc


最后达成以下效果:


干货!教你搭建两种MySQL集群


    PXC集群创建好了,现在我们可以在任意一个节点上读写数据了,并且整个集群的数据是一致的。

解决pxc容器闪退问题


问题一,重启后主节点无法启动。


    PXC集群会将最后一个正常退出的节点的safe_to_bootstrap参数标记为1,下次启动集群时,需要先启动上次最后一个关闭的节点后,再启动其他节点(用这个节点来初始化其他节点)。


    所以解决思路有两个:

    一是找到那个最后启动的节点,先启动它,再启动其他节点(不适用于Docker部署)。

    二是修改var/lib/mysql/grastate.dat文件,把safe_to_bootstrap参数改成1,然后就能启动了。


    因为我们是用Docker搭建的PXC集群,在搭建之初就已经规定好了容器的启动顺序(先启动pn1容器)。所以解决思路1不太适用于Docker方案,Docker PXC方案可以使用解决思路二。


使用docker volume inspect pnv1命令查看pn1容器的数据详情:


干货!教你搭建两种MySQL集群


进入数据卷目录


干货!教你搭建两种MySQL集群


编辑grastate.dat文件,将safe_to_bootstrap:改成1即可


干货!教你搭建两种MySQL集群


修改完成后使用docker start pn1命令即可成功启动pn1节点



问题二,从节点闪退。


在启动从节点时,如果主节点没有完全启动成功,从节点就会闪退。


创建两个pxc切片


    因为我们需要做基于PXC的数据切分,所以至少需要创建2个PXC集群。


干货!教你搭建两种MySQL集群


第一个PXC分片

干货!教你搭建两种MySQL集群

第二个PXC分片

干货!教你搭建两种MySQL集群



|创建Replication集群



下载镜像

docker pull mishamx/mysqldocker tag mishamx/mysql repdocker rmi mishamx/mysql


创建主节点容器

docker run -d -p 9003:3306 --name rn1 -e MYSQL_MASTER_PORT=3306 -e MYSQL_ROOT_PASSWORD=abc123456 -e MYSQL_REPLICATION_USER=backup -e MYSQL_REPLICATION_PASSWORD=backup123 -v rnv1:/var/lib/mysql --privileged --net=swarm_mysql rep


创建从节点容器


    在Docker主机2上执行以下命令创建从节点容器

docker run -d -p 9003:3306 --name rn2 -e MYSQL_MASTER_HOST=rn1 -e MYSQL_MASTER_PORT=3306 -e MYSQL_ROOT_PASSWORD=abc123456 -e MYSQL_REPLICATION_USER=backup -e MYSQL_REPLICATION_PASSWORD=backup123 -v rnv2:/var/lib/mysql --privileged --net=swarm_mysql rep


    Docker主机3、4所执行的命令跟上面类似,只需要相应的修改一下名字即可。

docker run -d -p 9003:3306 --name rn3 -e MYSQL_MASTER_HOST=rn1 -e MYSQL_MASTER_PORT=3306 -e MYSQL_ROOT_PASSWORD=abc123456 -e MYSQL_REPLICATION_USER=backup -e MYSQL_REPLICATION_PASSWORD=backup123 -v rnv3:/var/lib/mysql --privileged --net=swarm_mysql repdocker run -d -p 9003:3306 --name rn4 -e MYSQL_MASTER_HOST=rn1 -e MYSQL_MASTER_PORT=3306 -e MYSQL_ROOT_PASSWORD=abc123456 -e MYSQL_REPLICATION_USER=backup -e MYSQL_REPLICATION_PASSWORD=backup123 -v rnv4:/var/lib/mysql --privileged --net=swarm_mysql rep


    至此,Replication集群创建完成。我们可以在集群的主节点上写入数据,在任一节点读取数据。


创建两个Replication切片


在这里同样创建2个Replication集群来做数据切分


干货!教你搭建两种MySQL集群

第一个分片

干货!教你搭建两种MySQL集群


第二个分片

Replication集群注意事项


  • 主节点关闭,从节点依然可以使用,只不过主从同步机制失效。

  • 主节点不启动,从节点也能启动,主从同步失效。

  • 人为往从节点写入数据,主从同步失效。


|写在最后



    本篇文章对PXC集群和Replication集群做了简单的介绍,并讲了如何使用Docker搭建PXC集群和Replication集群,并分别搭建了2个PXC集群和2个Replication集群。后面我将讲解如何使用Mycat中间件统一管理这4个数据库集群,并实现数据切分,从而实现在业务层代码零改动的情况下,将原来的单节点数据库升级为数据库集群。


    如果你觉得这篇文章对你有帮助,麻烦关注一下我。点一点关注、点一点在看都是对我莫大的鼓励。