1. 擴(kuò)容方案剖析
1.1 擴(kuò)容問(wèn)題
在項(xiàng)目初期,我們部署了三個(gè)數(shù)據(jù)庫(kù) A、B、C,此時(shí)數(shù)據(jù)庫(kù)的規(guī)??梢詽M足我們的業(yè)務(wù)需求。為了將數(shù)據(jù)做到平均分配,我們?cè)?Service 服務(wù)層使用 uid%3 進(jìn)行取模分片,從而將數(shù)據(jù)平均分配到三個(gè)數(shù)據(jù)庫(kù)中。
如圖所示:
后期隨著用戶量的增加,用戶產(chǎn)生的數(shù)據(jù)信息被源源不斷的添加到數(shù)據(jù)庫(kù)中,最終達(dá)到數(shù)據(jù)庫(kù)的最佳存儲(chǔ)容量。如果此時(shí)繼續(xù)向數(shù)據(jù)庫(kù)中新增數(shù)據(jù),會(huì)導(dǎo)致數(shù)據(jù)庫(kù)的 CRUD 等基本操作變慢,進(jìn)而影響整個(gè)服務(wù)的響應(yīng)速度。
這時(shí),我們需要增加新的節(jié)點(diǎn),對(duì)數(shù)據(jù)庫(kù)進(jìn)行水平擴(kuò)容,那么加入新的數(shù)據(jù)庫(kù) D 后,數(shù)據(jù)庫(kù)的規(guī)模由原來(lái)的 3 個(gè)變?yōu)?4 個(gè)。
如圖所示:
此時(shí)由于分片規(guī)則發(fā)生了變化(uid%3 變?yōu)?uid%4),導(dǎo)致大部分的數(shù)據(jù),無(wú)法命中原有的數(shù)據(jù),需要重新進(jìn)行分配,要做大量的數(shù)據(jù)遷移處理。
比如之前 uid 如果是 uid=3 取模 3%3=0, 是分配在 A 庫(kù)上,新加入 D 庫(kù)后, uid=3 取模 3%4=3,分配在 D 庫(kù)上;
新增一個(gè)節(jié)點(diǎn), 大概會(huì)有 90% 的數(shù)據(jù)需要遷移, 這樣會(huì)面臨大量的數(shù)據(jù)壓力,并且對(duì)服務(wù)造成極大的不穩(wěn)定性。
1.2 停機(jī)方案
發(fā)布公告
為了進(jìn)行數(shù)據(jù)的重新拆分,在停止服務(wù)之前,我們需要提前通知用戶,比如:我們的服務(wù)會(huì)在 yyyy-MM-dd 進(jìn)行升級(jí),給您帶來(lái)的不便敬請(qǐng)諒解。
停止服務(wù)
關(guān)閉 Service
離線數(shù)據(jù)遷移(拆分,重新分配數(shù)據(jù))
將舊庫(kù)中的數(shù)據(jù)按照 Service 層的算法,將數(shù)據(jù)拆分,重新分配數(shù)據(jù)
數(shù)據(jù)校驗(yàn)
開(kāi)發(fā)定制一個(gè)程序?qū)εf庫(kù)和新庫(kù)中的數(shù)據(jù)進(jìn)行校驗(yàn),比對(duì)
更改配置
修改 Service 層的配置算法,也就是將原來(lái)的 uid%3 變?yōu)?uid%4
恢復(fù)服務(wù)
重啟 Service 服務(wù)
回滾預(yù)案
針對(duì)上述的每個(gè)步驟都要有數(shù)據(jù)回滾預(yù)案,一旦某個(gè)環(huán)節(jié)(如:數(shù)據(jù)遷移,恢復(fù)服務(wù)等)執(zhí)行失敗,立刻進(jìn)行回滾,重新再來(lái)
停止服務(wù)之后, 能夠保證遷移工作的正常進(jìn)行, 但是服務(wù)停止,傷害用戶體驗(yàn), 并造成了時(shí)間壓力, 必須在指定的時(shí)間內(nèi)完成遷移。
1.3 停寫(xiě)方案
支持讀寫(xiě)分離
數(shù)據(jù)庫(kù)支持讀寫(xiě)分離,在擴(kuò)容之前,每個(gè)數(shù)據(jù)庫(kù)都提供了讀寫(xiě)功能,數(shù)據(jù)重新分配的過(guò)程中,將每個(gè)數(shù)據(jù)庫(kù)設(shè)置為只讀狀態(tài),關(guān)閉寫(xiě)的功能
升級(jí)公告
為了進(jìn)行數(shù)據(jù)的重新拆分,在停寫(xiě)之前,我們需要提前通知用戶,比如:我們的服務(wù)會(huì)在 yyyy-MM-dd 進(jìn)行升級(jí),給您帶來(lái)的不便敬請(qǐng)諒解。
中斷寫(xiě)操作,隔離寫(xiě)數(shù)據(jù)源(或攔截返回統(tǒng)一提示)
在 Service 層對(duì)所有的寫(xiě)請(qǐng)求進(jìn)行攔截,統(tǒng)一返回提示信息,如:服務(wù)正在升級(jí)中,只對(duì)外提供讀服務(wù)
數(shù)據(jù)同步處理
將舊庫(kù)中的數(shù)據(jù)按照 Service 層的算法,將數(shù)據(jù)重新分配,遷移(復(fù)制數(shù)據(jù))
數(shù)據(jù)校驗(yàn)
開(kāi)發(fā)定制一個(gè)程序?qū)εf庫(kù)中的數(shù)據(jù)進(jìn)行備份,使用備份的數(shù)據(jù)和重新分配后的數(shù)據(jù)進(jìn)行校驗(yàn),比對(duì)
更改配置
通過(guò)配置中心,修改 Service 層的配置算法,也就是將原來(lái)的 uid%3 變?yōu)?uid%4,這個(gè)過(guò)程不需要重啟服務(wù)
恢復(fù)寫(xiě)操作
設(shè)置數(shù)據(jù)庫(kù)恢復(fù)讀寫(xiě)功能,去除 Service 層的攔截提示
數(shù)據(jù)清理
使用 delete 語(yǔ)句對(duì)冗余數(shù)據(jù)進(jìn)行刪除
回滾預(yù)案
針對(duì)上述的每個(gè)步驟都要有數(shù)據(jù)回滾預(yù)案,一旦某個(gè)環(huán)節(jié)(如:數(shù)據(jù)遷移等)執(zhí)行失敗,立刻進(jìn)行回滾,重新再來(lái)
缺點(diǎn):在數(shù)據(jù)的復(fù)制過(guò)程需要消耗大量的時(shí)間,停寫(xiě)時(shí)間太長(zhǎng),數(shù)據(jù)需要先復(fù)制,再清理冗余數(shù)據(jù)
1.4 日志方案
核心是通過(guò)日志進(jìn)行數(shù)據(jù)庫(kù)的同步遷移, 主要操作步驟如下:
數(shù)據(jù)遷移之前, 業(yè)務(wù)應(yīng)用訪問(wèn)舊的數(shù)據(jù)庫(kù)節(jié)點(diǎn)。
日志記錄
在升級(jí)之前, 記錄 “對(duì)舊數(shù)據(jù)庫(kù)上的數(shù)據(jù)修改” 的日志(這里修改包括增、刪、改),這個(gè)日志不需要記錄詳細(xì)的數(shù)據(jù)信息,主要記錄:
(1)修改的庫(kù);
(2)修改的表;
(3)修改的唯一主鍵;
(4)修改操作類(lèi)型。
日志記錄不用關(guān)注新增了哪些信息,修改的數(shù)據(jù)格式,只需要記錄以上數(shù)據(jù)信息,這樣日志格式是固定的, 這樣能保證方案的通用性。
服務(wù)升級(jí)日志記錄功能風(fēng)險(xiǎn)較?。?/p>
寫(xiě)和修改接口是少數(shù), 改動(dòng)點(diǎn)少;
升級(jí)只是增加了一些日志,采用異步方式實(shí)現(xiàn), 對(duì)業(yè)務(wù)功能沒(méi)有太多影響。
數(shù)據(jù)遷移:
研發(fā)定制數(shù)據(jù)遷移工具, 作用是把舊庫(kù)中的數(shù)據(jù)遷移至新庫(kù)中。
整個(gè)過(guò)程仍然采用舊庫(kù)進(jìn)行對(duì)外服務(wù)。
數(shù)據(jù)同步工具實(shí)現(xiàn)復(fù)雜度不高。
只對(duì)舊庫(kù)進(jìn)行讀取操作, 如果同步出現(xiàn)問(wèn)題, 都可以對(duì)新庫(kù)進(jìn)行回滾操作。
可以限速或分批遷移執(zhí)行, 不會(huì)有時(shí)間壓力。
數(shù)據(jù)遷移完成之后, 并不能切換至新庫(kù)提供服務(wù)。
因?yàn)榕f庫(kù)依然對(duì)線上提供服務(wù), 庫(kù)中的數(shù)據(jù)隨時(shí)會(huì)發(fā)生變化, 但這些變化的數(shù)據(jù)并沒(méi)有同步到新庫(kù)中, 舊庫(kù)和新庫(kù)數(shù)據(jù)不一致, 所以不能直接進(jìn)行切換, 需要將數(shù)據(jù)同步完整。
日志增量遷移
研發(fā)一個(gè)日志遷移工具,把上面遷移數(shù)據(jù)過(guò)程中的差異數(shù)據(jù)追平,處理步驟:
讀取 log 日志,獲取具體是哪個(gè)庫(kù)、表和主鍵發(fā)生了變化修改;
把舊庫(kù)中的主鍵記錄讀取出來(lái)
根據(jù)主鍵 ID,把新庫(kù)中的記錄替換掉
這樣可以最大程度的保障數(shù)據(jù)的一致性。風(fēng)險(xiǎn)分析:
整個(gè)過(guò)程, 仍然是舊庫(kù)對(duì)線上提供服務(wù);
日志遷移工具實(shí)現(xiàn)的復(fù)雜度較低;
任何時(shí)間發(fā)現(xiàn)問(wèn)題, 可以重新再來(lái),有充分的容錯(cuò)空間;
可以限速重放處理日志, 處理過(guò)程不會(huì)因?yàn)閷?duì)線上影響造成時(shí)間壓力。
但是, 日志增量同步完成之后, 還不能切換到新的數(shù)據(jù)庫(kù)。
因?yàn)槿罩驹隽客竭^(guò)程中,舊庫(kù)中可能有數(shù)據(jù)發(fā)生變化, 導(dǎo)致數(shù)據(jù)不一致,所以需要進(jìn)一步讀取日志, 追平數(shù)據(jù)記錄;日志增量同步過(guò)程隨時(shí)可能會(huì)產(chǎn)生新的數(shù)據(jù), 新庫(kù)與舊庫(kù)的數(shù)據(jù)追平也會(huì)是一個(gè)無(wú)限逼近的過(guò)程。
數(shù)據(jù)校驗(yàn)
準(zhǔn)備好數(shù)據(jù)校驗(yàn)工具,將舊庫(kù)和新庫(kù)中的數(shù)據(jù)進(jìn)行比對(duì),直到數(shù)據(jù)完全一致。
切換新庫(kù)
數(shù)據(jù)比對(duì)完成之后, 將流量轉(zhuǎn)移切換至新庫(kù), 至此新庫(kù)提供服務(wù), 完成遷移。
但是在極限情況下, 即便通過(guò)上面的數(shù)據(jù)校驗(yàn)處理, 也有可能出現(xiàn) 99.99% 數(shù)據(jù)一致, 不能保障完全一致,這個(gè)時(shí)候可以在舊庫(kù)做一個(gè) readonly 只讀功能, 或者將流量屏蔽降級(jí),等待日志增量同步工具完全追平后, 再進(jìn)行新庫(kù)的切換。
至此,完成日志方案的遷移擴(kuò)容處理, 整個(gè)過(guò)程能夠持續(xù)對(duì)線上提供服務(wù), 只會(huì)短暫的影響服務(wù)的可用性。
這種方案的弊端,是操作繁瑣,需要適配多個(gè)同步處理工具,成本較高, 需要制定個(gè)性化業(yè)務(wù)的同步處理, 不具備普遍性,耗費(fèi)的時(shí)間周期也較長(zhǎng)。
1.5 雙寫(xiě)方案(中小型數(shù)據(jù))
雙寫(xiě)方案可通過(guò) canal 或 mq 做實(shí)現(xiàn)。
增加新庫(kù),按照現(xiàn)有節(jié)點(diǎn), 增加對(duì)應(yīng)的數(shù)量。
數(shù)據(jù)遷移:避免增量影響, 先斷開(kāi)主從,再導(dǎo)入(耗時(shí)較長(zhǎng)), 同步完成并做校驗(yàn)
增量同步:開(kāi)啟 Canal 同步服務(wù), 監(jiān)聽(tīng)從節(jié)點(diǎn)數(shù)據(jù)庫(kù), 再開(kāi)啟主從同步,從節(jié)點(diǎn)收到數(shù)據(jù)后會(huì)通過(guò) Canal 服務(wù), 傳遞至新的 DB 節(jié)點(diǎn)。
切換新庫(kù):通過(guò) Nginx,切換訪問(wèn)流量至新的服務(wù)。
修復(fù)切換異常數(shù)據(jù):在切換過(guò)程中, 如果出現(xiàn),Canal 未同步,但已切換至新庫(kù)的請(qǐng)求(比如下單,修改了資金, 但還未同步 ), 可以通過(guò)定制程序, 讀取檢測(cè)異常日志,做自動(dòng)修復(fù)或人工處理。
針對(duì)此種情況, 最好是在凌晨用戶量小的時(shí)候, 或?qū)iT(mén)停止外網(wǎng)訪問(wèn),進(jìn)行切換,減少異常數(shù)據(jù)的產(chǎn)生。
數(shù)據(jù)校驗(yàn):為保障數(shù)據(jù)的完全一致, 有必要對(duì)數(shù)據(jù)的數(shù)量完整性做校驗(yàn)。
1.6 平滑 2N 方案(大數(shù)據(jù)量)
線上數(shù)據(jù)庫(kù),為了保障其高可用,一般每臺(tái)主庫(kù)會(huì)配置一臺(tái)從庫(kù),主庫(kù)負(fù)責(zé)讀寫(xiě),從庫(kù)負(fù)責(zé)讀取。下圖所示,A,B 是主庫(kù),A0 和 B0 是從庫(kù)。
當(dāng)需要擴(kuò)容的時(shí)候,我們把 A0 和 B0 升級(jí)為新的主庫(kù)節(jié)點(diǎn),如此由 2 個(gè)分庫(kù)變?yōu)?4 個(gè)分庫(kù)。同時(shí)在上層的分片配置,做好映射,規(guī)則如下:
把 uid%4=0 和 uid%4=2 的數(shù)據(jù)分別分配到 A 和 A0 主庫(kù)中
把 uid%4=1 和 uid%4=3 的數(shù)據(jù)分配到 B 和 B0 主庫(kù)中
因?yàn)?A 和 A0 庫(kù)的數(shù)據(jù)相同,B 和 B0 數(shù)據(jù)相同,此時(shí)無(wú)需做數(shù)據(jù)遷移。只需調(diào)整變更一下分片配置即可,通過(guò)配置中心更新,不需要重啟。
由于之前 uid%2 的數(shù)據(jù)是分配在 2 個(gè)庫(kù)里面,擴(kuò)容之后需要分布到 4 個(gè)庫(kù)中,但由于舊數(shù)據(jù)仍存在(uid%4=0 的節(jié)點(diǎn),還有一半 uid%4=2 的數(shù)據(jù)),所以需要對(duì)冗余數(shù)據(jù)做一次清理。
這個(gè)清理,并不會(huì)影響線上數(shù)據(jù)的一致性,可以隨時(shí)隨地進(jìn)行。
處理完成之后,為保證數(shù)據(jù)的高可用,以及將來(lái)下一步的擴(kuò)容需求。
可以為現(xiàn)有的主庫(kù)再次分配一個(gè)從庫(kù)。
2. 平滑 2N 擴(kuò)容方案實(shí)踐
2.1 實(shí)現(xiàn)應(yīng)用服務(wù)級(jí)別的動(dòng)態(tài)擴(kuò)容
擴(kuò)容前部署架構(gòu):
2.1.1 MariaDB 服務(wù)安裝
切換阿里云鏡像服務(wù)(YUM 安裝過(guò)慢可以切換)
yum -y install wget ## 備份CentOS-Base.repo mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo wget -P /etc/yum.repos.d/ http://mirrors.aliyun.com/repo/epel-7.repo yum clean all yum makecache
配置 YUM 源
vi /etc/yum.repos.d/mariadb-10.2.repo
增加以下內(nèi)容:
[mariadb] name = MariaDB baseurl = https://mirrors.ustc.edu.cn/mariadb/yum/10.2/centos7-amd64 gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB gpgcheck=1
執(zhí)行安裝
yum -y install mariadb mariadb-server MariaDB-client MariaDB-common
如果之前已經(jīng)安裝, 需要先刪除(如果之前沒(méi)有安裝, 可以忽略此步驟)
停止 Mariadb 服務(wù)
[root@localhost yum.repos.d]# ps -ef | grep mysql root 1954 1 0 Oct04 ? 0043 /usr/sbin/mysqld --wsrep-new-cluster --user=root root 89521 81403 0 07:40 pts/0 0000 grep --color=auto mysql [root@localhost yum.repos.d]# kill 1954
卸載 Mariadb 服務(wù)
yum -y remove Maria*
刪除數(shù)據(jù)與配置:
rm -rf /var/lib/mysql/* rm -rf /etc/my.cnf.d/ rm -rf /etc/my.cnf
啟動(dòng) MariaDB 后,執(zhí)行安全配置向?qū)?,可根?jù)安全配置向?qū)岣邤?shù)據(jù)庫(kù)的安全性
systemctl start mariadb mysql_secure_installation
開(kāi)啟用戶遠(yuǎn)程連接權(quán)限
將連接用戶 root 開(kāi)啟遠(yuǎn)程連接權(quán)限;
mysql -uroot -p654321
進(jìn)入 MySQL 服務(wù), 執(zhí)行以下操作:
use mysql; delete from user; ## 配置root用戶使用密碼654321從任何主機(jī)都可以連接到mysql服務(wù)器 GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '654321' WITH GRANT OPTION; FLUSH PRIVILEGES;
2.1.2 MariaDB 雙主同步
在 Server1 增加配置:
在 /etc/my.cnf 中添加以下配置:
[mysqld] server-id = 1 log-bin=mysql-bin relay-log = mysql-relay-bin ## 忽略mysql、information_schema庫(kù)下對(duì)表的操作 replicate-wild-ignore-table=mysql.% replicate-wild-ignore-table=information_schema.% ## 默認(rèn)的情況下mysql是關(guān)閉的; log-slave-updates=on ## 復(fù)制過(guò)程中,有任何錯(cuò)誤,直接跳過(guò) slave-skip-errors=all auto-increment-offset=1 auto-increment-increment=2 ## binlog的格式:STATEMENT,ROW,MIXED binlog_format=mixed ## 自動(dòng)過(guò)期清理binlog,默認(rèn)0天,即不自動(dòng)清理 expire_logs_days=10
注意, Server1 自增為奇數(shù)位:
auto-increment-offset=1 主鍵自增基數(shù),從 1 開(kāi)始。
auto-increment-increment=2 主鍵自增偏移量,每次為 2。
在 Server2 增加配置:
修改 /etc/my.cnf:
[mysqld] server-id = 2 log-bin=mysql-bin relay-log = mysql-relay-bin replicate-wild-ignore-table=mysql.% replicate-wild-ignore-table=information_schema.% log-slave-updates=on slave-skip-errors=all auto-increment-offset=2 auto-increment-increment=2 binlog_format=mixed expire_logs_days=10
Server2 自增為偶數(shù)位:
auto-increment-offset=2 主鍵自增基數(shù),從 2 開(kāi)始。
auto-increment-increment=2 主鍵自增偏移量,每次為 2。
配置修改完成后, 重啟數(shù)據(jù)庫(kù)。
同步授權(quán)配置
在 Server1 創(chuàng)建 replica 用于主從同步的用戶:
MariaDB [(none)]> grant replication slave, replication client on *.* to 'replica'@'%' identified by 'replica'; mysql> flush privileges;
查詢(xún)?nèi)罩疚募c偏移量,開(kāi)啟同步時(shí)需使用:
MariaDB [(none)]> show master status; +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000001 | 663 | | | +------------------+----------+--------------+------------------+
同樣, 在 Server2 創(chuàng)建 replica 用于主從同步的用戶:
MariaDB [(none)]> grant replication slave, replication client on *.* to 'replica'@'%' identified by 'replica'; mysql> flush privileges;
查詢(xún)?nèi)罩疚募c偏移量:
MariaDB [(none)]> show master status; +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000001 | 663 | | | +------------------+----------+--------------+------------------+
配置主從同步信息
在 Server1 中執(zhí)行:
MariaDB [(none)]> change master to master_host='192.168.116.141',master_user='replica', master_password='replica', master_port=3306, master_log_file='mysql-bin.000007', master_log_pos=374, master_connect_retry=30;
在 Server2 中執(zhí)行:
MariaDB [(none)]> change master to master_host='192.168.116.140',master_user='replica', master_password='replica', master_port=3306, master_log_file='mysql-bin.000015', master_log_pos=374, master_connect_retry=30;
開(kāi)啟雙主同步
在 Server1 和 Server2 中分別執(zhí)行:
MariaDB [(none)]> start slave; Query OK, 0 rows affected (0.00 sec)
在 Server1 查詢(xún)同步信息:
MariaDB [(none)]> show slave statusG; *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 10.10.20.126 Master_User: replica Master_Port: 3306 Connect_Retry: 30 Master_Log_File: mysql-bin.000001 Read_Master_Log_Pos: 663 Relay_Log_File: mysql-relay-bin.000002 Relay_Log_Pos: 555 Relay_Master_Log_File: mysql-bin.000001 Slave_IO_Running: Yes Slave_SQL_Running: Yes ...
在 Server2 查詢(xún)同步信息:
MariaDB [(none)]> show slave statusG; *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 10.10.20.125 Master_User: replica Master_Port: 3306 Connect_Retry: 30 Master_Log_File: mysql-bin.000001 Read_Master_Log_Pos: 663 Relay_Log_File: mysql-relay-bin.000002 Relay_Log_Pos: 555 Relay_Master_Log_File: mysql-bin.000001 Slave_IO_Running: Yes Slave_SQL_Running: Yes ...
Slave_IO_Running 和 Slave_SQL_Running 都是 Yes,說(shuō)明雙主同步配置成功。
2.1.3 KeepAlived 安裝與高可用配置
在 Server1 與 Server2 兩臺(tái)節(jié)點(diǎn)安裝 keepalived:
yum -y install keepalived
關(guān)閉防火墻
systemctl stop firewalld systemctl disable firewalld
設(shè)置主機(jī)名稱(chēng):
Server1 節(jié)點(diǎn):
hostnamectl set-hostname vip1
Server2 節(jié)點(diǎn):
hostnamectl set-hostname vip2
Server1 節(jié)點(diǎn)配置
/etc/keepalived/keepalived.conf:
global_defs { router_id vip1 # 機(jī)器標(biāo)識(shí),和主機(jī)名保持一致,運(yùn)行keepalived服務(wù)器的一個(gè)標(biāo)識(shí) } vrrp_instance VI_1 { #vrrp實(shí)例定義 state BACKUP #lvs的狀態(tài)模式,MASTER代表主, BACKUP代表備份節(jié)點(diǎn) interface ens33 #綁定對(duì)外訪問(wèn)的網(wǎng)卡,vrrp實(shí)例綁定的網(wǎng)卡 virtual_router_id 111 #虛擬路由標(biāo)示,同一個(gè)vrrp實(shí)例采用唯一標(biāo)示 priority 100 #優(yōu)先級(jí),100代表最大優(yōu)先級(jí), 數(shù)字越大優(yōu)先級(jí)越高 advert_int 1 #master與backup節(jié)點(diǎn)同步檢查的時(shí)間間隔,單位是秒 authentication { #設(shè)置驗(yàn)證信息 auth_type PASS #有PASS和AH兩種 auth_pass 6666 #驗(yàn)證密碼,BACKUP密碼須相同 } virtual_ipaddress { #KeepAlived虛擬的IP地址 192.168.116.150 } } virtual_server 192.168.116.150 3306 { #配置虛擬服務(wù)器IP與訪問(wèn)端口 delay_loop 6 #健康檢查時(shí)間 lb_algo rr #負(fù)載均衡調(diào)度算法, rr代表輪詢(xún) lb_kind DR #負(fù)載均衡轉(zhuǎn)發(fā)規(guī)則 DR/NAT/ persistence_timeout 0 #會(huì)話保持時(shí)間,這里要做測(cè)試, 所以設(shè)為0, 實(shí)際可根據(jù)session有效時(shí)間配置 protocol TCP #轉(zhuǎn)發(fā)協(xié)議類(lèi)型,支持TCP和UDP real_server 192.168.116.140 3306 { #配置服務(wù)器節(jié)點(diǎn)VIP1 notify_down /usr/local/shell/mariadb.sh #當(dāng)服務(wù)掛掉時(shí), 會(huì)執(zhí)行此腳本,結(jié)束keepalived進(jìn)程 weight 1 #設(shè)置權(quán)重,越大權(quán)重越高 TCP_CHECK { #狀態(tài)監(jiān)測(cè)設(shè)置 connect_timeout 10 #超時(shí)配置, 單位秒 retry 3 #重試次數(shù) delay_before_retry 3 #重試間隔 connect_port 3306 #連接端口, 和上面保持一致 } } }
創(chuàng)建關(guān)閉腳本 mariadb.sh
/usr/local/shell/mariadb.sh:
pkill keepalived
加入執(zhí)行權(quán)限:
chmod a+x mariadb.sh
Server2 節(jié)點(diǎn)配置:
global_defs { router_id vip2 # 機(jī)器標(biāo)識(shí),和主機(jī)名保持一致,運(yùn)行keepalived服務(wù)器的一個(gè)標(biāo)識(shí) } vrrp_instance VI_1 { #vrrp實(shí)例定義 state BACKUP #lvs的狀態(tài)模式,MASTER代表主, BACKUP代表備份節(jié)點(diǎn) interface ens33 #綁定對(duì)外訪問(wèn)的網(wǎng)卡 virtual_router_id 111 #虛擬路由標(biāo)示,同一個(gè)vrrp實(shí)例采用唯一標(biāo)示 priority 98 #優(yōu)先級(jí),100代表最大優(yōu)先級(jí), 數(shù)字越大優(yōu)先級(jí)越高 advert_int 1 #master與backup節(jié)點(diǎn)同步檢查的時(shí)間間隔,單位是秒 authentication { #設(shè)置驗(yàn)證信息 auth_type PASS #有PASS和AH兩種 auth_pass 6666 #驗(yàn)證密碼,BACKUP密碼須相同 } virtual_ipaddress { #KeepAlived虛擬的IP地址 192.168.116.150 } } virtual_server 192.168.116.150 3306 { #配置虛擬服務(wù)器IP與訪問(wèn)端口 delay_loop 6 #健康檢查時(shí)間 lb_algo rr #負(fù)載均衡調(diào)度算法, rr代表輪詢(xún), 可以關(guān)閉 lb_kind DR #負(fù)載均衡轉(zhuǎn)發(fā)規(guī)則, 可以關(guān)閉 persistence_timeout 0 #會(huì)話保持時(shí)間,這里要做測(cè)試, 所以設(shè)為0, 實(shí)際可根據(jù)session有效時(shí)間配置 protocol TCP #轉(zhuǎn)發(fā)協(xié)議類(lèi)型,支持TCP和UDP real_server 192.168.116.141 3306{ #配置服務(wù)器節(jié)點(diǎn)VIP2 notify_down /usr/local/shell/mariadb.sh #當(dāng)服務(wù)掛掉時(shí), 會(huì)執(zhí)行此腳本,結(jié)束keepalived進(jìn)程 weight 1 #設(shè)置權(quán)重,越大權(quán)重越高 TCP_CHECK { #r狀態(tài)監(jiān)測(cè)設(shè)置 connect_timeout 10 #超時(shí)配置, 單位秒 retry 3 #重試次數(shù) delay_before_retry 3 #重試間隔 connect_port 3306 #連接端口, 和上面保持一致 } } }
和 Server1 的差異項(xiàng):
router_id vip2 # 機(jī)器標(biāo)識(shí),和主機(jī)名保持一致 priority 98 #優(yōu)先級(jí),100代表最大優(yōu)先級(jí), 數(shù)字越大優(yōu)先級(jí)越高 real_server 10.10.20.126 3306 #配置服務(wù)器節(jié)點(diǎn)VIP2
注意, 兩臺(tái)節(jié)點(diǎn)都設(shè)為 BACKUP
virtual_router_id 111 #同一個(gè)vrrp實(shí)例采用唯一標(biāo)示 state BACKUP
如果不想重啟后, 爭(zhēng)奪備用節(jié)點(diǎn)的 VIP, 可以設(shè)置此項(xiàng)
nopreempt #不主動(dòng)搶占資源
注意:這個(gè)配置只能設(shè)置在 backup 主機(jī)上,而且這個(gè)主機(jī)優(yōu)先級(jí)要比另外一臺(tái)高
驗(yàn)證高可用
停止主節(jié)點(diǎn) MariaDB 服務(wù), 驗(yàn)證是否自動(dòng)切換。
2.1.4 搭建應(yīng)用服務(wù)工程
ShardingJDBC 的介紹
是 ShardingSphere 下的一個(gè)產(chǎn)品
定位為輕量級(jí) Java 框架,在 Java 的 JDBC 層提供的額外服務(wù)。它使用客戶端直連數(shù)據(jù)庫(kù),以 jar 包形式提供服務(wù),無(wú)需額外部署和依賴(lài),可理解為增強(qiáng)版的 JDBC 驅(qū)動(dòng),完全兼容 JDBC 和各種 ORM 框架。
適用于任何基于 JDBC 的 ORM 框架,如:JPA, Hibernate, Mybatis, Spring JDBC Template 或直接使用 JDBC。
支持任何第三方的數(shù)據(jù)庫(kù)連接池,如:DBCP, C3P0, BoneCP, Druid, HikariCP 等。
支持任意實(shí)現(xiàn) JDBC 規(guī)范的數(shù)據(jù)庫(kù),目前支持 MySQL,Oracle,SQLServer,PostgreSQL 以及任何遵循 SQL92 標(biāo)準(zhǔn)的數(shù)據(jù)庫(kù)
ShardingJDBC 初始化流程
1)配置 ShardingRuleConfiguration 對(duì)象
2)配置表分片規(guī)則 TableRuleConfiguration 對(duì)象,設(shè)置分庫(kù)、分表策略
3)通過(guò) Factory 對(duì)象將 Rule 對(duì)象與 DataSource 對(duì)象裝配
4)ShardingJDBC 使用 DataSource 對(duì)象進(jìn)行分庫(kù)
ShardingJDBC 集成配置
1)maven 依賴(lài)
2)規(guī)則配置 application.yml
3)創(chuàng)建 DataSource
驗(yàn)證應(yīng)用服務(wù)動(dòng)態(tài)擴(kuò)容
// 動(dòng)態(tài)數(shù)據(jù)源配置實(shí)現(xiàn)擴(kuò)容 Properties properties = loadPropertiesFile("datasource1.properties"); try { log.info("load datasource config url: " + properties.get("url")); DruidDataSource druidDataSource = (DruidDataSource) DruidDataSourceFactory.createDataSource(properties); druidDataSource.setRemoveAbandoned(true); druidDataSource.setRemoveAbandonedTimeout(600); druidDataSource.setLogAbandoned(true); // 設(shè)置數(shù)據(jù)源錯(cuò)誤重連時(shí)間 druidDataSource.setTimeBetweenConnectErrorMillis(60000); druidDataSource.init(); OrchestrationShardingDataSource dataSource = SpringContextUtil.getBean("tradeSystemDataSource", OrchestrationShardingDataSource.class); MapdataSourceMap = dataSource.getDataSource().getDataSourceMap(); dataSourceMap.put(DatasourceEnum.DATASOURCE_2.getValue(), druidDataSource); Map dataSourceConfigMap = new HashMap (); for(String key : dataSourceMap.keySet()) { dataSourceConfigMap.put(key, DataSourceConfiguration.getDataSourceConfiguration(dataSourceMap.get(key))); } String result = SHARDING_RULE_TABLE_ORDER.replace(SHARDING_RULE_DATASOURCE, newRule); replaceActualDataNodes(result); SHARDING_RULE_DATASOURCE = newRule; dataSource.renew(new DataSourceChangedEvent( "/" + DruidSystemDataSourceConfiguration.DYNAMIC_SHARDING + "/config/schema/logic_db/datasource", dataSourceConfigMap)); return; } catch (Exception e) { log.error(e.getMessage(), e); }
配置兩個(gè)數(shù)據(jù)源,分別指向 Server1 和 Server2
分片只配置一個(gè)數(shù)據(jù)源
動(dòng)態(tài)增加另一個(gè)數(shù)據(jù)源
注意事項(xiàng)
Sharding JDBC, Mycat, Drds 等產(chǎn)品都是分布式數(shù)據(jù)庫(kù)中間件,相比直接的數(shù)據(jù)源操作,會(huì)存在一些限制,Sharding JDBC 在使用時(shí),要注意以下問(wèn)題:
有限支持子查詢(xún)
不支持 HAVING
不支持 OR,UNION 和 UNION ALL
不支持特殊 INSERT
每條 INSERT 語(yǔ)句只能插入一條數(shù)據(jù),不支持 VALUES 后有多行數(shù)據(jù)的語(yǔ)句
不支持 DISTINCT 聚合
不支持 dual 虛擬表查詢(xún)
不支持 SELECT LAST_INSERT_ID (), 不支持自增序列
不支持 CASE WHEN
2.2 實(shí)現(xiàn)數(shù)據(jù)庫(kù)的秒級(jí)平滑 2N 擴(kuò)容
** 擴(kuò)容部署架構(gòu):**
2.2.1 新增數(shù)據(jù)庫(kù) VIP
在 Server2 節(jié)點(diǎn), 增加 VIP
修改 /etc/keepalived/keepalived.conf
global_defs { router_id vip2 } vrrp_instance VI_1 { #vrrp實(shí)例定義 state BACKUP #lvs的狀態(tài)模式,MASTER代表主, BACKUP代表備份節(jié)點(diǎn) interface ens33 #綁定對(duì)外訪問(wèn)的網(wǎng)卡 virtual_router_id 112 #虛擬路由標(biāo)示,同一個(gè)vrrp實(shí)例采用唯一標(biāo)示 priority 100 #優(yōu)先級(jí),100代表最大優(yōu)先級(jí), 數(shù)字越大優(yōu)先級(jí)越高 advert_int 1 #master與backup節(jié)點(diǎn)同步檢查的時(shí)間間隔,單位是秒 authentication { #設(shè)置驗(yàn)證信息 auth_type PASS #有PASS和AH兩種 auth_pass 6666 #驗(yàn)證密碼,BACKUP密碼須相同 } virtual_ipaddress { #KeepAlived虛擬的IP地址 192.168.116.151 } } virtual_server 192.168.116.151 3306 { #配置虛擬服務(wù)器IP與訪問(wèn)端口 delay_loop 6 #健康檢查時(shí)間 persistence_timeout 0 #會(huì)話保持時(shí)間,這里要做測(cè)試, 所以設(shè)為0, 實(shí)際可根據(jù)session有效時(shí)間配置 protocol TCP #轉(zhuǎn)發(fā)協(xié)議類(lèi)型,支持TCP和UDP real_server 192.168.116.141 3306{ #配置服務(wù)器節(jié)點(diǎn)VIP1 notify_down /usr/local/shell/mariadb.sh weight 1 #設(shè)置權(quán)重,越大權(quán)重越高 TCP_CHECK { #r狀態(tài)監(jiān)測(cè)設(shè)置 connect_timeout 10 #超時(shí)配置, 單位秒 retry 3 #重試次數(shù) delay_before_retry 3 #重試間隔 connect_port 3306 #連接端口, 和上面保持一致 } } }
注意配置項(xiàng):
virtual_router_id 112 #虛擬路由標(biāo)示,同一個(gè)vrrp實(shí)例采用唯一標(biāo)示 priority 100 #優(yōu)先級(jí),100代表最大優(yōu)先級(jí), 數(shù)字越大優(yōu)先級(jí)越高
2.2.2 應(yīng)用服務(wù)增加動(dòng)態(tài)數(shù)據(jù)源
修改應(yīng)用服務(wù)配置, 增加新的數(shù)據(jù)源, 指向新設(shè)置的 VIP:192.168.116.151
通過(guò)應(yīng)用服務(wù)接口, 動(dòng)態(tài)擴(kuò)容調(diào)整
2.2.3 解除原雙主同步
mysql -uroot -p654321
進(jìn)入 Server1:
MariaDB [(none)]> stop slave;
進(jìn)入 Server2:
MariaDB [(none)]> stop slave;
通過(guò)應(yīng)用服務(wù)接口驗(yàn)證數(shù)據(jù)是否解除同步
2.2.4 安裝 MariaDB 擴(kuò)容服務(wù)器
新建兩臺(tái)虛擬機(jī), 分別為 Server3 和 Server4。
在 Server3 和 Server4 兩臺(tái)節(jié)點(diǎn)上安裝 MariaDB 服務(wù)
參考 2.1.1 MariaDB 服務(wù)安裝
配置 Server3 與 Server1,實(shí)現(xiàn)新的雙主同步
[mysqld] server-id = 3 log-bin=mysql-bin relay-log = mysql-relay-bin replicate-wild-ignore-table=mysql.% replicate-wild-ignore-table=information_schema.% log-slave-updates=on slave-skip-errors=all auto-increment-offset=2 auto-increment-increment=2 binlog_format=mixed expire_logs_days=10
service mariadb restart
MariaDB [(none)]> grant replication slave, replication client on *.* to 'replica'@'%' identified by 'replica'; mysql> flush privileges;
mysqldump -uroot -p654321 --routines --single_transaction --master-data=2 --databases smooth > server1.sql
... -- -- Position to start replication or point-in-time recovery from -- -- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000002', MASTER_LOG_POS=17748; ...
scp server1.sql root@192.168.116.142:/usr/local/
mysql -uroot -p654321 < /usr/local/server1.sql
根據(jù)上面的 master status 信息, 在 Server3 中執(zhí)行:
MariaDB [(none)]> change master to master_host='192.168.116.140',master_user='replica', master_password='replica', master_port=3306, master_log_file='mysql-bin.000016', master_log_pos=1754, master_connect_retry=30; Query OK, 0 rows affected (0.01 sec)
MariaDB [(none)]> start slave; Query OK, 0 rows affected (0.00 sec)
如果出現(xiàn)問(wèn)題, 復(fù)原主從同步信息:
MariaDB [(none)]> reset slave; Query OK, 0 rows affected (0.01 sec)
MariaDB [(none)]> show slave status G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 10.10.20.125 Master_User: replica Master_Port: 3306 Connect_Retry: 30 Master_Log_File: mysql-bin.000004 Read_Master_Log_Pos: 11174 Relay_Log_File: mysql-relay-bin.000002 Relay_Log_Pos: 1746 Relay_Master_Log_File: mysql-bin.000004 Slave_IO_Running: Yes Slave_SQL_Running: Yes
查看 Server3 的日志信息:
MariaDB [(none)]> show master status; +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000001 | 4781 | | | +------------------+----------+--------------+------------------+
在 Server1 節(jié)點(diǎn), 配置同步信息:
MariaDB [(none)]> reset slave; Query OK, 0 rows affected (0.00 sec) MariaDB [(none)]> change master to master_host='192.168.116.142',master_user='replica', master_password='replica', master_port=3306, master_log_file='mysql-bin.000005', master_log_pos=6931, master_connect_retry=30; MariaDB [(none)]> start slave; Query OK, 0 rows affected (0.00 sec)
配置 Server1 與 Server3 節(jié)點(diǎn)的同步
檢查同步狀態(tài)信息:
開(kāi)啟主從同步:
配置主從同步信息
將數(shù)據(jù)還原至 Server3 節(jié)點(diǎn):
將備份的 server1.sql 通過(guò) scp 命令拷貝至 Server3 節(jié)點(diǎn)。
查看并記錄 master status 信息:
在 Server1 節(jié)點(diǎn),進(jìn)行數(shù)據(jù)全量備份:
創(chuàng)建 replica 用于主從同步的用戶:
重啟 Server3 數(shù)據(jù)庫(kù)
Server3 節(jié)點(diǎn), 修改 /etc/my.cnf:
配置 Server4 與 Server2 的雙主同步
[mysqld] server-id = 4 log-bin=mysql-bin relay-log = mysql-relay-bin replicate-wild-ignore-table=mysql.% replicate-wild-ignore-table=information_schema.% log-slave-updates=on slave-skip-errors=all auto-increment-offset=2 auto-increment-increment=2 binlog_format=mixed expire_logs_days=10
service mariadb restart
MariaDB [(none)]> grant replication slave, replication client on *.* to 'replica'@'%' identified by 'replica'; mysql> flush privileges;
mysqldump -uroot -p654321 --routines --single_transaction --master-data=2 --databases smooth > server2.sql
... -- -- Position to start replication or point-in-time recovery from -- -- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000003', MASTER_LOG_POS=4208; ...
scp server2.sql root@192.168.116.143:/usr/local/
mysql -uroot -p654321 < /usr/local/server2.sql
根據(jù)上面的 master status 信息, 在 Server4 中執(zhí)行:
MariaDB [(none)]> change master to master_host='192.168.116.141',master_user='replica', master_password='replica', master_port=3306, master_log_file='mysql-bin.000007', master_log_pos=3006, master_connect_retry=30; Query OK, 0 rows affected (0.01 sec)
MariaDB [(none)]> start slave; Query OK, 0 rows affected (0.00 sec)
注意, 如果出現(xiàn)問(wèn)題, 復(fù)原主從同步信息:
MariaDB [(none)]> reset slave; Query OK, 0 rows affected (0.01 sec)
MariaDB [(none)]> show slave status G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 10.10.20.125 Master_User: replica Master_Port: 3306 Connect_Retry: 30 Master_Log_File: mysql-bin.000004 Read_Master_Log_Pos: 11174 Relay_Log_File: mysql-relay-bin.000002 Relay_Log_Pos: 1746 Relay_Master_Log_File: mysql-bin.000004 Slave_IO_Running: Yes Slave_SQL_Running: Yes
查看 Server4 的日志信息:
MariaDB [(none)]> show master status; +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000001 | 3696 | | | +------------------+----------+--------------+------------------+
在 Server2 節(jié)點(diǎn), 配置同步信息:
MariaDB [(none)]> reset slave; Query OK, 0 rows affected (0.00 sec) MariaDB [(none)]> change master to master_host='192.168.116.143',master_user='replica', master_password='replica', master_port=3306, master_log_file='mysql-bin.000005', master_log_pos=5787, master_connect_retry=30; MariaDB [(none)]> start slave; Query OK, 0 rows affected (0.00 sec)
配置 Server2 與 Server4 節(jié)點(diǎn)的同步
檢查同步狀態(tài)信息:
開(kāi)啟主從同步:
配置主從同步信息
將數(shù)據(jù)還原至 Server4 節(jié)點(diǎn):
將備份的 server2.sql 通過(guò) scp 命令拷貝至 Server4 節(jié)點(diǎn)。
查看并記錄 master status 信息:
在 Server2 節(jié)點(diǎn),進(jìn)行數(shù)據(jù)全量備份:
創(chuàng)建 replica 用于主從同步的用戶:
重啟 Server4 數(shù)據(jù)庫(kù)
Server4 節(jié)點(diǎn), 修改 /etc/my.cnf:
2.2.5 增加 KeepAlived 服務(wù)實(shí)現(xiàn)高可用
確保新增的 Server3 和 Server4 節(jié)點(diǎn)安裝 Keepalived 服務(wù)。
修改 Server3 節(jié)點(diǎn)配置
global_defs { router_id vip3 # 機(jī)器標(biāo)識(shí),一般設(shè)為hostname,故障發(fā)生時(shí),郵件通知會(huì)使用到。 } vrrp_instance VI_1 { #vrrp實(shí)例定義 state BACKUP #lvs的狀態(tài)模式,MASTER代表主, BACKUP代表備份節(jié)點(diǎn) interface ens33 #綁定對(duì)外訪問(wèn)的網(wǎng)卡 virtual_router_id 111 #虛擬路由標(biāo)示,同一個(gè)vrrp實(shí)例采用唯一標(biāo)示 priority 98 #優(yōu)先級(jí),100代表最大優(yōu)先級(jí), 數(shù)字越大優(yōu)先級(jí)越高 advert_int 1 #master與backup節(jié)點(diǎn)同步檢查的時(shí)間間隔,單位是秒 authentication { #設(shè)置驗(yàn)證信息 auth_type PASS #有PASS和AH兩種 auth_pass 6666 #驗(yàn)證密碼,BACKUP密碼須相同 } virtual_ipaddress { #KeepAlived虛擬的IP地址 192.168.116.150 } } virtual_server 192.168.116.150 3306 { #配置虛擬服務(wù)器IP與訪問(wèn)端口 delay_loop 6 #健康檢查時(shí)間 persistence_timeout 0 #會(huì)話保持時(shí)間,這里要做測(cè)試, 所以設(shè)為0, 實(shí)際可根據(jù)session有效時(shí)間配置 protocol TCP #轉(zhuǎn)發(fā)協(xié)議類(lèi)型,支持TCP和UDP real_server 192.168.116.142 3306{ #配置服務(wù)器節(jié)點(diǎn)VIP3 notify_down /usr/local/shell/mariadb.sh weight 1 #設(shè)置權(quán)重,越大權(quán)重越高 TCP_CHECK { #r狀態(tài)監(jiān)測(cè)設(shè)置 connect_timeout 10 #超時(shí)配置, 單位秒 retry 3 #重試次數(shù) delay_before_retry 3 #重試間隔 connect_port 3306 #連接端口, 和上面保持一致 } } }
注意里面 IP 配置正確, 修改完成后重啟服務(wù)。
創(chuàng)建關(guān)閉腳本 mariadb.sh
/usr/local/shell/mariadb.sh:
pkill keepalived
加入執(zhí)行權(quán)限:
chmod a+x mariadb.sh
修改 Server4 節(jié)點(diǎn)配置
global_defs { router_id vip4 # 機(jī)器標(biāo)識(shí),一般設(shè)為hostname,故障發(fā)生時(shí),郵件通知會(huì)使用到。 } vrrp_instance VI_1 { #vrrp實(shí)例定義 state BACKUP #lvs的狀態(tài)模式,MASTER代表主, BACKUP代表備份節(jié)點(diǎn) interface ens33 #綁定對(duì)外訪問(wèn)的網(wǎng)卡 virtual_router_id 112 #虛擬路由標(biāo)示,同一個(gè)vrrp實(shí)例采用唯一標(biāo)示 priority 98 #優(yōu)先級(jí),100代表最大優(yōu)先級(jí), 數(shù)字越大優(yōu)先級(jí)越高 advert_int 1 #master與backup節(jié)點(diǎn)同步檢查的時(shí)間間隔,單位是秒 authentication { #設(shè)置驗(yàn)證信息 auth_type PASS #有PASS和AH兩種 auth_pass 6666 #驗(yàn)證密碼,BACKUP密碼須相同 } virtual_ipaddress { #KeepAlived虛擬的IP地址 192.168.116.151 } } virtual_server 192.168.116.151 3306 { #配置虛擬服務(wù)器IP與訪問(wèn)端口 delay_loop 6 #健康檢查時(shí)間 persistence_timeout 0 #會(huì)話保持時(shí)間,這里要做測(cè)試, 所以設(shè)為0, 實(shí)際可根據(jù)session有效時(shí)間配置 protocol TCP #轉(zhuǎn)發(fā)協(xié)議類(lèi)型,支持TCP和UDP real_server 192.168.116.143 3306{ #配置服務(wù)器節(jié)點(diǎn)VIP4 notify_down /usr/local/shell/mariadb.sh weight 1 #設(shè)置權(quán)重,越大權(quán)重越高 TCP_CHECK { #r狀態(tài)監(jiān)測(cè)設(shè)置 connect_timeout 10 #超時(shí)配置, 單位秒 retry 3 #重試次數(shù) delay_before_retry 3 #重試間隔 connect_port 3306 #連接端口, 和上面保持一致 } } }
創(chuàng)建關(guān)閉腳本 mariadb.sh
/usr/local/shell/mariadb.sh:
pkill keepalived
給所有的用戶組加入執(zhí)行權(quán)限:
chmod a+x mariadb.sh
修改完后重啟 Keepalived 服務(wù)。
2.2.6 清理數(shù)據(jù)并驗(yàn)證
通過(guò)應(yīng)用服務(wù)動(dòng)態(tài)擴(kuò)容接口做調(diào)整和驗(yàn)證
在 Server1 節(jié)點(diǎn)清理數(shù)據(jù)
根據(jù)取模規(guī)則, 保留 accountNo 為偶數(shù)的數(shù)據(jù)
delete from t_trade_order where accountNo % 2 != 0
在 Server2 節(jié)點(diǎn)清理數(shù)據(jù)
根據(jù)取模規(guī)則, 保留 accountNo 為奇數(shù)的數(shù)據(jù)
delete from t_trade_order where accountNo % 2 != 1
3.keepalived 高可用配置大全
在 Server1(192.168.116.140)中執(zhí)行:
MariaDB [(none)]> change master to master_host='192.168.116.141',master_user='replica', master_password='replica', master_port=3306, master_log_file='mysql-bin.000005', master_log_pos=3207, master_connect_retry=30;
在 Server2(192.168.116.141)中執(zhí)行:
MariaDB [(none)]> change master to master_host='192.168.116.140',master_user='replica', master_password='replica', master_port=3306, master_log_file='mysql-bin.000012', master_log_pos=1951, master_connect_retry=30;
在 Server3(192.168.116.142)中執(zhí)行:
MariaDB [(none)]> change master to master_host='192.168.116.140',master_user='replica', master_password='replica', master_port=3306, master_log_file='mysql-bin.000013', master_log_pos=2781, master_connect_retry=30; Query OK, 0 rows affected (0.01 sec)
在 Server4(192.168.116.143)中執(zhí)行:
MariaDB [(none)]> change master to master_host='192.168.116.141',master_user='replica', master_password='replica', master_port=3306, master_log_file='mysql-bin.000005', master_log_pos=7358, master_connect_retry=30; Query OK, 0 rows affected (0.01 sec)
Server1 和 Server2 雙主關(guān)系
Server1: keepalived.conf
vi /etc/keepalived/keepalived.conf
global_defs { router_id vip1 } vrrp_instance VI_1 { state BACKUP interface ens33 virtual_router_id 111 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 6666 } virtual_ipaddress { 192.168.116.150 } } virtual_server 192.168.116.150 3306 { delay_loop 6 lb_algo rr lb_kind DR // NAT|DR|TUN persistence_timeout 0 protocol TCP real_server 192.168.116.140 3306 { notify_down /usr/local/shell/mariadb.sh weight 1 TCP_CHECK { connect_timeout 10 retry 3 delay_before_retry 3 connect_port 3306 } } }
Server2:keepalived.conf
vi /etc/keepalived/keepalived.conf
global_defs { router_id vip2 } vrrp_instance VI_1 { state BACKUP interface ens33 virtual_router_id 111 priority 98 advert_int 1 authentication { auth_type PASS auth_pass 6666 } virtual_ipaddress { 192.168.116.150 } } virtual_server 192.168.116.150 3306 { delay_loop 6 lb_algo rr lb_kind DR persistence_timeout 0 protocol TCP real_server 192.168.116.141 3306{ notify_down /usr/local/shell/mariadb.sh weight 1 TCP_CHECK { connect_timeout 10 retry 3 delay_before_retry 3 connect_port 3306 } } }
新增數(shù)據(jù)庫(kù) VIP
Server2:keepalived.conf
vi /etc/keepalived/keepalived.conf
global_defs { router_id vip2 } vrrp_instance VI_1 { state BACKUP interface ens33 virtual_router_id 112 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 6666 } virtual_ipaddress { 192.168.116.151 } } virtual_server 192.168.116.151 3306 { delay_loop 6 persistence_timeout 0 protocol TCP real_server 192.168.116.141 3306{ notify_down /usr/local/shell/mariadb.sh weight 1 TCP_CHECK { connect_timeout 10 retry 3 delay_before_retry 3 connect_port 3306 } } }
Server1 和 Server3 雙主關(guān)系
Server3: keepalived.conf
vi /etc/keepalived/keepalived.conf
global_defs { router_id vip3 } vrrp_instance VI_1 { state BACKUP interface ens33 virtual_router_id 111 priority 98 advert_int 1 authentication { auth_type PASS auth_pass 6666 } virtual_ipaddress { 192.168.116.150 } } virtual_server 192.168.116.150 3306 { delay_loop 6 lb_algo rr lb_kind DR persistence_timeout 0 protocol TCP real_server 192.168.116.142 3306 { notify_down /usr/local/shell/mariadb.sh weight 1 TCP_CHECK { connect_timeout 10 retry 3 delay_before_retry 3 connect_port 3306 } } }
Server2 和 Server4 雙主關(guān)系
Server4: keepalived.conf
vi /etc/keepalived/keepalived.conf
global_defs { router_id vip4 } vrrp_instance VI_1 { state BACKUP interface ens33 virtual_router_id 112 priority 98 advert_int 1 authentication { auth_type PASS auth_pass 6666 } virtual_ipaddress { 192.168.116.151 } } virtual_server 192.168.116.151 3306 { delay_loop 6 lb_algo rr lb_kind DR persistence_timeout 0 protocol TCP real_server 192.168.116.143 3306{ notify_down /usr/local/shell/mariadb.sh weight 1 TCP_CHECK { connect_timeout 10 retry 3 delay_before_retry 3 connect_port 3306 } } }
審核編輯:劉清
-
TCP
+關(guān)注
關(guān)注
8文章
1402瀏覽量
81015 -
UDP
+關(guān)注
關(guān)注
0文章
330瀏覽量
34638 -
虛擬機(jī)
+關(guān)注
關(guān)注
1文章
966瀏覽量
29346 -
MYSQL數(shù)據(jù)庫(kù)
+關(guān)注
關(guān)注
0文章
96瀏覽量
9876
原文標(biāo)題:6種MySQL數(shù)據(jù)庫(kù)平滑擴(kuò)容方案剖析
文章出處:【微信號(hào):OSC開(kāi)源社區(qū),微信公眾號(hào):OSC開(kāi)源社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
labview有調(diào)用mysql數(shù)據(jù)庫(kù)問(wèn)題????
MySQL數(shù)據(jù)庫(kù)如何安裝和使用說(shuō)明
華為云數(shù)據(jù)庫(kù)-RDS for MySQL數(shù)據(jù)庫(kù)
【數(shù)據(jù)庫(kù)數(shù)據(jù)恢復(fù)】MySQL數(shù)據(jù)庫(kù)Delete誤刪除的數(shù)據(jù)恢復(fù)案例

有哪些不同的MySQL數(shù)據(jù)庫(kù)引擎?
MySQL數(shù)據(jù)庫(kù)管理與應(yīng)用
mysql是一個(gè)什么類(lèi)型的數(shù)據(jù)庫(kù)
數(shù)據(jù)庫(kù)mysql基本增刪改查
MySQL數(shù)據(jù)庫(kù)基礎(chǔ)知識(shí)
mysql數(shù)據(jù)庫(kù)基礎(chǔ)命令
數(shù)據(jù)庫(kù)數(shù)據(jù)恢復(fù)—未開(kāi)啟binlog的Mysql數(shù)據(jù)庫(kù)數(shù)據(jù)恢復(fù)案例

數(shù)據(jù)庫(kù)數(shù)據(jù)恢復(fù)—Mysql數(shù)據(jù)庫(kù)表記錄丟失的數(shù)據(jù)恢復(fù)流程

MySQL數(shù)據(jù)庫(kù)的安裝

評(píng)論