詳解Mysql數(shù)據(jù)庫平滑擴(kuò)容解決高并發(fā)和大數(shù)據(jù)量問題
1 停機(jī)方案
- 發(fā)布公告
- 停止服務(wù)
- 離線數(shù)據(jù)遷移(拆分,重新分配數(shù)據(jù))
- 數(shù)據(jù)校驗(yàn)
- 更改配置
- 恢復(fù)服務(wù)
- 回滾預(yù)案
2 停寫方案
- 支持讀寫分離
- 升級(jí)公告
- 中斷寫操作,隔離寫數(shù)據(jù)源(或攔截返回統(tǒng)一提示)
- 數(shù)據(jù)同步處理
- 數(shù)據(jù)校驗(yàn)
- 更改配置
- 恢復(fù)寫操作
- 數(shù)據(jù)清理
- 回滾預(yù)案
3 平滑擴(kuò)容之雙寫方案(中小型數(shù)據(jù))

雙寫方案可通過canal或mq做實(shí)現(xiàn)。
- 增加新庫
- 數(shù)據(jù)遷移:
避免增量影響, 先斷開主從,再導(dǎo)入(耗時(shí)較長), 同步完成并做校驗(yàn) - 增量同步:
監(jiān)聽Canal,并開啟主從同步 - 切換新庫
- 修復(fù)切換異常數(shù)據(jù)(canal未同步但已切換至新庫的請(qǐng)求), 通過定制程序讀取異常日志做處理
為什么不通過MariaDB Galera集群直接擴(kuò)充新的服務(wù)器節(jié)點(diǎn)去實(shí)現(xiàn)擴(kuò)容?
- Galera集群是多主同步,擴(kuò)充的節(jié)點(diǎn)提升的是并發(fā)吞吐能力,數(shù)據(jù)瓶頸問題未解決。
通過路由中間件MyCat,Sharding JDBC等, 直接擴(kuò)充新的節(jié)點(diǎn)是否可性? - 原數(shù)據(jù)需要重新分配, 比如取模分片。
總結(jié):這種方案就是水平擴(kuò)容,提高了并發(fā)量,但是實(shí)際大數(shù)據(jù)量的瓶頸沒有解決.
4 平滑擴(kuò)容之2N方案大數(shù)據(jù)量問題解決
4.1 擴(kuò)容問題
項(xiàng)目初期,部署了數(shù)據(jù)庫A及其從機(jī)A0,B及其從節(jié)點(diǎn)B0,為將數(shù)據(jù)平均分配,在service層,使用uid%2取模分片(可采用sharding JDBC),將數(shù)據(jù)分配到對(duì)應(yīng)的數(shù)據(jù)庫。如下圖

隨著用戶量的增大,用戶產(chǎn)生的數(shù)據(jù)量最終達(dá)到數(shù)據(jù)庫的最佳存儲(chǔ)容量,需要進(jìn)行擴(kuò)容,否則CRUD操作會(huì)變慢,影響服務(wù)的響應(yīng)速度。
如何平滑的擴(kuò)容,保證業(yè)務(wù)的連續(xù)性和高可用,對(duì)業(yè)務(wù)影響最?。?/p>
4.2 解決方案
先把A0和B0升級(jí)為新的主庫節(jié)點(diǎn),如此,由2個(gè)分庫變?yōu)?個(gè)分庫。同時(shí)在上層的分片配置,做好映射,規(guī)則如下:
uid%4=0的和uid%4=2的數(shù)據(jù)分別分配到A和A0主庫中uid%4=1的和uid%4=3的數(shù)據(jù)分別分配到B和B0主庫中

由于A和A0庫的數(shù)據(jù)相同,B和B0庫的數(shù)據(jù)相同,此時(shí)無需數(shù)據(jù)遷移,只需調(diào)整分片配置即可,可通過配置中心更新,不需要重啟。

