服務(wù)器快過(guò)期了,清一點(diǎn)庫(kù)存,把運(yùn)維這塊的知識(shí)復(fù)習(xí)下
為什么要搭MySQL集群技術(shù)層面上,傳統(tǒng)的單節(jié)點(diǎn)數(shù)據(jù)庫(kù),萬(wàn)一宕機(jī)了,就涼涼了。容災(zāi)性能差、抗并發(fā)能力有限,數(shù)據(jù)量大的時(shí)候查詢有瓶頸。學(xué)習(xí)層面上,作為一個(gè)技術(shù)人了解一些技術(shù)相關(guān)的知識(shí)那也是無(wú)可厚非,愛(ài)折騰嘛。所以、本著“不把雞蛋放在一個(gè)籃子里”的思想,我們來(lái)一起探討學(xué)習(xí)下如何搭建MySQL集群。 MySQL集群的解決方案關(guān)于搭建MySQL集群解決方案的操作方面,這部分知識(shí)其實(shí)是很死板的,沒(méi)有特別多的含金量,真正有含金量的是挖掘其背后實(shí)現(xiàn)的原理和思路,并能夠曉之以情動(dòng)之以理地講出來(lái)。這里主要介紹兩種解決方案,我們抓牢它們的側(cè)重點(diǎn)總結(jié)下吧。 PXC強(qiáng)一致性 速度慢 只支持InnoDB存儲(chǔ)引擎同步 所有節(jié)點(diǎn)可讀寫(xiě) 同步機(jī)制為同步 存儲(chǔ)信息價(jià)值量高
Replication弱一致性 速度快 從節(jié)點(diǎn)不可寫(xiě)入 同步機(jī)制為異步 存儲(chǔ)信息價(jià)值量不高
這里我們主要講下PXC,當(dāng)你在一個(gè)節(jié)點(diǎn)進(jìn)行相關(guān)操作,比如說(shuō)插入一條數(shù)據(jù)、它會(huì)同步到其他節(jié)點(diǎn),若所有節(jié)點(diǎn)同步成功則插入成功、若所有節(jié)點(diǎn)同步失敗,則回滾并告知插入失敗,這個(gè)我們后面實(shí)踐一下就知道了。 創(chuàng)建MySQL集群的步驟(PXC)(一)、拉取鏡像并重命名
# 拉取鏡像 docker pull percona/percona-xtradb-cluster
# 重名名(這步也可以不做,我就是想后面少打點(diǎn)字) docker tag percona/percona-xtradb-cluster:latest pxc:latest
(二)、組網(wǎng)2.1、創(chuàng)建網(wǎng)絡(luò): 命令:docker network create mysql_net 演示:
? root@ataola ~ docker network create mysql_net 79885a1c3b8a783e096a1610df08e353641bda74d0b996b4200f2ea5db3c5dbd ? root@ataola ~
2.2、查看網(wǎng)絡(luò): 命令:docker network inspect mysql_net 演示:
? root@ataola ~ docker network inspect mysql_net [ { "Name": "mysql_net", "Id": "79885a1c3b8a783e096a1610df08e353641bda74d0b996b4200f2ea5db3c5dbd", "Created": "2020-05-30T21:26:53.852825919+08:00", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": {}, "Config": [ { "Subnet": "172.19.0.0/16", "Gateway": "172.19.0.1" } ] }, "Internal": false, "Attachable": false, "Containers": {}, "Options": {}, "Labels": {} } ] ? root@ataola ~
(三)、創(chuàng)建數(shù)據(jù)卷3.1、創(chuàng)建數(shù)據(jù)卷 命令:docker volume create mysql_v 演示: ? root@ataola ~ docker volume create mysql_v1 mysql_v1 ? root@ataola ~ docker volume create mysql_v2 mysql_v2 ? root@ataola ~ docker volume create mysql_v3 mysql_v3 ? root@ataola ~ docker volume create mysql_v4 mysql_v4 ? root@ataola ~ docker volume create mysql_v5 mysql_v5 ? root@ataola ~
3.2:查看數(shù)據(jù)卷 命令:docker volume inspect mysql_v 演示:
? ? root@ataola /home/caocao docker volume inspect mysql_v1 [ { "Driver": "local", "Labels": {}, "Mountpoint": "/var/lib/docker/volumes/mysql_v1/_data", "Name": "mysql_v1", "Options": {}, "Scope": "local" } ] ? root@ataola /home/caocao
(四)、創(chuàng)建MySQL節(jié)點(diǎn)4.1、主節(jié)點(diǎn): 命令:docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=studypxc -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=studymysql -v mysql_v1:/var/lib/mysql --privileged --name=mysql_node1 --net=mysql_net pxc 演示:
? root@ataola ~ docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=studypxc -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=studymysql -v mysql_v1:/var/lib/mysql --privileged --name=mysql_node1 --net=mysql_net pxc 09e7715f71b4411974d862a2aa74ed0b1018fc4efb4196707576f935e1425f6b ? root@ataola ~ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 09e7715f71b4 pxc "/entrypoint.sh my..." 8 seconds ago Up 6 seconds 0.0.0.0:3306->3306/tcp, 4567-4568/tcp mysql_node1 ? root@ataola ~
4.2、從節(jié)點(diǎn): 命令:docker run -d -p 3307:3306 -e MYSQL_ROOT_PASSWORD=studypxc -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=studymysql -e CLUSTER_JOIN=mysql_node1 -v mysql_v2:/var/lib/mysql --privileged --name=mysql_node2 --net=mysql_net pxc 更改相關(guān)參數(shù)重復(fù)三次樓上操作,我們構(gòu)建一個(gè)主節(jié)點(diǎn)外加四個(gè)從節(jié)點(diǎn)的mysql集群,這個(gè)時(shí)候我們執(zhí)行docker ps -a 看下,可以看到它們都跑起來(lái)了。
? root@ataola ~ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 8d809616ea08 pxc "/entrypoint.sh my..." 9 seconds ago Up 8 seconds 4567-4568/tcp, 0.0.0.0:3310->3306/tcp mysql_node5 6dc023253205 pxc "/entrypoint.sh my..." 18 seconds ago Up 17 seconds 4567-4568/tcp, 0.0.0.0:3309->3306/tcp mysql_node4 18c232855938 pxc "/entrypoint.sh my..." 53 seconds ago Up 52 seconds 4567-4568/tcp, 0.0.0.0:3308->3306/tcp mysql_node3 6de60216270a pxc "/entrypoint.sh my..." 2 minutes ago Up 2 minutes 4567-4568/tcp, 0.0.0.0:3307->3306/tcp mysql_node2 09e7715f71b4 pxc "/entrypoint.sh my..." 10 minutes ago Up 10 minutes 0.0.0.0:3306->3306/tcp, 4567-4568/tcp mysql_node1 ? root@ataola ~
然后我們可以通過(guò)docker network inspect mysql_net 查看我們剛才創(chuàng)建集群的網(wǎng)絡(luò)信息 ? root@ataola /home/caocao docker network inspect mysql_net [ { "Name": "mysql_net", "Id": "79885a1c3b8a783e096a1610df08e353641bda74d0b996b4200f2ea5db3c5dbd", "Created": "2020-05-30T21:26:53.852825919+08:00", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": {}, "Config": [ { "Subnet": "172.19.0.0/16", "Gateway": "172.19.0.1" } ] }, "Internal": false, "Attachable": false, "Containers": { "09e7715f71b4411974d862a2aa74ed0b1018fc4efb4196707576f935e1425f6b": { "Name": "mysql_node1", "EndpointID": "621bc0ec6e4adb78e72f0f78ca04d154029abe1f0bb91fc5ccd42156bfa32d52", "MacAddress": "02:42:ac:13:00:02", "IPv4Address": "172.19.0.2/16", "IPv6Address": "" }, "0e4ef69c19b981163067ec8af0c38b6fa84c380855c22309a884f0a0ed691912": { "Name": "haproxy1", "EndpointID": "02e8c179fdb7cbc4b3e7d72f8412129da487c65a3897e70e0da5693aa0d8d500", "MacAddress": "02:42:ac:13:00:07", "IPv4Address": "172.19.0.7/16", "IPv6Address": "" }, "18c232855938d7263b90a4ab88874676110c6197a601aa72d8bec8f52e73dd02": { "Name": "mysql_node3", "EndpointID": "010538caec3ab7aafe1c708ebebdffa43e268d68147cf4a60f86a77247b3ef86", "MacAddress": "02:42:ac:13:00:04", "IPv4Address": "172.19.0.4/16", "IPv6Address": "" }, "6dc0232532057a65db0607c92517307ee480bec32cb6311d6615555482670c7a": { "Name": "mysql_node4", "EndpointID": "cc59fe8fc8d7d02f367ec75b1897c51bf3731dbc5dc8d70510dde34aee6d4afa", "MacAddress": "02:42:ac:13:00:05", "IPv4Address": "172.19.0.5/16", "IPv6Address": "" }, "6de60216270a3b6f5bfbe5d94d40fa2449e443eb77b67d4bf005061dd4ff412e": { "Name": "mysql_node2", "EndpointID": "b674d25e3e6c999324de9704419b1c97f008ca6e5d27e825bc0fc61d600848ff", "MacAddress": "02:42:ac:13:00:03", "IPv4Address": "172.19.0.3/16", "IPv6Address": "" }, "8d809616ea08d46a3febb95259d9d0672d6112dd8cbe6c29f03f49cbc44ef444": { "Name": "mysql_node5", "EndpointID": "01f0988019206e959a7099736d9995cec1676aaec360db9bd78fa61b68a87f71", "MacAddress": "02:42:ac:13:00:06", "IPv4Address": "172.19.0.6/16", "IPv6Address": "" } }, "Options": {}, "Labels": {} } ] ? root@ataola /home/caocao
至此,基于PXC解決方案MySQL集群搭建已經(jīng)完成了,當(dāng)然這里涉及到的一些命令和參數(shù)具體的還是要讀者去看樓下參考文獻(xiàn)的官方文檔的。 負(fù)載均衡(haproxy)在樓上的例子中,我們創(chuàng)建了一個(gè)MySQL集群,我們可以把它理解成一家超市。然后每個(gè)節(jié)點(diǎn)就是收銀臺(tái)。這個(gè)時(shí)候就會(huì)有個(gè)問(wèn)題了,假設(shè)那批去超市購(gòu)物的人不太正常了,買(mǎi)完?yáng)|西都擠到1號(hào)收銀臺(tái),那么1號(hào)收銀臺(tái)的收銀員她承受的壓力就會(huì)比較大,就會(huì)很焦慮。這個(gè)時(shí)候呢,超市經(jīng)理拿這個(gè)大喇叭過(guò)來(lái)啊,你你你,去2號(hào)收銀臺(tái)、你們?nèi)?號(hào)收銀臺(tái),購(gòu)物的人很快地就付完錢(qián)回家了。haproxy就相當(dāng)于這個(gè)超市經(jīng)理,哪里有空閑就調(diào)度往哪個(gè)節(jié)點(diǎn)去。 在理解完haproxy做的事情后,我們來(lái)實(shí)踐一番吧。 (一)、拉取鏡像這里我就不改名了,有興趣的童鞋自己對(duì)照pxc改個(gè)名字。
(二)、創(chuàng)建haproxy配置文件這里其他的配置都不用動(dòng),就后面server改成你電腦的配置
# haproxy.cfg global #工作目錄 chroot /usr/local/etc/haproxy #日志文件,使用rsyslog服務(wù)中l(wèi)ocal5日志設(shè)備(/var/log/local5),等級(jí)info log 127.0.0.1 local5 info #守護(hù)進(jìn)程運(yùn)行 daemon
defaults log global mode http #日志格式 option httplog #日志中不記錄負(fù)載均衡的心跳檢測(cè)記錄 option dontlognull #連接超時(shí)(毫秒) timeout connect 5000 #客戶端超時(shí)(毫秒) timeout client 50000 #服務(wù)器超時(shí)(毫秒) timeout server 50000
#監(jiān)控界面 listen admin_stats #監(jiān)控界面的訪問(wèn)的IP和端口 bind 0.0.0.0:8888 #訪問(wèn)協(xié)議 mode http #URI相對(duì)地址 stats uri /dbs #統(tǒng)計(jì)報(bào)告格式 stats realm Global\ statistics #登陸帳戶信息 stats auth admin:abc123456 #數(shù)據(jù)庫(kù)負(fù)載均衡 listen proxy-mysql #訪問(wèn)的IP和端口 bind 0.0.0.0:3306 #網(wǎng)絡(luò)協(xié)議 mode tcp #負(fù)載均衡算法(輪詢算法) #輪詢算法:roundrobin #權(quán)重算法:static-rr #最少連接算法:leastconn #請(qǐng)求源IP算法:source balance roundrobin #日志格式 option tcplog #在MySQL中創(chuàng)建一個(gè)沒(méi)有權(quán)限的haproxy用戶,密碼為空。Haproxy使用這個(gè)賬戶對(duì)MySQL數(shù)據(jù)庫(kù)心跳檢測(cè) option mysql-check user haproxy server MySQL_1 172.18.0.2:3306 check weight 1 maxconn 2000 server MySQL_2 172.18.0.3:3306 check weight 1 maxconn 2000 server MySQL_3 172.18.0.4:3306 check weight 1 maxconn 2000 server MySQL_4 172.18.0.5:3306 check weight 1 maxconn 2000 server MySQL_5 172.18.0.6:3306 check weight 1 maxconn 2000 #使用keepalive檢測(cè)死鏈 option tcpka
(三)、創(chuàng)建haproxy容器命令:docker run -it -d -p 4001:8888 -p 4002:3306 -v /root/haproxy:/usr/local/etc/haproxy --name haproxy1 --privileged --net=mysql_net haproxy 這里把監(jiān)控界面的8888端口映射到宿主機(jī)的4001,然后把數(shù)據(jù)庫(kù)負(fù)載均衡的3306端口映射到宿主機(jī)的4002 演示:
? root@ataola ~/haproxy docker run -it -d -p 4001:8888 -p 4002:3306 -v /root/haproxy:/usr/local/etc/haproxy --name haproxy1 --privileged --net=mysql_net haproxy 0e4ef69c19b981163067ec8af0c38b6fa84c380855c22309a884f0a0ed691912 ? root@ataola ~/haproxy
之后我們進(jìn)入到這個(gè)起起來(lái)的容器docker exec -it haproxy1 bash 執(zhí)行配置命令:haproxy -f /usr/local/etc/haproxy/haproxy.cfg (四)、創(chuàng)建haproxy數(shù)據(jù)庫(kù)賬號(hào)打開(kāi)MySQL數(shù)據(jù)庫(kù),創(chuàng)建一個(gè)用戶CREATE USER 'haproxy'@'%' IDENTIFIED BY 'superman'; 訪問(wèn)http://localhost:4001/dbs ,就可以看到數(shù)據(jù)集群的情況。 看到這里就說(shuō)明你的haproxy搭建成功了,接下來(lái)我們進(jìn)行相關(guān)的實(shí)踐。
相關(guān)實(shí)驗(yàn)實(shí)驗(yàn)須知這里我們?cè)趧?chuàng)建了一個(gè)test數(shù)據(jù)庫(kù),在數(shù)據(jù)庫(kù)中創(chuàng)建一張數(shù)據(jù)表為user,并添加相應(yīng)的字段和數(shù)據(jù),具體的如下: 實(shí)驗(yàn)一:在主節(jié)點(diǎn)和從節(jié)點(diǎn)都完好的情況下,分別向主節(jié)點(diǎn)和從節(jié)點(diǎn)插入數(shù)據(jù),看看其他節(jié)點(diǎn)的變化。
主節(jié)點(diǎn)插入: 我們嘗試在主節(jié)點(diǎn)mysql_node1插入數(shù)據(jù),然后去mysql_node_2去讀取數(shù)據(jù),這里我們就直接硬核的手動(dòng)擋來(lái)吧(PS:初次加載時(shí)間長(zhǎng),如下圖) 可以看到我們從mysql_node2節(jié)點(diǎn)讀取到了mysql_node1主節(jié)點(diǎn)寫(xiě)入的內(nèi)容。
從節(jié)點(diǎn)插入: 把樓上的例子反過(guò)來(lái),這次我們從節(jié)點(diǎn)插入,主節(jié)點(diǎn)讀取看看。 從這個(gè)實(shí)驗(yàn),我們可以印證一點(diǎn)的是,主從節(jié)點(diǎn)都是可以讀寫(xiě)的。
實(shí)驗(yàn)二:掛掉主節(jié)點(diǎn),從節(jié)點(diǎn)看能不能插入接下來(lái)我們就要開(kāi)始搞事情了,把主節(jié)點(diǎn)停掉,再?gòu)墓?jié)點(diǎn)插入數(shù)據(jù)看看。 命令:docker pause mysql_node1 演示: 這個(gè)時(shí)候主節(jié)點(diǎn)是打不開(kāi)的,相當(dāng)于宕機(jī)了。
我們嘗試著在從節(jié)點(diǎn)插入數(shù)據(jù),發(fā)現(xiàn)從節(jié)點(diǎn)也是打不開(kāi)的 這印證了上面說(shuō)的強(qiáng)一致性,同步機(jī)制為同步, 當(dāng)主節(jié)點(diǎn)掛了以后,其余節(jié)點(diǎn)不可讀寫(xiě)。 實(shí)驗(yàn)三:掛掉某個(gè)從節(jié)點(diǎn),看看主從節(jié)點(diǎn)能否插入我們把node3和node4服務(wù)給停掉,接著我們嘗試著打開(kāi)node1去插入一條張東升試試 可以看到在主節(jié)點(diǎn)插入數(shù)據(jù),從節(jié)點(diǎn)也能夠同步。 接著我們?cè)趎ode2從節(jié)點(diǎn)插入張朝陽(yáng) 可以看到從節(jié)點(diǎn)插入成功,也同步到了主節(jié)點(diǎn)。
這個(gè)時(shí)候,我們把node3和node4起起來(lái),看下數(shù)據(jù)會(huì)不會(huì)進(jìn)行一個(gè)同步 可以看到,當(dāng)node3和node4恢復(fù)的時(shí)候,便會(huì)進(jìn)行一個(gè)數(shù)據(jù)同步,我們便在node3和node4中看到了張東升和張朝陽(yáng)。
參考文獻(xiàn)percona介紹:https://hub./_/percona percona安裝:https://www./doc/percona-server/8.0/installation/docker.html Docker環(huán)境下的前后端分離項(xiàng)目部署與運(yùn)維:https://coding.imooc.com/class/219.html 最后寫(xiě)到這里,筆者也只是記流水賬一樣,記錄了當(dāng)時(shí)的操作過(guò)程并加以復(fù)現(xiàn),并沒(méi)有對(duì)集群關(guān)于性能熱備份冷備份等等方面進(jìn)行深入探討學(xué)習(xí),這里僅作拋磚引玉,有興趣的童鞋接力實(shí)踐吧!
|