乐趣区

关于mysql:MySQL-数据库集群PXC-方案二

MySQL 数据库集群 -PXC 计划(二)

集群状态信息

PXC 集群信息能够分为队列信息、复制信息、流控信息、事务信息、状态信息。这些信息能够通过 SQL 查问到。每种信息的具体意义能够在官网查看。

show status like '%wsrep%';

复制信息

举例说明几个重要的信息:

状态 形容
wsrep_replicated 被其余节点复制的次数
wsrep_replicated_bytes 被其余节点复制的数据次数
wsrep_received 从其余节点处收到的写入申请总数
wsrep_received_bytes 从其余节点处收到的写入数据总数
wsrep_last_applied 同步利用次数
wsrep_last_committed 事务提交次数

队列信息

队列是一种很好的缓存机制,如果 PXC 正在满负荷工作,没有线程去执行数据的同步,同步申请会缓存到队列中,而后闲暇线程从队列中取出工作,执行同步的申请,有了队列 PXC 就能用大量的线程应答刹时大量的同步申请。

状态 形容
wsrep_local_send_queue 发送队列的长度(刹时同步的申请数量)
wsrep_local_send_queue_max 发送队列的最大长度
wsrep_local_send_queue_min 发送队列的最小长度
wsrep_local_send_queue_avg 发送队列的均匀长度
wsrep_local_recv_queue 接管队列的长度
wsrep_local_recv_queue_max 接管队列的最大长度
wsrep_local_recv_queue_min 接管队列的最小长度
wsrep_local_recv_queue_avg 接管队列的均匀长度

当发送队列的 均匀长度 (wsrep_local_send_queue_avg) 值很大,发送队列的长度 (wsrep_local_send_queue) 也很大的时候,阐明 PXC 集群同步数据的速度曾经很慢了,队列里边积压了大量的同步申请,这个时候就要检查一下网速是不是失常,或者同步的线程数量是不是太少。

当接管队列的 均匀长度 (wsrep_local_recv_queue_avg) 值很大,接管队列的长度 (wsrep_local_recv_queue) 也很大的时候,这阐明本地没有足够的线程去执行长久化的操作,减少线程 就能够解决这个问题。

流量管制信息

流量管制就是 PXC 集群在同步速度较慢的状况下,为了防止同步速度跟不上写入速度而推出的一种限速机制,就是限度数据的写入,直到同步队列的长度变小,同步速度变快为止,才会解除流量管制。流量管制的结果很重大,而且一个很小的操作就会引发流量管制。

状态 阐明
wsrep_flow_control_paused_ns 流控暂停状态下破费的总工夫(纳秒)
wsrep_flow_control_paused 流量管制暂停工夫的占比(0~1)
wsrep_flow_control_sent 发送的流控暂停事件的数量
wsrep_flow_control_recv 接管的流控暂停事件的数量
wsrep_flow_control_interval 流量管制的上限和下限。下限是队列中容许的最大申请数。如果队列达到下限,则回绝新的申请。当解决现有申请时,队列会缩小,一旦达到上限,将再次容许新的申请
wsrep_flow_control_status 流量管制状态 OFF: 敞开 0N: 开启

流控的次要起因节点之间同步的速度慢,队列积压了大量的申请,这才是流控的次要起因。

流控解决办法:

  1. 改善网速,进步带宽,更换交换机,千兆网卡更换成万兆网卡
  2. 减少线程,线程多了执行的速度也就快了。队列里边就不会积压大量的申请
  3. 晋升硬件性能,比方降级 CPU,内存以及更换光纤硬盘等等都能够进步写入速度

第一项和第三项属于更换硬件的办法,次要说一下第二个办法减少线程数晋升同步速度。在 PXC 的配置文件加上 wsrep_slave_threads 参数。代表的是本地执行队列的线程数量,个别这个数是 CPU 线程数的 1-1.5 倍。比方服务器 CPU 是 8 核 16 线程的,这里就能够写 16-24 就能够。

wsrep_slave_threads=16

节点与集群的状态信息

状态 阐明
wsrep_local_state_comment 节点状态
wsrep_cluster_status 集群状态(Primary:失常状态、Non-Primary:呈现了脑裂申请、Disconnected:不能提供服务, 呈现宕机)
wsrep_connected 节点是否连贯到集群
wsrep_ready 集群是否失常工作
wsrep_cluster_size 节点数量
wsrep_desync_count 延时节点数量
wsrep_incoming_addresses 集群节点 IP 地址