3. 擴(kuò)容之后舊數(shù)據(jù)有冗余,需要對(duì)冗余數(shù)據(jù)做清理
-- 針對(duì)A,去除%4!=0的 delete from user.userinfo where uid % 4 != 0; -- 針對(duì)A0,去除%4!=2的 delete from user.userinfo where uid % 4 != 2; -- 針對(duì)B,去除%4!=1的 delete from user.userinfo where uid % 4 != 1; -- 針對(duì)B0,去除%4!=3的 delete from user.userinfo where uid % 4 != 3;
處理完成后,為保證數(shù)據(jù)高可用,需要再次為現(xiàn)有主庫增加一個(gè)從庫

以下為雙主架構(gòu)進(jìn)行水平擴(kuò)容,下圖為現(xiàn)在的架構(gòu)

4.3 雙主架構(gòu)思想
1.兩臺(tái)mysql都可讀寫,互為主備,默認(rèn)只使用一臺(tái)(masterA)負(fù)責(zé)數(shù)據(jù)的寫入,另一臺(tái)(masterB)備用;
2.masterA是masterB的主庫,masterB又是masterA的主庫,它們互為主從;
3.兩臺(tái)主庫之間做高可用,可以采用keepalived等方案(使用VIP對(duì)外提供服務(wù));
4.所有提供服務(wù)的從服務(wù)器與masterB進(jìn)行主從同步(雙主多從);
5.建議采用高可用策略的時(shí)候,masterA或masterB均不因宕機(jī)恢復(fù)后而搶占VIP(非搶占模式);
這樣做可以在一定程度上保證主庫的高可用,在一臺(tái)主庫down掉之后,可以在極短的時(shí)間內(nèi)切換到另一臺(tái)主庫上(盡可能減少主庫宕機(jī)對(duì)業(yè)務(wù)造成的影響),減少了主從同步給線上主庫帶來的壓力;
但是也有幾個(gè)不足的地方:
1.masterB可能會(huì)一直處于空閑狀態(tài)(可以用它當(dāng)從庫,負(fù)責(zé)部分查詢);
2.主庫后面提供服務(wù)的從庫要等masterB先同步完了數(shù)據(jù)后才能去masterB上去同步數(shù)據(jù),這樣可能會(huì)造成一定程度的同步延時(shí);
4.4 環(huán)境部署
4.4.1 MariaDB服務(wù)安裝 切換阿里云鏡像服務(wù)(YUM安裝過慢可以切換)
yum -y install wget 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)安裝, 需要先刪除(如果之前沒有安裝, 可以忽略此步驟)
停止Mariadb服務(wù)
[root@localhost yum.repos.d]# ps -ef | grep mysql root 1954 1 0 Oct04 ? 00:05:43 /usr/sbin/mysqld -- wsrep-new-cluster --user=root root 89521 81403 0 07:40 pts/0 00:00:00 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
初始化配置
systemctl start mariadb mysql_secure_installation
開啟用戶遠(yuǎn)程連接權(quán)限
將連接用戶root開啟遠(yuǎn)程連接權(quán)限;
mysql -uroot -p654321
進(jìn)入MySQL服務(wù), 執(zhí)行以下操作:
use mysql; delete from user; GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '654321' WITH GRANT OPTION; FLUSH PRIVILEGES;
4.4.2 MariaDB雙主同步
在Server1增加配置:
在/etc/my.cnf中添加以下配置:
[mysqld] server-id = 1 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=1 auto-increment-increment=2 binlog_format=mixed expire_logs_days=10
注意, Server1自增為奇數(shù)位:
auto-increment-offset=1 主鍵自增基數(shù), 從1開始。
auto-increment-increment=2 主鍵自增偏移量,每次為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開始。
auto-increment-increment=2 主鍵自增偏移量,每次為2。
配置修改完成后, 重啟數(shù)據(jù)庫。
3. 同步授權(quán)配置
在Server1創(chuàng)建replica用于主從同步的用戶:
MariaDB [(none)]> grant replication slave, replication client on *.* to 'replica'@'%' identified by 'replica'; mysql> flush privileges;
查詢?nèi)罩疚募c偏移量,開啟同步時(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;
查詢?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='10.10.20.126',master_user='replica', master_password='replica', master_port=3306, master_log_file='mysql-bin.000001', master_log_pos=663, master_connect_retry=30;
在Server2中執(zhí)行:
MariaDB [(none)]> change master to master_host='10.10.20.125',master_user='replica', master_password='replica', master_port=3306, master_log_file='mysql-bin.000001', master_log_pos=663, master_connect_retry=30;
開啟雙主同步
在Server1和Server2中分別執(zhí)行:
MariaDB [(none)]> start slave; Query OK, 0 rows affected (0.00 sec)
在Server1查詢同步信息:
MariaDB [(none)]> show slave status\G;
*************************** 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查詢同步信息:
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.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,說明雙主同步配置成功。
4.4.3 KeepAlived安裝與高可用配置
在Server1與Server2兩臺(tái)節(jié)點(diǎn)安裝keepalived:
yum -y install keepalived
2.關(guān)閉防火墻
systemctl stop firewalld systemctl disable firewalld
設(shè)置主機(jī)名稱:
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ī)名保持一致
}
vrrp_instance VI_1 { #vrrp實(shí)例定義
state BACKUP #lvs的狀態(tài)模式,MASTER代表主, BACKUP代表備份節(jié)點(diǎn)
interface ens33 #綁定對(duì)外訪問的網(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地址
10.10.20.130
}
}
virtual_server 10.10.20.130 3306 { #配置虛擬服務(wù)器IP與訪問端口
delay_loop 6 #健康檢查時(shí)間
lb_algo rr #負(fù)載均衡調(diào)度算法, rr代表輪詢
lb_kind DR #負(fù)載均衡轉(zhuǎn)發(fā)規(guī)則
persistence_timeout 0 #會(huì)話保持時(shí)間,這里要做測試, 所以設(shè)為0, 實(shí)際可根
據(jù)session有效時(shí)間配置
protocol TCP #轉(zhuǎn)發(fā)協(xié)議類型,支持TCP和UDP
real_server 10.10.20.125 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 { #r狀態(tài)監(jiān)測設(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
5.Server2節(jié)點(diǎn)配置:
global_defs {
router_id vip2 # 機(jī)器標(biāo)識(shí),和主機(jī)名保持一致
}
vrrp_instance VI_1 { #vrrp實(shí)例定義
state BACKUP #lvs的狀態(tài)模式,MASTER代表主, BACKUP代表備份節(jié)點(diǎn)
interface ens33 #綁定對(duì)外訪問的網(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地址
10.10.20.130
}
}
virtual_server 10.10.20.130 3306 { #配置虛擬服務(wù)器IP與訪問端口
delay_loop 6 #健康檢查時(shí)間
lb_algo rr #負(fù)載均衡調(diào)度算法, rr代表輪詢, 可以關(guān)閉
lb_kind DR #負(fù)載均衡轉(zhuǎn)發(fā)規(guī)則, 可以關(guān)閉
persistence_timeout 0 #會(huì)話保持時(shí)間,這里要做測試, 所以設(shè)為0, 實(shí)際可根
據(jù)session有效時(shí)間配置
protocol TCP #轉(zhuǎn)發(fā)協(xié)議類型,支持TCP和UDP
real_server 10.10.20.126 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)測設(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
如果不想重啟后, 爭奪備用節(jié)點(diǎn)的VIP, 可以設(shè)置此項(xiàng)
nopreempt #不主動(dòng)搶占資源
6. 驗(yàn)證高可用
停止主節(jié)點(diǎn)MariaDB服務(wù), 驗(yàn)證是否自動(dòng)切換。
4.4.4 搭建應(yīng)用服務(wù)工程
- ShardingJDBC的集成配置
- ShardingJDBC數(shù)據(jù)源的動(dòng)態(tài)切換實(shí)現(xiàn)
- 驗(yàn)證應(yīng)用服務(wù)動(dòng)態(tài)擴(kuò)容
- 配置兩個(gè)數(shù)據(jù)源,分別指向Server1和Server2
- 分片只配置一個(gè)數(shù)據(jù)源
- 動(dòng)態(tài)增加另一個(gè)數(shù)據(jù)源
- 動(dòng)態(tài)擴(kuò)容的驗(yàn)證
- 動(dòng)態(tài)擴(kuò)容的復(fù)原驗(yàn)證(模擬節(jié)點(diǎn)異常, 實(shí)現(xiàn)復(fù)原單節(jié)點(diǎn)數(shù)據(jù)源)
- 采用動(dòng)態(tài)數(shù)據(jù)源配置實(shí)現(xiàn)擴(kuò)容(擴(kuò)容實(shí)踐中改造)
// 動(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);
Map<String, DataSource> dataSourceMap =
dataSource.getDataSource().getDataSourceMap();
dataSourceMap.put(DatasourceEnum.DATASOURCE_2.getValue(),
druidDataSource);
Map<String, DataSourceConfiguration> dataSourceConfigMap = new
HashMap<String, DataSourceConfiguration>();
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);
}
注意事項(xiàng)
Sharding JDBC, Mycat, Drds 等產(chǎn)品都是分布式數(shù)據(jù)庫中間件, 相比直接的數(shù)據(jù)源操作, 會(huì)存在一些
限制, Sharding JDBC在使用時(shí), 要注意以下問題:
有限支持子查詢
不支持HAVING
不支持OR,UNION 和 UNION ALL
不支持特殊INSERT
每條INSERT語句只能插入一條數(shù)據(jù),不支持VALUES后有多行數(shù)據(jù)的語句
不支持DISTINCT聚合
不支持dual虛擬表查詢
不支持SELECT LAST_INSERT_ID(), 不支持自增序列
不支持CASE WHEN
5 數(shù)據(jù)庫秒級(jí)平滑2N擴(kuò)容實(shí)踐
擴(kuò)容部署架構(gòu):

