為PXC集群引入Mycat并構(gòu)建完整的高可用集群架構(gòu)

MySQL集群中間件比較

在CentOS8下搭建PXC集群一文中,演示了如何從零開始搭建一個(gè)三節(jié)點(diǎn)的PXC集群。但是光搭建了PXC集群還不夠,因?yàn)樵趯?shí)際的企業(yè)應(yīng)用中,可能會(huì)存在多個(gè)PXC集群,每個(gè)集群作為一個(gè)數(shù)據(jù)分片存在。因此,在完整的架構(gòu)下我們還需要為集群引入數(shù)據(jù)庫(kù)中間件,以實(shí)現(xiàn)數(shù)據(jù)分片和負(fù)載均衡等功能。

創(chuàng)新互聯(lián)IDC提供業(yè)務(wù):成都服務(wù)器托管,成都服務(wù)器租用,成都服務(wù)器托管,重慶服務(wù)器租用等四川省內(nèi)主機(jī)托管與主機(jī)租用業(yè)務(wù);數(shù)據(jù)中心含:雙線機(jī)房,BGP機(jī)房,電信機(jī)房,移動(dòng)機(jī)房,聯(lián)通機(jī)房。

市面上有許多的數(shù)據(jù)庫(kù)中間件,這些中間件主要分為兩種類型,負(fù)載均衡型和數(shù)據(jù)切分型(通常數(shù)據(jù)切分型會(huì)具備負(fù)載均衡功能):

  • 負(fù)載均衡型:
    • Haproxy
    • MySQL - Proxy
  • 數(shù)據(jù)切分型:
    • MyCat
    • Atlas
    • OneProxy
    • ProxySQL

負(fù)載均衡型中間件的作用:

  • 負(fù)載均衡提供了請(qǐng)求轉(zhuǎn)發(fā),可以將請(qǐng)求均勻的轉(zhuǎn)發(fā)到集群中的各個(gè)節(jié)點(diǎn)上,降低了單節(jié)點(diǎn)的負(fù)載
  • 使得我們可以充分利用到集群中的各個(gè)節(jié)點(diǎn)的資源,以發(fā)揮集群的性能

數(shù)據(jù)切分型中間件的作用:

  • 按照不同的路由算法分發(fā)SQL語(yǔ)句,讓不同的分片可以存儲(chǔ)不同的數(shù)據(jù),這樣就形成了數(shù)據(jù)切分
  • 讓數(shù)據(jù)均勻的存儲(chǔ)在不同的分片上,避免某一個(gè)分片的數(shù)據(jù)量超過(guò)數(shù)據(jù)庫(kù)的存儲(chǔ)極限。這里的分片指的是一個(gè)集群或一個(gè)數(shù)據(jù)庫(kù)節(jié)點(diǎn)

以下是對(duì)常見(jiàn)的中間件進(jìn)行的一個(gè)比較:

名稱是否開源免費(fèi)負(fù)載能力開發(fā)語(yǔ)言功能文檔普及率
MyCat 開源免費(fèi) 基于阿里巴巴的Corba中間件重構(gòu)而來(lái),有高訪問(wèn)量的檢驗(yàn) Java 功能全面,有豐富的分片算法以及讀寫分離、全局主鍵和分布式事務(wù)等功能 文檔豐富,不僅有官方的《Mycat權(quán)威指南》,還有許多社區(qū)貢獻(xiàn)的文檔 電信、電商領(lǐng)域均有應(yīng)用,是國(guó)內(nèi)普及率最高的MySQL中間件
Atlas 開源免費(fèi) 基于MySQL Proxy,主要用于360產(chǎn)品,有每天承載幾十億次請(qǐng)求的訪問(wèn)量檢驗(yàn) C語(yǔ)言 功能有限,實(shí)現(xiàn)了讀寫分離,具有少量的數(shù)據(jù)切分算法,不支持全局主鍵和分布式事務(wù) 文檔較少,只有開源項(xiàng)目文檔,無(wú)技術(shù)社區(qū)和出版物 普及率低,除了奇虎360外,僅在一些中小型項(xiàng)目在使用,可供參考的案例不多
OneProxy 分為免費(fèi)版和企業(yè)版 基于C語(yǔ)言的內(nèi)核,性能較好 C語(yǔ)言 功能有限,實(shí)現(xiàn)了讀寫分離,具有少量的數(shù)據(jù)切分算法,不支持全局主鍵和分布式事務(wù) 文檔較少,官網(wǎng)不提供使用文檔,無(wú)技術(shù)社區(qū)和出版物 普及率低,僅僅在一些中小型企業(yè)的內(nèi)部系統(tǒng)中使用過(guò)
ProxySQL 開源免費(fèi) 性能出眾,Percona推薦 C++ 功能相對(duì)豐富,支持讀寫分離、數(shù)據(jù)切分、故障轉(zhuǎn)移及查詢緩存等 文檔豐富,有官方文檔和技術(shù)社區(qū) 普及率相比于Mycat要低,但已有許多公司嘗試使用