事务相干信息

状态 阐明
wsrep_cert_deps_distance 事务执行并发数
wsrep_apply_oooe 接管队列中事务的占比
wsrep_apply_oool 接管队列中事务乱序执行的频率
wsrep_apply_window 接管队列中事务的均匀数量
wsrep_commit_oooe 发送队列中事务的占比
wsrep_commit_oool 无任何意义, 不存在本地的乱序提交
wsrep_commit_window 发送队列中事务的均匀数量

PXC 节点的平安下线操作

节点用什么命令启动,就用对应的敞开命令去敞开。

  • 主节点的治理命令(第一个启动的 PXC 节点)
 systemctl start mysql@bootstrap.service
 systemctl stop mysql@bootstrap.service
 systemctl restart mysql@bootstrap.service
  • 非主节点的治理命令(非第一个启动的 PXC 节点)
service mysql start
service mysql stop
service mysql restart
  • 如果最初敞开的 PXC 节点是平安退出的,那么下次启动要最先启动这个节点,而且要以主节点启动。
  • 如果最初敞开的 PXC 节点不是平安退出的,那么要先批改 /var/lib/mysql/grastate.dat 文件,把其中的safe_to_bootstrap 属性值设置为 1,再依照主节点启动。

意外下线局部节点

平安下线节点不会让剩下的节点宕机,如果节点意外退出,集群的规模不会放大,意外退出的节点超过半数,比方三个节点意外退出了 2 个节点,那么剩下的节点就不可能读写了。其余节点依照 一般节点 启动上线即可复原 pxc 集群。

意外下线全副节点,不同时退出

如果三个节点都意外退出,那么查看 /var/lib/mysql/grastate.dat 文件,看看哪个文件的 safe_to_bootstarp 的值是 1,那么那个节点是最初意外敞开的,再依照 safe_to_bootstarp 的值启动 pxc 集群。

意外下线全副节点,同时退出

如果三个节点同时意外退出,咱们须要批改配置文件,筛选一个节点作为主节点,批改 safe_to_bootstarp 的值设置为 1,那么这个节点能够以主节点启动。

配置 MyCat 负载平衡

筹备工作(一)

咱们须要创立两个 PXC 集群,充当两个分片。

上文中曾经创立进去了一个分片,参考步骤而后创立进去第二个分片。

最初会有 6 个 centos 虚拟机。

我的第一个如下:

  • 主:192.168.3.137
  • 从:192.168.3.138
  • 从:192.168.3.139

我的第二个如下:

  • 主:192.168.3.141
  • 从:192.168.3.143
  • 从:192.168.3.144

MyCat:192.168.3.146

筹备工作(二)

在 192.168.3.146 Centos 服务器上进行如下操作:

因为 MyCat 是依赖 jdk 的所以咱们先装置 jdk 环境。

yum install -y java-1.8.0-openjdk-devel.x86_64

配置 JAVA_HOME 环境变量

ls -lrt /etc/alternatives/java
vim /etc/profile
source /etc/profile

export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.272.b10-1.el7_9.x86_64/

输出 java -version 如下图就实现配置。

筹备工作(三)

下载 mycat

http://dl.mycat.org.cn/1.6.5/

上传 MyCat 压缩包到虚拟机,并解压。

凋谢防火墙 8066 和 9066 端口:

firewall-cmd --zone=public --add-port=8066/tcp --permanent
firewall-cmd --zone=public --add-port=9066/tcp --permanent
firewall-cmd --reload

敞开 SELINUX

vim /etc/selinux/config

把 SELINUX 属性值设置成 disabled,之后保留。重启。

reboot

批改 MyCat 的 bin 目录中所有.sh 文件的权限:

chmod -R 777 ./*.sh

MyCat 启动与敞开

启动 MyCat:./mycat start
查看启动状态:./mycat status
进行:./mycat stop
重启:./mycat restart

筹备工作(四)

批改配置文件:

批改 server.xml 文件,设置 MyCat 帐户和虚构逻辑库

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://io.mycat/">
    <system>
        <property name="nonePasswordLogin">0</property>
        <property name="useHandshakeV10">1</property>
        <property name="useSqlStat">0</property>
        <property name="useGlobleTableCheck">0</property>
        <property name="sequnceHandlerType">2</property>
        <property name="subqueryRelationshipCheck">false</property>
        <property name="processorBufferPoolType">0</property>
        <property name="handleDistributedTransactions">0</property>
        <property name="useOffHeapForMerge">1</property>
        <property name="memoryPageSize">64k</property>
        <property name="spillsFileBufferSize">1k</property>
        <property name="useStreamOutput">0</property>
        <property name="systemReserveMemorySize">384m</property>
        <property name="useZKSwitch">false</property>
    </system>
    <!-- 这里是设置的 admin 用户和虚构逻辑库 -->
    <user name="admin" defaultAccount="true">
        <property name="password">Abc_123456</property>
        <property name="schemas">test</property>
    </user>
</mycat:server>

批改 schema.xml 文件,设置数据库连贯和虚构数据表

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
    <!-- 配置数据表 -->
    <schema name="test" checkSQLschema="false" sqlMaxLimit="100">
        <table name="t_user" dataNode="dn1,dn2" rule="mod-long" />
    </schema>
    <!-- 配置分片关系 -->
    <dataNode name="dn1" dataHost="cluster1" database="test" />
    <dataNode name="dn2" dataHost="cluster2" database="test" />
    <!-- 配置连贯信息 -->
    <dataHost name="cluster1" maxCon="1000" minCon="10" balance="2"
                writeType="1" dbType="mysql" dbDriver="native" switchType="1"
                slaveThreshold="100">
        <heartbeat>select user()</heartbeat>
        <writeHost host="W1" url="192.168.3.137:3306" user="admin"
                     password="Abc_123456">
            <readHost host="W1R1" url="192.168.3.138:3306" user="admin"
                        password="Abc_123456" />
            <readHost host="W1R2" url="192.168.3.139:3306" user="admin"
                        password="Abc_123456" />
        </writeHost>
        <writeHost host="W2" url="192.168.3.138:3306" user="admin"
                     password="Abc_123456">
            <readHost host="W2R1" url="192.168.3.137:3306" user="admin"
                        password="Abc_123456" />
            <readHost host="W2R2" url="192.168.3.139:3306" user="admin"
                        password="Abc_123456" />
        </writeHost>
    </dataHost>
    <dataHost name="cluster2" maxCon="1000" minCon="10" balance="2"
                writeType="1" dbType="mysql" dbDriver="native" switchType="1"
                slaveThreshold="100">
        <heartbeat>select user()</heartbeat>
        <writeHost host="W1" url="192.168.3.141:3306" user="admin"
                   password="Abc_123456">
            <readHost host="W1R1" url="192.168.3.143:3306" user="admin"
                        password="Abc_123456" />
            <readHost host="W1R2" url="192.168.3.144:3306" user="admin"
                        password="Abc_123456" />
        </writeHost>
        <writeHost host="W2" url="192.168.3.143:3306" user="admin"
                   password="Abc_123456">
            <readHost host="W2R1" url="192.168.3.141:3306" user="admin"
                        password="Abc_123456" />
            <readHost host="W2R2" url="192.168.3.144:3306" user="admin"
                        password="Abc_123456" />
        </writeHost>
    </dataHost>
</mycat:schema>

批改 rule.xml 文件,把 mod-long 的 count 值批改成 2

<function name="mod-long" class="io.mycat.route.function.PartitionByMod">
    <property name="count">2</property>
</function>

重启 MyCat。

测试

在两个分片中都创立 t_user 表:

CREATE TABLE t_user(
    id INT UNSIGNED PRIMARY KEY,
    username VARCHAR(200) NOT NULL,
    password VARCHAR(2000) NOT NULL,
    tel CHAR(11) NOT NULL,
    locked TINYINT(1) UNSIGNED NOT NULL DEFAULT 0,
    INDEX idx_username(username) USING BTREE,
    UNIQUE INDEX unq_username(username) USING BTREE
);

近程连贯 mycat。

向 t_user 表写入数据,感触数据的切分。

USE test;
select * from t_user;
#第一条记录被切分到第二个分片
INSERT INTO t_user(id,username,password,tel,locked) VALUES(1,"Jack",HEX(AES_ENCRYPT('123456','HelloWorld')),'1333222111',false);
#第二条记录被切分到第一个分片
INSERT INTO t_user(id,username,password,tel,locked) VALUES(2,"Rose",HEX(AES_ENCRYPT('123456','HelloWorld')),'1335555111',false);

能够查看对应的库中都是没有问题的。

数据切分

切分算法 实用场合 备注
主键求模切分 数据增长迟缓,难于减少分片 有明确主键值
枚举值切分 归类存储数据,实用于大多数业务
主键范畴切分 数据快速增长,容易减少分片 有明确主键值
日期切分 数据快速增长,容易减少分片

主键求模切分

下面的示例中,应用的就是主键求模切分,其特点如下:

  • 主键求模切分适宜用在初始数据很大,然而数据增长不快的场景。例如,地图产品、行政数据、企业数据等。
  • 主键求模切分的弊病在于扩大新分片难度大,迁徙的数据太多。
  • 如果须要扩大分片数量,倡议扩大后的分片数量是原有分片的 2n 倍。例如,本来是两个分片,扩大后是四个分片。

主键范畴切分

  • 主键范畴切分适宜用在数据快速增长的场景。
  • 容易减少分片,须要有明确的主键列。

日期切分

  • 日期切分适宜用在数据快速增长的场景。
  • 容易减少分片,须要有明确的日期列。

枚举值切分

  • 枚举值切分适宜用在归类存储数据的场景,适宜大多数业务。
  • 枚举值切分依照某个字段的值(数字)与 mapFile 配置的映射关系来切分数据。
  • 枚举值切分的弊病在于分片存储的数据不够平均。

rule.xml 中减少配置如下:

<!-- 定义分片规定 -->
<tableRule name="sharding-customer">
        <rule>
      <!-- 定义应用哪个列作为分片列 -->
            <columns>sharding_id</columns>
            <algorithm>customer-hash-int</algorithm>
        </rule>
    </tableRule>
<!-- 定义分片算法 -->
<function name="customer-hash-int"
        class="io.mycat.route.function.PartitionByFileMap">
  <!-- 定义 mapFile 的文件名,位于 conf 目录下 -->
        <property name="mapFile">customer-hash-int.txt</property>
</function>

conf 目录下创立 customer-hash-int.txt 文件,定义区号与分片索引的对应关系:0 代表第一个分片,1 代表第二个分片。

101=0
102=0
103=0
104=1
105=1
106=1

配置schema.xml,减少一个逻辑表,并将其分片规定设置为sharding-customer

<schema name="test" checkSQLschema="true" sqlMaxLimit="100" randomDataNode="dn1">
        <table name="t_user" dataNode="dn1,dn2" rule="mod-long"/>
        <table name="t_customer" dataNode="dn1,dn2" rule="sharding-customer"/>
</schema>

进入 MyCat 中执行热加载语句,该语句的作用能够使 Mycat 不必重启就能利用新的配置:

 reload @@config_all;

在两个分片中别离执行如下建表语句:

USE test;
CREATE TABLE t_customer(
    id INT UNSIGNED PRIMARY KEY,
    username VARCHAR(200) NOT NULL,
    sharding_id INT NOT NULL
);

之后咱们在 MyCat 中进行查问看看:

也是 ok 的。

接着咱们减少一条数据:

insert into t_customer(id,username,sharding_id) values (1,'Michelle',101);
insert into t_customer(id,username,sharding_id) values (2,'Jack',102);

查看第一个分片能够看到数据曾经切分过去了

如果咱们再减少一条 SQL:

insert into t_customer(id,username,sharding_id) values (3,'Smith',105);

很显然,数据被分到了第二个分片中。

父子表

当有关联的数据存储在不同的分片时,就会遇到表连贯的问题,在 MyCat 中是不容许跨分片做表连贯查问的。为了解决跨分片表连贯的问题,MyCat 提出了父子表这种解决方案。

父子表规定父表能够有任意的切分算法,但与之关联的子表不容许有切分算法,即子表的数据总是与父表的数据存储在一个分片中。父表不论应用什么切分算法,子表总是跟随着父表存储。

例如,用户表与订单表是有关联关系的,咱们能够将用户表作为父表,订单表作为子表。当 A 用户被存储至分片 1 中,那么 A 用户产生的订单数据也会跟随着存储在分片 1 中,这样在查问 A 用户的订单数据时就不须要跨分片了。如下图所示:

配置父子表

t_customer 中减少 childTable。须要留神的是一个 table 能够有多个 childTable。

<table name="t_customer" dataNode="dn1,dn2" rule="sharding-customer">
    <childTable name="t_orders" primaryKey="ID" joinKey="customer_id" parentKey="id"/>
</table>

进入 MyCat 中执行热加载语句,该语句的作用能够使 Mycat 不必重启就能利用新的配置:

 reload @@config_all;

在两个分片中执行建表 SQL:

USE test;
CREATE TABLE t_orders(
    id INT UNSIGNED PRIMARY KEY,
    customer_id INT NOT NULL,
    datetime TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

执行胜利后,咱们插入些数据测试:

USE test;
insert into t_orders(id,customer_id) values (1,1);
insert into t_orders(id,customer_id) values (2,1);
insert into t_orders(id,customer_id) values (3,1);
insert into t_orders(id,customer_id) values (4,2);
insert into t_orders(id,customer_id) values (5,3);

咱们在第一个分片中减少了两个用户 id 为 1、2 的,在第二个分片中减少了一个用户 id 为 3 的。

所以第一个分片会有 4 条记录,而第二个分片中有一条。

因为父子表的数据都是存储在同一个分片,所以在 MyCat 上进行关联查问也是没有问题的:

组建双机热备的高可用 MyCat 集群

在之前的示例中,咱们能够看到对后端数据库集群的读写操作都是在 MyCat 上进行的。MyCat 作为一个负责接管客户端申请,并将申请转发到后端数据库集群的中间件,不可避免的须要具备高可用性。否则,如果 MyCat 呈现单点故障,那么整个数据库集群也就无奈应用了,这对整个零碎的影响是非常微小的。

所以咱们当初将要演示如何去构建一个高可用的 MyCat 集群,为了搭建 MyCat 高可用集群,除了要有两个以上的 MyCat 节点外,还须要引入 Haproxy 和 Keepalived 组件。

其中 Haproxy 作为负载平衡组件,位于最前端接管客户端的申请并将申请散发到各个 MyCat 节点上,用于保障 MyCat 的高可用。而 Keepalived 则用于实现双机热备,因为 Haproxy 也须要高可用,当一个 Haproxy 宕机时,另一个备用的 Haproxy 可能马上接替。也就说同一时间下只会有一个 Haproxy 在运行,另一个 Haproxy 作为备用处于期待状态。当正在运行中的 Haproxy 因意外宕机时,Keepalived 可能马上将备用的 Haproxy 切换到运行状态。

Keepalived 是让主机之间争抢同一个虚构 IP(VIP)来实现高可用的,这些主机分为 Master 和 Backup 两种角色,并且 Master 只有一个,而 Backup 能够有多个。最开始 Master 先获取到 VIP 处于运行状态,当 Master 宕机后,Backup 检测不到 Master 的状况下就会主动获取到这个 VIP,此时发送到该 VIP 的申请就会被 Backup 接管到。这样 Backup 就能无缝接替 Master 的工作,以实现高可用。

引入这些组件后,最终咱们的集群架构将演变成这样子:

Haproxy 包含以下一些特色:

  • 依据动态调配的 cookie 调配 HTTP 申请。
  • 调配负载到各个服务器,同时保障服务器通过应用 HTTP Cookie 实现连贯放弃。
  • 当主服务器宕机时切换到备服务器,容许非凡端口的服务监控。
  • 做保护时通过配置能够保障业务的连续性,更加人性化。
  • 增加批改删除 HTTP Request 和 Respone 头。
  • 通过特定表达式 Block HTTP 申请。
  • 依据利用的 cookie 做连贯放弃。
  • 常有用户验证的具体的 HTML 监控报告。

Haproxy 的负载平衡算法当初具体有如下 8 种:

  • roundrobin:简略的轮询。
  • static-rr:权重轮询。
  • leastconn:起码连贯者优先。
  • source:依据申请源 IP, 这个跟 Nginx 的 ip_hash 机制相似。
  • ri:依据申请的 URI。
  • rl_param:示意依据申请的 URI 参数。
  • hdr(name):依据 HTTP 申请头来锁定每一次 HTTP 申请。
  • rdp-cookie(name):依据 cookie 来锁定并哈希每一次 TCP 申请。

这里就不再演示如何搭建第二台 Mycat 环境了

这里再说一下目前我的集群:

第一个 PXC 分片:

  • 主:192.168.3.137
  • 从:192.168.3.138
  • 从:192.168.3.139

第二个 PXC 分片:

  • 主:192.168.3.141
  • 从:192.168.3.143
  • 从:192.168.3.144

第一台 MyCat:192.168.3.146

第二台 MyCat:192.168.3.147

装置 Haproxy

因为我电脑只有 8G 内存,有点吃不消所以我的 Haproxy 都在 Mycat 服务器上。

凋谢防火墙 3306 和 4001 端口:

端口 作用
3306 TCP/IP 转发端口
4001 监控界面端口
firewall-cmd --zone=public --add-port=3306/tcp --permanent
firewall-cmd --zone=public --add-port=4001/tcp --permanent
firewall-cmd --reload

敞开 SELINUX

vim /etc/selinux/config

把 SELINUX 属性值设置成 disabled,之后保留。重启。

reboot

接着咱们装置 haproxy

yum install -y haproxy

装置实现后咱们批改对应的配置文件

vim /etc/haproxy/haproxy.cfg

记得批改为本人的 MyCat 的 IP。

global
    log         127.0.0.1 local2
    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    maxconn     4000
    user        haproxy
    group       haproxy
    daemon
    # turn on stats unix socket
    stats socket /var/lib/haproxy/stats

defaults
    mode                    http
    log                     global
    option                  httplog
    option                  dontlognull
    option http-server-close
    option forwardfor       except 127.0.0.0/8
    option                  redispatch
    retries                 3
    timeout http-request    10s
    timeout queue           1m
    timeout connect         10s
    timeout client          1m
    timeout server          1m
    timeout http-keep-alive 10s
    timeout check           10s
    maxconn                 3000

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
    # 负载平衡算法
    balance  roundrobin
    #日志格局
    option  tcplog
    # 须要被负载平衡的主机
    server   mycat_1  192.168.3.146:8066  check  port  8066 weight 1 maxconn  2000
    server   mycat_2  192.168.3.147:8066  check  port  8066 weight 1 maxconn  2000
    #应用 keepalive 检测死链
    option  tcpka

配置实现之后咱们进行启动

service haproxy start

咱们在浏览器输出 IP 测试:

http://192.168.3.146:4001/dbs

输出咱们配置的账号密码后就能够看到如下图:

Haproxy 的监控界面提供的监控信息也比拟全面,在该界面下,咱们能够看到每个主机的连贯信息及其本身状态。当主机无奈连贯时,Status一栏会显示DOWN,并且背景色也会变为红色。失常状态下的值则为UP,背景色为绿色。

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

测试 Haproxy

咱们近程连贯一下试试:

能够发现新增都是没有问题的。

咱们搭建 Haproxy 是为了让 MyCat 具备高可用的,所以最初测试一下 MyCat 是否已具备有高可用性,咱们将 147 的 MyCat 停掉。

此时,从 Haproxy 的监控界面中,能够看到 mycat_2 这个节点曾经处于下线状态了:

接着咱们再去减少一条数据试试。

从测试后果能够看到,插入和查问语句仍旧是能失常执行的。也就是说即使此时关掉一个 MyCat 节点整个数据库集群还可能失常应用,阐明当初 MyCat 集群是具备高可用性了。

利用 Keepalived 实现 Haproxy 的高可用

实现了 MyCat 集群的高可用之后,咱们还得实现 Haproxy 的高可用,因为当初的架构曾经从最开始的 MyCat 面向客户端变为了 Haproxy 面向客户端。

而同一时间只须要存在一个可用的 Haproxy,否则客户端就不晓得该连哪个 Haproxy 了。这也是为什么要采纳 VIP 的起因,这种机制能让多个节点相互接替时仍旧应用同一个 IP,客户端至始至终只须要连贯这个 VIP。所以实现 Haproxy 的高可用就要轮到 Keepalived 出场了。

先开启防火墙的 VRRP 协定:

# 开启 VRRP
firewall-cmd --direct --permanent --add-rule ipv4 filter INPUT 0 --protocol  vrrp -j ACCEPT
#利用设置
firewall-cmd --reload

装置 Keepalived

yum install -y keepalived

编辑配置文件

vim /etc/keepalived/keepalived.conf
vrrp_instance VI_1 {
    state MASTER
    interface enp0s3
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 123456
    }
    virtual_ipaddress {192.168.3.177}
}

配置阐明:

  • 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 服务:

service keepalived start

咱们 ping 一下咱们的虚拟地址试试,也是 OK 的!

另外一台步骤截然不同,这里就不演示了

测试 Keepalived

以上咱们实现了 Keepalived 的装置与配置,最初咱们来测试 Haproxy 是否已具备高可用性。

连贯胜利后,执行一些语句测试是否失常插入、查问数据:

最初测试一下 Haproxy 的高可用性,将其中一个 Haproxy 节点上的 keepalived 服务给关掉。

service keepalived stop

而后再次执行执行一些语句测试是否失常插入、查问数据,如下能失常执行代表 Haproxy 节点已具备高可用性:

功败垂成

退出移动版