1、Mysql主从模式介绍
Mysql主从模式是基于Mysql集群的分布式部署来实现的,其中在集群中,Master节点主要负责数据的分发和slave节点的管理。因此Master节点主要负责数据的写入和分发。而slave节点主要负责数据的读取。基本的master和slave的分工作业,如下图所示:
在主从模式下的Mysql数据复制实现的一台服务充当主服务器,其他一台或者多台服务器充当从服务器。这得益于Mysql支持单向、异步的数据复制。此时主服务器将更新写入二进制日志文件,并维护文件的一个索引以跟踪日志循环。这些日志可以记录发送到从服务器的更新。当一个从服务器连接主服务器时,它通知主服务器从服务器的日志中读取的最后一次成功更新的位置。从服务器接受从那时起发生的任何更新,然后封锁并等待主服务器通知新的更新。其数据在主从服务器之间的复制流程如下图所示:
根据上述流程图所示,从服务器创建两个进程:
(1)I/O进程:负责读取主服务器的二进制日志文件的数据,并将数据写入到从服务器的中继日志(Relay log)中;
(2)SQL进程:负责读取中继日志中的数据,并且将中继操作返回给从服务器。
在进行Mysql数据复制过程中,为了避免用户对主服务器上的表进行的更新与对从服务器上的表所进行的更新之间的冲突,所有的表更新都是在主服务器实现的,并且实现的是单向复制。从上述流程图来看,所有的写操作都是单向实现的。
单向复制有利于健壮性、速度和系统管理:
- 主服务器/从服务器设置增加了健壮性。主服务器出现问题时,可以切换到从服务器做备份;
- 通过在主服务器和从服务器之间切分处理用户查询的负荷,可以得到更好的用户响应时间。SELECT查询可以发送到从服务器以降低主服务器的查询处理负荷。但修改数据的语句仍然应该在主服务器上执行,以便主服务器和从服务器保持同步。如果非更新查询为主,该负载均衡策略很有效,但一般是更新查询;
- 使用复制的另一个好处是可以食用一个从服务器之行备份,而不悔干扰主服务器。在备份过程中主服务器可以继续处理更新。
MySQL提供了数据库的同步功能,这对我们实现数据库的容灾、备份、恢复、负载均衡等都是有极大帮助的。
具体的MySQL主从复制原理和数据库备至方法,可以参考一下《MySQL主从复制的原理及配置方法》:
2、基于Kubernates的MySQL主从模式部署方法
在Kubernates环境下通过创建Service和Pod的方式实现MySQL主从模式集群的部署。
(1)创建master
根据上一章节的master和slave方式,首先在Kubernates环境中也需要创建master和slave的service。依据K8s创建master服务的配置脚本如下:
apiVersion: v1
kind: Service
metadata:
name: mysql-master
labels:
name: mysql-master
spec:
ports:
- port: 3306
selector:
name: mysql-master
通过上述在K8s环境中创建一个名为mysql-master的服务器,通过如下命令,启动上述服务:
$ kubectl create -f ./mysql-master-service.yaml
执行完上述命令,通过下述命令,查看创建的服务是否成功:
$ kubectl get svc --all-namaspace
通过上图,我们发现创建的master服务已经创建成功了。
编写master容器创建的配置脚本:
piVersion: v1
kind: Pod
metadata:
name: mysql-master
labels:
name: mysql-master
spec:
nodeName: 10.1.24.137
containers:
- name: mysql-master
image: 10.1.24.90:5000/mysql-master:5.7
env:
- name: MYSQL_ROOT_PASSWORD
value: "root"
- name: MYSQL_REPLICATION_USER
value: "repl"
- name: MYSQL_REPLICATION_PASSWORD
value: "repl"
ports:
-
containerPort: 3306
hostPort: 1026
通过上述配置脚本,创建一个名叫mysql-master的容器,并且从10.1.24.90:5000服务器上下载容器镜像。配置环境变量,包括:数据库的用户和密码,以及容器端口和主机端口等。
执行如下命令,创建容器:
$ kubectl create -f ./mysql-master-pod.yaml
执行完成上述命令后,执行如下命令,查看容器是否创建成功:
$ kubectl get pods
如上图所示,发现在k8s环境中已经存在了名为mysql-master的容器,说明创建成功。
(2)创建slave
创建完成master以后,接下来创建slave。首先和上述过程一样,需要创建服务。其slave服务的配置脚本如下所示:
piVersion: v1
kind: Service
metadata:
name: mysql-slave
labels:
name: mysql-slave
spec:
ports:
- port: 3306
selector:
name: mysql-slave
然后执行如下命令,创建服务:
$ kubectl create -f ./mysql-slave_service.yaml
执行成功上述命令后,通过执行如下命令,查看服务是否已经创建成功:
$ kubectl get svc --all-namespaces
通过上图,我们发现名为mysql-slave的服务已经创建成功。
接下来,我们创建slave的容器,其配置脚本如下所示:
apiVersion: v1
kind: ReplicationController
metadata:
name: mysql-slave
labels:
name: mysql-slave
spec:
replicas: 3
selector:
name: mysql-slave
template:
metadata:
name: mysql-slave
labels:
name: mysql-slave
spec:
containers:
- name: mysql-slave
image: 10.1.24.90:5000/mysql-slave:5.7
env:
- name: MYSQL_ROOT_PASSWORD
value: "root"
- name: MYSQL_REPLICATION_USER
value: "repl"
- name: MYSQL_REPLICATION_PASSWORD
value: "repl"
- name: MYSQL_MASTER_SERVICE_HOST
value: mysql-master
ports:
- containerPort: 3306
通过上述脚本,我们需要创建一个名为mysql-slave的容器,其副本数为3,通过10.1.24.90:5000下载镜像,拉起容器。同样设置数据库的用户名和密码等等参数。
通过执行如下命令,创建slave的容器:
$ kubectl create -f ./mysql-slave-rc.yaml
执行完上述命令后,通过执行下述命令,查看slave容器创建情况:
$ kubectl get pods
通过上图我们发现通过Kubernates,我们创建了三个slave容器副本。分别是:mysql-slave-16acg、mysql-slave-4iola、mysql-slave-83v13的容器。
这样我们通过Kubernates就成功创建了master和slave的节点,从而形成1个master主服务器和3个slave从服务器的mysql主从服务器集群。
3、验证MySQL主从服务器集群部署情况
经过上述的集群部署,下面我们来验证集群是否已经可以成功运行了。
通过执行如下命令,访问数据库:
$ kubectl exec -ti mysql-master -- mysql -u root -proot
通过上述命令,我们通过root用户以及密码root登陆到mysql的主服务器节点上。
通过上图,我们发现已经成功登陆到主服务器数据库中。
通过执行如下命令,查看数据库节点的情况:
mysql> show slave hosts;
执行结果如下图所示:
通过上图,我们发现执行结果是在该主服务器下面连接这三台slave从服务器器。这与我们之前配置和创建的slave副本是吻合的。
至此表明,我们成功创建了基于Kubernates的MySQL主从服务集群。可以通过端口3306实现对数据库的访问和操作。