配置Mycat數(shù)據(jù)切分

經(jīng)過(guò)上一小節(jié)的介紹與比較,可以看出MyCat與ProxySQL是比較理想的數(shù)據(jù)庫(kù)中間件。由于MyCat相對(duì)于ProxySQL功能更全面,普及率也更高一些,所以這里采用Mycat來(lái)做為PXC集群的中間件。關(guān)于Mycat的介紹與安裝,可以參考我的另一篇Mycat 快速入門,這里就不再重復(fù)了。

本小節(jié)主要介紹如何配置Mycat的數(shù)據(jù)切分功能,讓Mycat作為前端的數(shù)據(jù)切分中間件轉(zhuǎn)發(fā)SQL請(qǐng)求到后端的PXC集群分片中。因此,這里我搭建了兩個(gè)PXC集群,每個(gè)集群就是一個(gè)分片,以及搭建了兩個(gè)Mycat節(jié)點(diǎn)和兩個(gè)Haproxy節(jié)點(diǎn)用于后面組建雙機(jī)熱備。如圖:
為PXC集群引入Mycat并構(gòu)建完整的高可用集群架構(gòu)

各個(gè)節(jié)點(diǎn)的信息如下表:

角色HostIP
Haproxy-Master Haproxy-Master 192.168.190.140
Haproxy-Backup Haproxy-Backup 192.168.190.141
Mycat:Node1 mycat-01 192.168.190.136
Mycat:Node2 mycat-02 192.168.190.135
PXC分片-1:Node1 PXC-Node1 192.168.190.132
PXC分片-1:Node2 PXC-Node2 192.168.190.133
PXC分片-1:Node3 PXC-Node3 192.168.190.134
PXC分片-2:Node1 PXC-Node1 192.168.190.137
PXC分片-2:Node2 PXC-Node2 192.168.190.138
PXC分片-2:Node3 PXC-Node3 192.168.190.139

在每個(gè)分片里創(chuàng)建一個(gè)test庫(kù),并在該庫(kù)中創(chuàng)建一張t_user表用作測(cè)試,具體的建表SQL如下:

CREATE TABLE `t_user` (
  `id` int(11) NOT NULL,
  `username` varchar(20) NOT NULL,
  `password` char(36) NOT NULL,
  `tel` char(11) NOT NULL,
  `locked` char(10) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `idx_username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

完成以上準(zhǔn)備后,接著我們開始配置Mycat,如果你對(duì)Mycat的配置文件不了解的話,可以參考我另一篇文章:Mycat 核心配置詳解,本文就不贅述了。

1、編輯server.xml文件,配置Mycat的訪問(wèn)用戶:

<user name="admin" defaultAccount="true">
        <property name="password">Abc_123456</property>
        <property name="schemas">test</property>
        <property name="defaultSchema">test</property>
</user>

2、編輯schema.xml文件,配置Mycat的邏輯庫(kù)、邏輯表以及集群節(jié)點(diǎn)的連接信息:

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
    <!-- 配置邏輯庫(kù) -->
    <schema name="test" checkSQLschema="true" sqlMaxLimit="100" randomDataNode="dn1">
        <!-- 配置邏輯表 -->
        <table name="t_user" dataNode="dn1,dn2" rule="mod-long"/>
    </schema>

    <!-- 配置數(shù)據(jù)分片,每個(gè)分片都會(huì)有一個(gè)索引值,從0開始。例如,dn1索引值為0,dn2的索引值為1,以此類推 -->
    <!-- 分片的索引與分片算法有關(guān),分片算法計(jì)算得出的值就是分片索引 -->
    <dataNode name="dn1" dataHost="pxc-cluster1" database="test" />
    <dataNode name="dn2" dataHost="pxc-cluster2" database="test" />

    <!-- 配置集群節(jié)點(diǎn)的連接信息 -->
    <dataHost name="pxc-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.190.132:3306" user="admin"
            password="Abc_123456">
            <readHost host="W1-R1" url="192.168.190.133:3306" user="admin" password="Abc_123456"/>
            <readHost host="W1-R2" url="192.168.190.134:3306" user="admin" password="Abc_123456"/>
        </writeHost>
        <writeHost host="W2" url="192.168.190.133:3306" user="admin"
                                    password="Abc_123456">
            <readHost host="W2-R1" url="192.168.190.132:3306" user="admin" password="Abc_123456"/>
                        <readHost host="W2-R2" url="192.168.190.134:3306" user="admin" password="Abc_123456"/>
                </writeHost>
    </dataHost>
    <dataHost name="pxc-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.190.137:3306" user="admin" password="Abc_123456"> 
                <readHost host="W1-R1" url="192.168.190.138:3306" user="admin" password="Abc_123456"/>  
            <readHost host="W1-R2" url="192.168.190.139:3306" user="admin" password="Abc_123456"/> 
        </writeHost>  
            <writeHost host="W2" url="192.168.190.138:3306" user="admin" password="Abc_123456"> 
                <readHost host="W2-R1" url="192.168.190.137:3306" user="admin" password="Abc_123456"/>  
                <readHost host="W2-R2" url="192.168.190.138:3306" user="admin" password="Abc_123456"/> 
                </writeHost> 
     </dataHost>
</mycat:schema>

3、編輯rule.xml文件,修改mod-long分片算法的求?;鶖?shù),由于只有兩個(gè)集群作為分片,所以這里需要將基數(shù)改為2

<tableRule name="mod-long">
        <rule>
                <columns>id</columns>
                <algorithm>mod-long</algorithm>
        </rule>
</tableRule>
<function name="mod-long" class="io.mycat.route.function.PartitionByMod">
        <!-- how many data nodes -->
        <property name="count">2</property>
</function>
  • Tips:該分片算法使用表中id列的值對(duì)求?;鶖?shù)進(jìn)行求模以得出數(shù)據(jù)分片的索引

完成以上三個(gè)文件的配置后,啟動(dòng)Mycat:

[root@mycat-01 ~]# mycat start
Starting Mycat-server...
[root@mycat-01 ~]# more /usr/local/mycat/logs/wrapper.log |grep successfully
# 日志輸出了 successfully 代表啟動(dòng)成功
INFO   | jvm 1    | 2020/01/19 15:09:02 | MyCAT Server startup successfully. see logs in logs/mycat.log

測(cè)試

啟動(dòng)完成后,進(jìn)入Mycat中執(zhí)行一條insert語(yǔ)句,測(cè)試下是否能將該SQL轉(zhuǎn)發(fā)到正確的集群分片上。具體步驟如下:

[root@mycat-01 ~]# mysql -uadmin -P8066 -h227.0.0.1 -p
mysql> use test;
mysql> insert into t_user(id, username, password, tel, locked)
    -> values(1, 'Jack', hex(AES_ENCRYPT('123456', 'Test')), '13333333333', 'N');

上面這條insert語(yǔ)句插入的是一條id1的記錄,而我們采用的是對(duì)id列求模的分片算法,配置的求?;鶖?shù)為2。因此,根據(jù)id的值和求?;鶖?shù)進(jìn)行求模計(jì)算的結(jié)果為:1 % 2 = 1。得出來(lái)的1就是分片的索引,所以正常情況下Mycat會(huì)將該insert語(yǔ)句轉(zhuǎn)發(fā)到分片索引為1的集群上。

根據(jù)schema.xml文件中的配置,索引為1的分片對(duì)應(yīng)的集群是pxc-cluster2,即第二個(gè)PXC集群分片。接下來(lái),我們可以通過(guò)對(duì)比這兩個(gè)集群中的數(shù)據(jù),以驗(yàn)證Mycat是否按照預(yù)期正確地轉(zhuǎn)發(fā)了該SQL。

從下圖中可以看到,Mycat正確地將該insert語(yǔ)句轉(zhuǎn)發(fā)到了第二個(gè)分片上,此時(shí)第一個(gè)分片是沒(méi)有數(shù)據(jù)的:
為PXC集群引入Mycat并構(gòu)建完整的高可用集群架構(gòu)

接著我們?cè)贉y(cè)試當(dāng)id2時(shí),Mycat是否能將該SQL轉(zhuǎn)發(fā)到第一個(gè)分片上。具體的SQL如下:

insert into t_user(id, username, password, tel, locked)
values(2, 'Jon', hex(AES_ENCRYPT('123456', 'Test')), '18888888888', 'N');

測(cè)試結(jié)果如圖:
為PXC集群引入Mycat并構(gòu)建完整的高可用集群架構(gòu)

在完成以上的測(cè)試后,此時(shí)在Mycat上是能夠查詢出所有分片中的數(shù)據(jù)的:
為PXC集群引入Mycat并構(gòu)建完整的高可用集群架構(gòu)


常用的四類數(shù)據(jù)切分算法

主鍵求模切分

上一小節(jié)的示例中,使用的就是主鍵求模切分,其特點(diǎn)如下:

  • 主鍵求模切分適合用在初始數(shù)據(jù)很大,但是數(shù)據(jù)增長(zhǎng)不快的場(chǎng)景。例如,地圖產(chǎn)品、行政數(shù)據(jù)、企業(yè)數(shù)據(jù)等。
  • 主鍵求模切分的弊端在于擴(kuò)展新分片難度大,遷移的數(shù)據(jù)太多
  • 如果需要擴(kuò)展分片數(shù)量,建議擴(kuò)展后的分片數(shù)量是原有分片的2n倍。例如,原本是兩個(gè)分片,擴(kuò)展后是四個(gè)分片

主鍵范圍切分

  • 主鍵范圍切分適合用在數(shù)據(jù)快速增長(zhǎng)的場(chǎng)景
  • 容易增加分片,需要有明確的主鍵列

日期切分

  • 日期切分適合用在數(shù)據(jù)快速增長(zhǎng)的場(chǎng)景
  • 容易增加分片,需要有明確的日期列

枚舉值切分

  • 枚舉值切分適合用在歸類存儲(chǔ)數(shù)據(jù)的場(chǎng)景,適合大多數(shù)業(yè)務(wù)
  • 枚舉值切分按照某個(gè)字段的值(數(shù)字)與mapFile配置的映射關(guān)系來(lái)切分?jǐn)?shù)據(jù)
  • 枚舉值切分的弊端在于分片存儲(chǔ)的數(shù)據(jù)不夠均勻

在Mycat 核心配置詳解一文中,也介紹過(guò)枚舉值切分算法。該算法相對(duì)于其他算法來(lái)說(shuō)要用到一個(gè)額外的映射文件(mapFile),所以這里就針對(duì)該算法的使用進(jìn)行一個(gè)簡(jiǎn)單的演示。

需求:用戶表中有一個(gè)存儲(chǔ)用戶所在區(qū)號(hào)的列,要求將該列作為分片列,實(shí)現(xiàn)讓不同區(qū)號(hào)下的用戶數(shù)據(jù)被分別存儲(chǔ)到不同的分片中

1、首先,在Mycat的rule.xml文件中,增加如下配置:

<!-- 定義分片規(guī)則 -->
<tableRule name="sharding-by-areafile"> 
  <rule> 
    <!-- 定義使用哪個(gè)列作為分片列 -->
    <columns>area_id</columns>  
    <algorithm>area-int</algorithm> 
  </rule> 
</tableRule>

<!-- 定義分片算法 -->
<function name="area-int" class="io.mycat.route.function.PartitionByFileMap">
    <!-- 定義mapFile的文件名,位于conf目錄下 -->
    <property name="mapFile">area-hash-int.txt</property>
</function>

2、在conf目錄下創(chuàng)建area-hash-int.txt文件,定義區(qū)號(hào)與分片索引的對(duì)應(yīng)關(guān)系:

[root@mycat-01 /usr/local/mycat]# vim conf/area-hash-int.txt
020=0
0755=0
0757=0
0763=1
0768=1
0751=1

3、配置schema.xml,增加一個(gè)邏輯表,并將其分片規(guī)則設(shè)置為sharding-by-areafile

<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-by-areafile"/>
</schema>

4、進(jìn)入Mycat中執(zhí)行熱加載語(yǔ)句,該語(yǔ)句的作用可以使Mycat不用重啟就能應(yīng)用新的配置:

[root@mycat-01 ~]# mysql -uadmin -P9066 -h227.0.0.1 -p
mysql> reload @@config_all;
測(cè)試

完成以上配置后,我們來(lái)建個(gè)表測(cè)試一下,在所有的集群中創(chuàng)建t_customer表。具體的建表SQL如下:

create table t_customer(
    id int primary key,
    username varchar(20) not null,
    area_id int not null
);

進(jìn)入Mycat中插入一條area_id020的記錄:

[root@mycat-01 ~]# mysql -uadmin -P8066 -h227.0.0.1 -p
mysql> use test;
mysql> insert into t_customer(id, username, area_id)
    -> values(1, 'Jack', 020);

根據(jù)映射文件中的配置,area_id020的數(shù)據(jù)會(huì)被存儲(chǔ)到第一個(gè)分片中,如下圖:
為PXC集群引入Mycat并構(gòu)建完整的高可用集群架構(gòu)

  • Tips:這里由于area_idint類型的,所以前面的0會(huì)被去掉

然后再插入一條area_id0763的記錄:

insert into t_customer(id, username, area_id)
values(2, 'Tom', 0763);

根據(jù)映射文件中的配置,area_id0763的數(shù)據(jù)會(huì)被存儲(chǔ)到第二個(gè)分片中,如下圖:
為PXC集群引入Mycat并構(gòu)建完整的高可用集群架構(gòu)

完成以上測(cè)試后,此時(shí)在Mycat中應(yīng)能查詢到所有分片中的數(shù)據(jù):
為PXC集群引入Mycat并構(gòu)建完整的高可用集群架構(gòu)


父子表

當(dāng)有關(guān)聯(lián)的數(shù)據(jù)存儲(chǔ)在不同的分片時(shí),就會(huì)遇到表連接的問(wèn)題,在Mycat中是不允許跨分片做表連接查詢的。為了解決跨分片表連接的問(wèn)題,Mycat提出了父子表這種解決方案。

父子表規(guī)定父表可以有任意的切分算法,但與之關(guān)聯(lián)的子表不允許有切分算法,即子表的數(shù)據(jù)總是與父表的數(shù)據(jù)存儲(chǔ)在一個(gè)分片中。父表不管使用什么切分算法,子表總是跟隨著父表存儲(chǔ)。

例如,用戶表與訂單表是有關(guān)聯(lián)關(guān)系的,我們可以將用戶表作為父表,訂單表作為子表。當(dāng)A用戶被存儲(chǔ)至分片1中,那么A用戶產(chǎn)生的訂單數(shù)據(jù)也會(huì)跟隨著存儲(chǔ)在分片1中,這樣在查詢A用戶的訂單數(shù)據(jù)時(shí)就不需要跨分片了。如下圖所示:
為PXC集群引入Mycat并構(gòu)建完整的高可用集群架構(gòu)

實(shí)踐

了解了父子表的概念后,接下來(lái)我們看看如何在Mycat中配置父子表。首先,在schema.xml文件中配置父子表關(guān)系:

<schema name="test" checkSQLschema="true" sqlMaxLimit="100" randomDataNode="dn1">
        <table name="t_customer" dataNode="dn1,dn2" rule="sharding-by-areafile">
                <!-- 配置子表 -->
                <childTable name="t_orders" joinKey="customer_id" parentKey="id"/>
        </table>
</schema>

childTable標(biāo)簽說(shuō)明:

  • joinKey屬性:定義子表中用于關(guān)聯(lián)父表的列
  • parentKey屬性:定義父表中被關(guān)聯(lián)的列
  • childTable標(biāo)簽內(nèi)還可以繼續(xù)添加childTable標(biāo)簽

完成以上配置后,讓Mycat重新加載配置文件:

reload @@config_all;

測(cè)試

接著在所有分片中創(chuàng)建t_orders表,具體的建表SQL如下:

create table t_orders(
    id int primary key,
    customer_id int not null,
    create_time datetime default current_timestamp
);

現(xiàn)在分片中有兩個(gè)用戶,id1的用戶存儲(chǔ)在第一個(gè)分片,id2的用戶存儲(chǔ)在第二個(gè)分片。此時(shí),通過(guò)Mycat插入一條訂單記錄:

insert into t_orders(id, customer_id)
values(1, 1);

由于該訂單記錄關(guān)聯(lián)的是id1的用戶,根據(jù)父子表的規(guī)定,會(huì)被存儲(chǔ)至第一個(gè)分片中。如下圖:
為PXC集群引入Mycat并構(gòu)建完整的高可用集群架構(gòu)

同樣,如果訂單記錄關(guān)聯(lián)的是id2的用戶,那么就會(huì)被存儲(chǔ)至第二個(gè)分片中:

insert into t_orders(id, customer_id)
values(2, 2);

測(cè)試結(jié)果如下:
為PXC集群引入Mycat并構(gòu)建完整的高可用集群架構(gòu)

由于父子表的數(shù)據(jù)都是存儲(chǔ)在同一個(gè)分片,所以在Mycat上進(jìn)行關(guān)聯(lián)查詢也是沒(méi)有問(wèn)題的:
為PXC集群引入Mycat并構(gòu)建完整的高可用集群架構(gòu)


組建雙機(jī)熱備的高可用Mycat集群

前言

在以上小節(jié)的示例中,我們可以看到對(duì)后端數(shù)據(jù)庫(kù)集群的讀寫操作都是在Mycat上進(jìn)行的。Mycat作為一個(gè)負(fù)責(zé)接收客戶端請(qǐng)求,并將請(qǐng)求轉(zhuǎn)發(fā)到后端數(shù)據(jù)庫(kù)集群的中間件,不可避免的需要具備高可用性。否則,如果Mycat出現(xiàn)單點(diǎn)故障,那么整個(gè)數(shù)據(jù)庫(kù)集群也就無(wú)法使用了,這對(duì)整個(gè)系統(tǒng)的影響是十分巨大的。

所以本小節(jié)將演示如何去構(gòu)建一個(gè)高可用的Mycat集群,為了搭建Mycat高可用集群,除了要有兩個(gè)以上的Mycat節(jié)點(diǎn)外,還需要引入Haproxy和Keepalived組件。

其中Haproxy作為負(fù)載均衡組件,位于最前端接收客戶端的請(qǐng)求并將請(qǐng)求分發(fā)到各個(gè)Mycat節(jié)點(diǎn)上,用于保證Mycat的高可用。而Keepalived則用于實(shí)現(xiàn)雙機(jī)熱備,因?yàn)镠aproxy也需要高可用,當(dāng)一個(gè)Haproxy宕機(jī)時(shí),另一個(gè)備用的Haproxy能夠馬上接替。也就說(shuō)同一時(shí)間下只會(huì)有一個(gè)Haproxy在運(yùn)行,另一個(gè)Haproxy作為備用處于等待狀態(tài)。當(dāng)正在運(yùn)行中的Haproxy因意外宕機(jī)時(shí),Keepalived能夠馬上將備用的Haproxy切換到運(yùn)行狀態(tài)。

Keepalived是讓主機(jī)之間爭(zhēng)搶同一個(gè)虛擬IP(VIP)來(lái)實(shí)現(xiàn)高可用的,這些主機(jī)分為Master和Backup兩種角色,并且Master只有一個(gè),而Backup可以有多個(gè)。最開始Master先獲取到VIP處于運(yùn)行狀態(tài),當(dāng)Master宕機(jī)后,Backup檢測(cè)不到Master的情況下就會(huì)自動(dòng)獲取到這個(gè)VIP,此時(shí)發(fā)送到該VIP的請(qǐng)求就會(huì)被Backup接收到。這樣Backup就能無(wú)縫接替Master的工作,以實(shí)現(xiàn)高可用。

引入這些組件后,最終我們的集群架構(gòu)將演變成這樣子:
為PXC集群引入Mycat并構(gòu)建完整的高可用集群架構(gòu)

安裝Haproxy

Haproxy由于是老牌的負(fù)載均衡組件了,所以CentOS的yum倉(cāng)庫(kù)中自帶有該組件的安裝包,安裝起來(lái)就非常簡(jiǎn)單。安裝命令如下:

[root@Haproxy-Master ~]# yum install -y haproxy

配置Haproxy:

[root@Haproxy-Master ~]# vim /etc/haproxy/haproxy.cfg
# 在文件的末尾添加如下配置項(xiàng)
# 監(jiān)控界面配置
listen admin_stats
    # 綁定的ip及監(jiān)聽的端口
    bind 0.0.0.0:4001
    # 訪問(wèn)協(xié)議
    mode http
    # URI 相對(duì)地址
    stats uri /dbs
    # 統(tǒng)計(jì)報(bào)告格式
    stats realm Global\ statistics
    # 用于登錄監(jiān)控界面的賬戶密碼
    stats auth admin:abc123456

# 數(shù)據(jù)庫(kù)負(fù)載均衡配置
listen proxy-mysql
    # 綁定的ip及監(jiān)聽的端口
    bind 0.0.0.0:3306
    # 訪問(wèn)協(xié)議
    mode tcp
    # 負(fù)載均衡算法
    # roundrobin:輪詢
    # static-rr:權(quán)重
    # leastconn:最少連接
    # source:請(qǐng)求源ip
    balance roundrobin
    # 日志格式
    option tcplog
    # 需要被負(fù)載均衡的主機(jī)
    server mycat_01 192.168.190.136:8066 check port 8066 weight 1 maxconn 2000
    server mycat_02 192.168.190.135:8066 check port 8066 weight 1 maxconn 2000
    # 使用keepalive檢測(cè)死鏈
    option tcpka

由于配置了3306端口用于TCP轉(zhuǎn)發(fā),以及4001作為Haproxy監(jiān)控界面的訪問(wèn)端口,所以在防火墻上需要開放這兩個(gè)端口:

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

完成以上步驟后,啟動(dòng)Haproxy服務(wù):

[root@Haproxy-Master ~]# systemctl start haproxy

然后使用瀏覽器訪問(wèn)Haproxy的監(jiān)控界面,初次訪問(wèn)會(huì)要求輸入用戶名密碼,這里的用戶名密碼就是配置文件中所配置的:
為PXC集群引入Mycat并構(gòu)建完整的高可用集群架構(gòu)

登錄成功后,就會(huì)看到如下頁(yè)面:
為PXC集群引入Mycat并構(gòu)建完整的高可用集群架構(gòu)

Haproxy的監(jiān)控界面提供的監(jiān)控信息也比較全面,在該界面下,我們可以看到每個(gè)主機(jī)的連接信息及其自身狀態(tài)。當(dāng)主機(jī)無(wú)法連接時(shí),Status一欄會(huì)顯示DOWN,并且背景色也會(huì)變?yōu)榧t色。正常狀態(tài)下的值則為UP,背景色為綠色。

另一個(gè)Haproxy節(jié)點(diǎn)也是使用以上的步驟進(jìn)行安裝和配置,這里就不再重復(fù)了。


測(cè)試Haproxy

Haproxy服務(wù)搭建起來(lái)后,我們來(lái)使用遠(yuǎn)程工具測(cè)試一下能否通過(guò)Haproxy正常連接到Mycat。如下:
為PXC集群引入Mycat并構(gòu)建完整的高可用集群架構(gòu)

連接成功后,在Haproxy上執(zhí)行一些SQL語(yǔ)句,看看能否正常插入數(shù)據(jù)和查詢數(shù)據(jù):
為PXC集群引入Mycat并構(gòu)建完整的高可用集群架構(gòu)

我們搭建Haproxy是為了讓Mycat具備高可用的,所以最后測(cè)試一下Mycat是否已具備有高可用性,首先將一個(gè)Mycat節(jié)點(diǎn)給停掉:

[root@mycat-01 ~]# mycat stop
Stopping Mycat-server...
Stopped Mycat-server.
[root@mycat-01 ~]#

此時(shí),從Haproxy的監(jiān)控界面中,可以看到mycat_01這個(gè)節(jié)點(diǎn)已經(jīng)處于下線狀態(tài)了:
為PXC集群引入Mycat并構(gòu)建完整的高可用集群架構(gòu)

現(xiàn)在集群中還剩一個(gè)Mycat節(jié)點(diǎn),然后我們到Haproxy上執(zhí)行一些SQL語(yǔ)句,看看是否還能正常插入數(shù)據(jù)和查詢數(shù)據(jù):
為PXC集群引入Mycat并構(gòu)建完整的高可用集群架構(gòu)

從測(cè)試結(jié)果可以看到,插入和查詢語(yǔ)句依舊是能正常執(zhí)行的。也就是說(shuō)即便此時(shí)關(guān)掉一個(gè)Mycat節(jié)點(diǎn)整個(gè)數(shù)據(jù)庫(kù)集群還能夠正常使用,說(shuō)明現(xiàn)在Mycat集群是具有高可用性了。


利用Keepalived實(shí)現(xiàn)Haproxy的高可用

實(shí)現(xiàn)了Mycat集群的高可用之后,我們還得實(shí)現(xiàn)Haproxy的高可用,因?yàn)楝F(xiàn)在的架構(gòu)已經(jīng)從最開始的Mycat面向客戶端變?yōu)榱薍aproxy面向客戶端。

而同一時(shí)間只需要存在一個(gè)可用的Haproxy,否則客戶端就不知道該連哪個(gè)Haproxy了。這也是為什么要采用VIP的原因,這種機(jī)制能讓多個(gè)節(jié)點(diǎn)互相接替時(shí)依舊使用同一個(gè)IP,客戶端至始至終只需要連接這個(gè)VIP。所以實(shí)現(xiàn)Haproxy的高可用就要輪到Keepalived出場(chǎng)了,在安裝Keepalived之前需要開啟防火墻的VRRP協(xié)議:

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

然后就可以使用yum命令安裝Keepalived了,需要注意Keepalived是安裝在Haproxy節(jié)點(diǎn)上的:

[root@Haproxy-Master ~]# yum install -y keepalived

安裝完成后,編輯keepalived的配置文件:

[root@Haproxy-Master ~]# mv /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.bak  # 不使用自帶的配置文件
[root@Haproxy-Master ~]# vim /etc/keepalived/keepalived.conf
vrrp_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.100
   }
}

配置說(shuō)明:

  • state MASTER:定義節(jié)點(diǎn)角色為master,當(dāng)角色為master時(shí),該節(jié)點(diǎn)無(wú)需爭(zhēng)搶就能獲取到VIP。集群內(nèi)允許有多個(gè)master,當(dāng)存在多個(gè)master時(shí),master之間就需要爭(zhēng)搶VIP。為其他角色時(shí),只有master下線才能獲取到VIP
  • interface ens32:定義可用于外部通信的網(wǎng)卡名稱,網(wǎng)卡名稱可以通過(guò)ip addr命令查看
  • virtual_router_id 51:定義虛擬路由的id,取值在0-255,每個(gè)節(jié)點(diǎn)的值需要唯一,也就是不能配置成一樣的
  • priority 100:定義權(quán)重,權(quán)重越高就越優(yōu)先獲取到VIP
  • advert_int 1:定義檢測(cè)間隔時(shí)間為1秒
  • authentication:定義心跳檢查時(shí)所使用的認(rèn)證信息
    • auth_type PASS:定義認(rèn)證類型為密碼
    • auth_pass 123456:定義具體的密碼
  • virtual_ipaddress:定義虛擬IP(VIP),需要為同一網(wǎng)段下的IP,并且每個(gè)節(jié)點(diǎn)需要一致

完成以上配置后,啟動(dòng)keepalived服務(wù):

[root@Haproxy-Master ~]# systemctl start keepalived

當(dāng)keepalived服務(wù)啟動(dòng)成功,使用ip addr命令可以查看到網(wǎng)卡綁定的虛擬IP:
為PXC集群引入Mycat并構(gòu)建完整的高可用集群架構(gòu)

另一個(gè)節(jié)點(diǎn)也是使用以上的步驟進(jìn)行安裝和配置,這里就不再重復(fù)了。


測(cè)試Keepalived

以上我們完成了Keepalived的安裝與配置,最后我們來(lái)測(cè)試Keepalived服務(wù)是否正??捎?,以及測(cè)試Haproxy是否已具有高可用性。

首先,在其他節(jié)點(diǎn)上測(cè)試虛擬IP能否正常ping通,如果不能ping通就需要檢查配置了。如圖,我這里是能正常ping通的:
為PXC集群引入Mycat并構(gòu)建完整的高可用集群架構(gòu)

常見(jiàn)的虛擬IP ping不通的情況:

  • 防火墻配置有誤,沒(méi)有正確開啟VRRP協(xié)議
  • 配置的虛擬IP與其他節(jié)點(diǎn)的IP不處于同一網(wǎng)段
  • Keepalived配置有誤,或Keepalived根本沒(méi)啟動(dòng)成功

確認(rèn)能夠從外部ping通Keepalived的虛擬IP后,使用Navicat測(cè)試能否通過(guò)虛擬IP連接到Mycat:
為PXC集群引入Mycat并構(gòu)建完整的高可用集群架構(gòu)

連接成功后,執(zhí)行一些語(yǔ)句測(cè)試能否正常插入、查詢數(shù)據(jù):
為PXC集群引入Mycat并構(gòu)建完整的高可用集群架構(gòu)

到此就基本沒(méi)什么問(wèn)題了,最后測(cè)試一下Haproxy的高可用性,將其中一個(gè)Haproxy節(jié)點(diǎn)上的keepalived服務(wù)給關(guān)掉:

[root@Haproxy-Master ~]# systemctl stop keepalived

然后再次執(zhí)行執(zhí)行一些語(yǔ)句測(cè)試能否正常插入、查詢數(shù)據(jù),如下能正常執(zhí)行代表Haproxy節(jié)點(diǎn)已具有高可用性:
為PXC集群引入Mycat并構(gòu)建完整的高可用集群架構(gòu)

名稱欄目:為PXC集群引入Mycat并構(gòu)建完整的高可用集群架構(gòu)
鏈接URL:http://muchs.cn/article44/igedhe.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供自適應(yīng)網(wǎng)站、網(wǎng)站制作App設(shè)計(jì)、網(wǎng)站排名外貿(mào)網(wǎng)站建設(shè)、全網(wǎng)營(yíng)銷推廣

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站制作