5.1 新增數(shù)據(jù)庫VIP
在Server2節(jié)點(diǎn), 增加VIP
修改/etc/keepalived/keepalived.conf,追加:
...
vrrp_instance VI_2 { #vrrp實(shí)例定義
state BACKUP #lvs的狀態(tài)模式,MASTER代表主, BACKUP代表備份節(jié)點(diǎn)
interface ens33 #綁定對(duì)外訪問的網(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地址
10.10.20.131
}
}
virtual_server 10.10.20.131 3306 { #配置虛擬服務(wù)器IP與訪問端口
delay_loop 6 #健康檢查時(shí)間
persistence_timeout 0 #會(huì)話保持時(shí)間,這里要做測試, 所以設(shè)為0, 實(shí)際可根
據(jù)session有效時(shí)間配置
protocol TCP #轉(zhuǎn)發(fā)協(xié)議類型,支持TCP和UDP
real_server 10.10.20.126 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)測設(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í)越高
5.2 應(yīng)用服務(wù)增加動(dòng)態(tài)數(shù)據(jù)源
- 修改應(yīng)用服務(wù)配置, 增加新的數(shù)據(jù)源, 指向新設(shè)置的VIP: 10.10.20.131
- 通過應(yīng)用服務(wù)接口, 動(dòng)態(tài)擴(kuò)容調(diào)整
5.3 解除原雙主同步
- 進(jìn)入Server1: MariaDB [(none)]> stop slave;
- 進(jìn)入Server2:MariaDB [(none)]> stop slave;
- 通過應(yīng)用服務(wù)接口驗(yàn)證數(shù)據(jù)是否解除同步
5.4 安裝MariaDB擴(kuò)容服務(wù)器
- 新建兩臺(tái)虛擬機(jī), 分別為Server3和Server4。
- 在Server3和Server4兩臺(tái)節(jié)點(diǎn)上安裝MariaDB服務(wù)
- 參考 MariaDB服務(wù)安裝
- 配置Server3與Server1,實(shí)現(xiàn)新的雙主同步
Server3節(jié)點(diǎn), 修改/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
重啟Server3數(shù)據(jù)庫
service mariadb restart
創(chuàng)建replica用于主從同步的用戶:
MariaDB [(none)]> grant replication slave, replication client on *.* to 'replica'@'%' identified by 'replica'; mysql> flush privileges;
在Server1節(jié)點(diǎn),進(jìn)行數(shù)據(jù)全量備份:
mysqldump -uroot -p654321 --routines --single_transaction --master-data=2 -- databases smooth > server1.sql
查看并記錄master status信息:
... -- -- Position to start replication or point-in-time recovery from -- -- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000002', MASTER_LOG_POS=17748; ...
將備份的server1.sql通過scp命令拷貝至Server3節(jié)點(diǎn)。scp server1.sql root@10.10.20.127:/usr/local/將數(shù)據(jù)還原至Server3節(jié)點(diǎn):mysql -uroot -p654321 < /usr/local/server1.sql配置主從同步信息
根據(jù)上面的master status信息, 在Server3中執(zhí)行:
MariaDB [(none)]> change master to master_host='10.10.20.125',master_user='replica', master_password='replica', master_port=3306, master_log_file='mysql-bin.000002', master_log_pos=17748, 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)問題, 復(fù)原主從同步信息:
MariaDB [(none)]> reset slave; Query OK, 0 rows affected (0.01 sec)
檢查同步狀態(tài)信息:
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
配置Server1與Server3節(jié)點(diǎn)的同步
查看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='10.10.20.127',master_user='replica', master_password='replica', master_port=3306, master_log_file='mysql-bin.000001', master_log_pos=4781, master_connect_retry=30; MariaDB [(none)]> start slave; Query OK, 0 rows affected (0.00 sec)
配置Server4與Server2的雙主同步
Server4節(jié)點(diǎn), 修改/etc/my.cnf:
[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
重啟Server4數(shù)據(jù)庫
service mariadb restart
創(chuàng)建replica用于主從同步的用戶
MariaDB [(none)]> grant replication slave, replication client on *.* to 'replica'@'%' identified by 'replica'; mysql> flush privileges;
在Server2節(jié)點(diǎn),進(jìn)行數(shù)據(jù)全量備份:
mysqldump -uroot -p654321 --routines --single_transaction --master-data=2 -- databases smooth > server2.sql
查看并記錄master status信息:
... -- -- Position to start replication or point-in-time recovery from -- -- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000003', MASTER_LOG_POS=4208; ...
將備份的server2.sql通過scp命令拷貝至Server4節(jié)點(diǎn)。scp server2.sql root@10.10.20.128:/usr/local/
將數(shù)據(jù)還原至Server4節(jié)點(diǎn):mysql -uroot -p654321 < /usr/local/server2.sql
配置主從同步信息
根據(jù)上面的master status信息, 在Server4中執(zhí)行:
MariaDB [(none)]> change master to master_host='10.10.20.126',master_user='replica', master_password='replica', master_port=3306, master_log_file='mysql-bin.000003', master_log_pos=4208, 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)問題, 復(fù)原主從同步信息:
MariaDB [(none)]> reset slave; Query OK, 0 rows affected (0.01 sec)
檢查同步狀態(tài)信息:
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
配置Server2與Server4節(jié)點(diǎn)的同步
查看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='10.10.20.128',master_user='replica', master_password='replica', master_port=3306, master_log_file='mysql-bin.000001', master_log_pos=3696, master_connect_retry=30; MariaDB [(none)]> start slave; Query OK, 0 rows affected (0.00 sec)
5.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ǎ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地址
10.10.20.130
}
}
virtual_server 10.10.20.130 3306 { #配置虛擬服務(wù)器IP與訪問端口
delay_loop 6 #健康檢查時(shí)間
persistence_timeout 0 #會(huì)話保持時(shí)間,這里要做測試, 所以設(shè)為0, 實(shí)際可根
據(jù)session有效時(shí)間配置
protocol TCP #轉(zhuǎn)發(fā)協(xié)議類型,支持TCP和UDP
real_server 10.10.20.127 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)測設(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
3. 修改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ǎ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地址
10.10.20.131
}
}
virtual_server 10.10.20.131 3306 { #配置虛擬服務(wù)器IP與訪問端口
delay_loop 6 #健康檢查時(shí)間
persistence_timeout 0 #會(huì)話保持時(shí)間,這里要做測試, 所以設(shè)為0, 實(shí)際可根
據(jù)session有效時(shí)間配置
protocol TCP #轉(zhuǎn)發(fā)協(xié)議類型,支持TCP和UDP
real_server 10.10.20.128 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)測設(shè)置
connect_timeout 10 #超時(shí)配置, 單位秒
retry 3 #重試次數(shù)
delay_before_retry 3 #重試間隔
connect_port 3306 #連接端口, 和上面保持一致
}
}
}
重啟服務(wù),創(chuàng)建關(guān)閉腳本mariadb.sh
/usr/local/shell/mariadb.sh:
pkill keepalived
加入執(zhí)行權(quán)限:chmod a+x mariadb.sh
4. 修改Server2節(jié)點(diǎn)的keepAlived配置:
global_defs {
router_id vip2 # 機(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ǎ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地址
10.10.20.131
}
}
virtual_server 10.10.20.131 3306 { #配置虛擬服務(wù)器IP與訪問端口
delay_loop 6 #健康檢查時(shí)間
persistence_timeout 0 #會(huì)話保持時(shí)間,這里要做測試, 所以設(shè)為0, 實(shí)際可根
據(jù)session有效時(shí)間配置
protocol TCP #轉(zhuǎn)發(fā)協(xié)議類型,支持TCP和UDP
real_server 10.10.20.126 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)測設(shè)置
connect_timeout 10 #超時(shí)配置, 單位秒
retry 3 #重試次數(shù)
delay_before_retry 3 #重試間隔
connect_port 3306 #連接端口, 和上面保持一致
}
}
}
修改完后重啟Keepalived服務(wù)。
5.6 清理數(shù)據(jù)并驗(yàn)證
通過應(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
到此這篇關(guān)于詳解Mysql數(shù)據(jù)庫平滑擴(kuò)容解決高并發(fā)和大數(shù)據(jù)量問題的文章就介紹到這了,更多相關(guān)Mysql數(shù)據(jù)庫平滑擴(kuò)容內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
MySQL8.0.21安裝步驟及出現(xiàn)問題解決方案
這篇文章主要介紹了MySQL8.0.21安裝步驟及出現(xiàn)問題解決方案,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12
淺談mysql的timestamp存在的時(shí)區(qū)問題
本文主要介紹了淺談mysql的timestamp存在的時(shí)區(qū)問題,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07
MySQL去重中distinct和group?by的區(qū)別淺析
今天無意中聽到有同事在討論,distinct和group by有什么區(qū)別,下面這篇文章主要給大家介紹了關(guān)于MySQL去重中distinct和group?by區(qū)別的相關(guān)資料,需要的朋友可以參考下2022-11-11
SQL實(shí)現(xiàn)相鄰兩行數(shù)據(jù)的加減乘除操作
這篇文章主要介紹了SQL實(shí)現(xiàn)相鄰兩行數(shù)據(jù)的加減乘除操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-10-10

