“`basic |
1、一個徹底開源的,面向企業應用開發的大數據庫集群 |
2、支持事務、ACID、可以替代MySQL的加強版數據庫 |
3、一個可以視為MySQL集群的企業級數據庫,用來替代昂貴的Oracle集群 |
4、一個融合內存緩存技術、NoSQL技術、HDFS大數據的新型SQL Server |
5、結合傳統數據庫和新型分佈式數據倉庫的新一代企業級數據庫產品 |
6、一個新穎的數據庫中間件產品 |
“` |
|
|
|
## Mycat原理 |
|
|
|
|
然後將此SQL發往後端的真實數據庫,並將返回的結果做適當的處理,最終再返回給用戶。 |
如下圖: |
|
因此你可以用一台到N台服務器來分片,分片規則為(sharding rule)典型的字符串枚舉分片規則,一個規則的定義是分片字段(sharding column)+分片函數(rule function), |
|
|
|
然後將SQL發往這些分片去執行,最後收集和處理所有分片返回的結果數據,並輸出到客戶端。以select * from Orders where prov=?語句為例,查到prov=wuhan,按照分片函數,wuhan返回dn1, |
於是SQL就發給了MySQL1,去取DB1上的查詢結果,並返回給用戶。 |
|
如果上述SQL改為select * from Orders where prov in (『wuhan』,『beijing』),那麼,SQL就會發給MySQL1與MySQL2去執行,然後結果集合併後輸出給用戶。但通常業務中我們的SQL會有Order By |
以及Limit翻頁語法,此時就涉及到結果集在Mycat端的二次處理,這部分的代碼也比較複雜,而最複雜的則屬兩個表的Jion問題, |
|
為此,Mycat提出了創新性的ER分片、全局表、HBT(Human Brain Tech)人工智能的Catlet、以及結合Storm/Spark引擎等十八般武藝的解決辦法,從而成為目前業界最強大的方案,這就是開源的力量! |
|
1.png |
|
## 為什麼使用Mycat |
|
如今隨着互聯網的發展,數據的量級也是撐指數的增長,從GB到TB到PB。對數據的各種操作也是愈加的困難,傳統的關係性數據庫已經無法滿足快速查詢與插入數據的需求; |
|
|
|
一些折衷是無法滿足使用場景的,就比如有些使用場景是絕對要有事務與安全指標的。這個時候NoSQL肯定是無法滿足的,所以還是需要使用關係性數據庫。 |
|
如何使用關係型數據庫解決海量存儲的問題呢?此時就需要做數據庫集群,為了提高查詢性能將一個數據庫的數據分散到不同的數據庫中存儲,為應對此問題就出現了——MyCat |
|
核心技術(分庫分表) |
|
數據庫分片指:通過某種特定的條件,將我們存放在一個數據庫中的數據分散存放在不同的多個數據庫(主機)中,這樣來達到分散單台設備的負載,根據切片規則,可分為以下兩種切片模式 |
MyCAT通過定義表的分片規則來實現分片,每個表格可以捆綁一個分片規則,每個分片規則指定一個分片字段並綁定一個函數,來實現動態分片算法 |
|
1 . Schema:邏輯庫,與MySQL中的Database(數據庫)對應,一個邏輯庫中定義了所包括的Table。 |
2 . Table:邏輯表,即物理數據庫中存儲的某一張表,與傳統數據庫不同,這裡的表格需要聲明其所存儲的邏輯數據節點DataNode。在此可以指定表的分片規則。 |
3 . DataNode:MyCAT的邏輯數據節點,是存放table的具體物理節點,也稱之為分片節點,通過DataSource來關聯到後端某個具體數據庫上 |
4.DataSource:定義某個物理庫的訪問地址,用於捆綁到Datanode上 |
5 . 分片規則:前面講了數據切分,一個大表被分成若干個分片表,就需要一定的規則,這樣按照某種業務規則把數據分到某個分片的規則就是分片規則,數據切分選擇合適的分片規則非常重要,將極大的避免後續數據處理的難 |
|
## Mycat讀寫分離 |
|
· 基礎架構圖 |
|
|
|
2.png |
|
### 環境準備 |
|
|
|
|
|
|
|
|
|
|
|
|
### 二進制安裝mysql |
|
1.創建目錄初始化數據 |
|
“`bash |
mkdir /data/33{07..10}/data -p |
mysqld –initialize-insecure –user=mysql –datadir=/data/3307/data –basedir=/app/mysql |
mysqld –initialize-insecure –user=mysql –datadir=/data/3308/data –basedir=/app/mysql |
mysqld –initialize-insecure –user=mysql –datadir=/data/3309/data –basedir=/app/mysql |
mysqld –initialize-insecure –user=mysql –datadir=/data/3310/data –basedir=/app/mysql |
“` |
|
|
2.準備配置文件和啟動腳本 |
|
“`bash |
db01====== |
cat >/data/3307/my.cnf<<EOF |
[mysqld] |
basedir=/app/mysql |
datadir=/data/3307/data |
socket=/data/3307/mysql.sock |
port=3307 |
log-error=/data/3307/mysql.log |
log_bin=/data/3307/mysql-bin |
binlog_format=row |
skip-name-resolve |
server-id=7 |
gtid-mode=on |
enforce-gtid-consistency=true |
log-slave-updates=1 |
EOF |
|
cat >/data/3308/my.cnf<<EOF |
[mysqld] |
basedir=/app/mysql |
datadir=/data/3308/data |
port=3308 |
socket=/data/3308/mysql.sock |
log-error=/data/3308/mysql.log |
log_bin=/data/3308/mysql-bin |
binlog_format=row |
skip-name-resolve |
server-id=8 |
gtid-mode=on |
enforce-gtid-consistency=true |
log-slave-updates=1 |
EOF |
|
cat >/data/3309/my.cnf<<EOF |
[mysqld] |
basedir=/app/mysql |
datadir=/data/3309/data |
socket=/data/3309/mysql.sock |
port=3309 |
log-error=/data/3309/mysql.log |
log_bin=/data/3309/mysql-bin |
binlog_format=row |
skip-name-resolve |
server-id=9 |
gtid-mode=on |
enforce-gtid-consistency=true |
log-slave-updates=1 |
EOF |
cat >/data/3310/my.cnf<<EOF |
[mysqld] |
basedir=/app/mysql |
datadir=/data/3310/data |
socket=/data/3310/mysql.sock |
port=3310 |
log-error=/data/3310/mysql.log |
log_bin=/data/3310/mysql-bin |
binlog_format=row |
skip-name-resolve |
server-id=10 |
gtid-mode=on |
enforce-gtid-consistency=true |
log-slave-updates=1 |
EOF |
|
cat >/etc/systemd/system/mysqld3307.service<<EOF |
[Unit] |
Description=MySQL Server |
Documentation=man:mysqld(8) |
Documentation=//dev.mysql.com/doc/refman/en/using-systemd.html |
After=network.target |
After=syslog.target |
[Install] |
WantedBy=multi-user.target |
[Service] |
User=mysql |
Group=mysql |
ExecStart=/app/mysql/bin/mysqld –defaults-file=/data/3307/my.cnf |
LimitNOFILE = 5000 |
EOF |
|
cat >/etc/systemd/system/mysqld3308.service<<EOF |
[Unit] |
Description=MySQL Server |
Documentation=man:mysqld(8) |
Documentation=//dev.mysql.com/doc/refman/en/using-systemd.html |
After=network.target |
After=syslog.target |
[Install] |
WantedBy=multi-user.target |
[Service] |
User=mysql |
Group=mysql |
ExecStart=/app/mysql/bin/mysqld –defaults-file=/data/3308/my.cnf |
LimitNOFILE = 5000 |
EOF |
|
cat >/etc/systemd/system/mysqld3309.service<<EOF |
[Unit] |
Description=MySQL Server |
Documentation=man:mysqld(8) |
Documentation=//dev.mysql.com/doc/refman/en/using-systemd.html |
After=network.target |
After=syslog.target |
[Install] |
WantedBy=multi-user.target |
[Service] |
User=mysql |
Group=mysql |
ExecStart=/app/mysql/bin/mysqld –defaults-file=/data/3309/my.cnf |
LimitNOFILE = 5000 |
EOF |
cat >/etc/systemd/system/mysqld3310.service<<EOF |
[Unit] |
Description=MySQL Server |
Documentation=man:mysqld(8) |
Documentation=//dev.mysql.com/doc/refman/en/using-systemd.html |
After=network.target |
After=syslog.target |
|
[Install] |
WantedBy=multi-user.target |
[Service] |
User=mysql |
Group=mysql |
ExecStart=/app/mysql/bin/mysqld –defaults-file=/data/3310/my.cnf |
LimitNOFILE = 5000 |
EOF |
db02======= |
cat >/data/3307/my.cnf<<EOF |
[mysqld] |
basedir=/app/mysql |
datadir=/data/3307/data |
socket=/data/3307/mysql.sock |
port=3307 |
log-error=/data/3307/mysql.log |
log_bin=/data/3307/mysql-bin |
binlog_format=row |
skip-name-resolve |
server-id=17 |
gtid-mode=on |
enforce-gtid-consistency=true |
log-slave-updates=1 |
EOF |
cat >/data/3308/my.cnf<<EOF |
[mysqld] |
basedir=/app/mysql |
datadir=/data/3308/data |
port=3308 |
socket=/data/3308/mysql.sock |
log-error=/data/3308/mysql.log |
log_bin=/data/3308/mysql-bin |
binlog_format=row |
skip-name-resolve |
server-id=18 |
gtid-mode=on |
enforce-gtid-consistency=true |
log-slave-updates=1 |
EOF |
cat >/data/3309/my.cnf<<EOF |
[mysqld] |
basedir=/app/mysql |
datadir=/data/3309/data |
socket=/data/3309/mysql.sock |
port=3309 |
log-error=/data/3309/mysql.log |
log_bin=/data/3309/mysql-bin |
binlog_format=row |
skip-name-resolve |
server-id=19 |
gtid-mode=on |
enforce-gtid-consistency=true |
log-slave-updates=1 |
EOF |
|
|
cat >/data/3310/my.cnf<<EOF |
[mysqld] |
basedir=/app/mysql |
datadir=/data/3310/data |
socket=/data/3310/mysql.sock |
port=3310 |
log-error=/data/3310/mysql.log |
log_bin=/data/3310/mysql-bin |
binlog_format=row |
skip-name-resolve |
server-id=20 |
gtid-mode=on |
enforce-gtid-consistency=true |
log-slave-updates=1 |
EOF |
|
cat >/etc/systemd/system/mysqld3307.service<<EOF |
[Unit] |
Description=MySQL Server |
Documentation=man:mysqld(8) |
Documentation=//dev.mysql.com/doc/refman/en/using-systemd.html |
After=network.target |
After=syslog.target |
[Install] |
WantedBy=multi-user.target |
[Service] |
User=mysql |
Group=mysql |
ExecStart=/app/mysql/bin/mysqld –defaults-file=/data/3307/my.cnf |
LimitNOFILE = 5000 |
EOF |
|
cat >/etc/systemd/system/mysqld3308.service<<EOF |
[Unit] |
Description=MySQL Server |
Documentation=man:mysqld(8) |
Documentation=//dev.mysql.com/doc/refman/en/using-systemd.html |
After=network.target |
After=syslog.target |
[Install] |
WantedBy=multi-user.target |
[Service] |
User=mysql |
Group=mysql |
ExecStart=/app/mysql/bin/mysqld –defaults-file=/data/3308/my.cnf |
LimitNOFILE = 5000 |
EOF |
|
cat >/etc/systemd/system/mysqld3309.service<<EOF |
[Unit] |
Description=MySQL Server |
Documentation=man:mysqld(8) |
Documentation=//dev.mysql.com/doc/refman/en/using-systemd.html |
After=network.target |
After=syslog.target |
[Install] |
WantedBy=multi-user.target |
[Service] |
User=mysql |
Group=mysql |
ExecStart=/app/mysql/bin/mysqld –defaults-file=/data/3309/my.cnf |
LimitNOFILE = 5000 |
EOF |
cat >/etc/systemd/system/mysqld3310.service<<EOF |
[Unit] |
Description=MySQL Server |
Documentation=man:mysqld(8) |
Documentation=//dev.mysql.com/doc/refman/en/using-systemd.html |
After=network.target |
After=syslog.target |
[Install] |
WantedBy=multi-user.target |
[Service] |
User=mysql |
Group=mysql |
ExecStart=/app/mysql/bin/mysqld –defaults-file=/data/3310/my.cnf |
LimitNOFILE = 5000 |
EOF |
“` |
|
|
3.修改權限啟動多實例 |
|
“`bash |
chown -R mysql.mysql /data/* |
systemctl start mysqld3307 |
systemctl start mysqld3308 |
systemctl start mysqld3309 |
systemctl start mysqld3310 |
|
mysql -S /data/3307/mysql.sock -e “show variables like ‘server_id'” |
mysql -S /data/3308/mysql.sock -e “show variables like ‘server_id'” |
mysql -S /data/3309/mysql.sock -e “show variables like ‘server_id'” |
mysql -S /data/3310/mysql.sock -e “show variables like ‘server_id'” |
“` |
|
|
4.主從配置 |
|
“`bash |
箭頭指向誰是主庫 |
10.0.0.51:3307 <—–> 10.0.0.52:3307 |
10.0.0.51:3309 ——> 10.0.0.51:3307 |
10.0.0.52:3309 ——> 10.0.0.52:3307 |
|
10.0.0.52:3308 <—–> 10.0.0.51:3308 |
10.0.0.52:3310 —–> 10.0.0.52:3308 |
10.0.0.51:3310 —–> 10.0.0.51:3308 |
“` |
|
|
5.分片規劃 |
|
“`bash |
shard1: |
Master:10.0.0.51:3307 |
slave1:10.0.0.51:3309 |
Standby Master:10.0.0.52:3307 |
slave2:10.0.0.52:3309 |
shard2: |
Master:10.0.0.52:3308 |
slave1:10.0.0.52:3310 |
Standby Master:10.0.0.51:3308 |
slave2:10.0.0.51:3310 |
“` |
|
|
6.配置操作 |
|
“`bash |
# db02 |
mysql -S /data/3307/mysql.sock -e “grant replication slave on . to repl@’10.0.0.%’ identified by ‘123’;” |
mysql -S /data/3307/mysql.sock -e “grant all on . to root@’10.0.0.%’ identified by ‘123’ with grant option;” |
|
# db01 |
mysql -S /data/3307/mysql.sock -e “CHANGE MASTER TO MASTER_HOST=’10.0.0.52′, MASTER_PORT=3307, MASTER_AUTO_POSITION=1, MASTER_USER=’repl’, MASTER_PASSWORD=’123′;” |
mysql -S /data/3307/mysql.sock -e “start slave;” |
mysql -S /data/3307/mysql.sock -e “show slave status\G” |
|
|
# db02 |
mysql -S /data/3307/mysql.sock -e “CHANGE MASTER TO MASTER_HOST=’10.0.0.51′, MASTER_PORT=3307, MASTER_AUTO_POSITION=1, MASTER_USER=’repl’, MASTER_PASSWORD=’123′;” |
mysql -S /data/3307/mysql.sock -e “start slave;” |
mysql -S /data/3307/mysql.sock -e “show slave status\G” |
|
# db01 |
mysql -S /data/3309/mysql.sock -e “CHANGE MASTER TO MASTER_HOST=’10.0.0.51′, MASTER_PORT=3307, MASTER_AUTO_POSITION=1, MASTER_USER=’repl’, MASTER_PASSWORD=’123′;” |
mysql -S /data/3309/mysql.sock -e “start slave;” |
mysql -S /data/3309/mysql.sock -e “show slave status\G” |
|
# db02 |
mysql -S /data/3309/mysql.sock -e “CHANGE MASTER TO MASTER_HOST=’10.0.0.52′, MASTER_PORT=3307, MASTER_AUTO_POSITION=1, MASTER_USER=’repl’, MASTER_PASSWORD=’123′;” |
mysql -S /data/3309/mysql.sock -e “start slave;” |
mysql -S /data/3309/mysql.sock -e “show slave status\G” |
|
# db01 |
mysql -S /data/3308/mysql.sock -e “grant replication slave on . to repl@’10.0.0.%’ identified by ‘123’;” |
mysql -S /data/3308/mysql.sock -e “grant all on . to root@’10.0.0.%’ identified by ‘123’ with grant option;” |
|
# db02 |
mysql -S /data/3308/mysql.sock -e “CHANGE MASTER TO MASTER_HOST=’10.0.0.51′, MASTER_PORT=3308, MASTER_AUTO_POSITION=1, MASTER_USER=’repl’, MASTER_PASSWORD=’123′;” |
mysql -S /data/3308/mysql.sock -e “start slave;” |
mysql -S /data/3308/mysql.sock -e “show slave status\G” |
|
# db01 |
mysql -S /data/3308/mysql.sock -e “CHANGE MASTER TO MASTER_HOST=’10.0.0.52′, MASTER_PORT=3308, MASTER_AUTO_POSITION=1, MASTER_USER=’repl’, MASTER_PASSWORD=’123′;” |
mysql -S /data/3308/mysql.sock -e “start slave;” |
mysql -S /data/3308/mysql.sock -e “show slave status\G” |
|
# db02 |
mysql -S /data/3310/mysql.sock -e “CHANGE MASTER TO MASTER_HOST=’10.0.0.52′, MASTER_PORT=3308, MASTER_AUTO_POSITION=1, MASTER_USER=’repl’, MASTER_PASSWORD=’123′;” |
mysql -S /data/3310/mysql.sock -e “start slave;” |
mysql -S /data/3310/mysql.sock -e “show slave status\G” |
|
# db01 |
mysql -S /data/3310/mysql.sock -e “CHANGE MASTER TO MASTER_HOST=’10.0.0.51′, MASTER_PORT=3308, MASTER_AUTO_POSITION=1, MASTER_USER=’repl’, MASTER_PASSWORD=’123′;” |
mysql -S /data/3310/mysql.sock -e “start slave;” |
mysql -S /data/3310/mysql.sock -e “show slave status\G” |
|
Copy |
7.主從狀態檢測 |
mysql -S /data/3307/mysql.sock -e “show slave status\G” |
mysql -S /data/3308/mysql.sock -e “show slave status\G” |
mysql -S /data/3309/mysql.sock -e “show slave status\G” |
mysql -S /data/3310/mysql.sock -e “show slave status\G” |
註:如果中間出現錯誤,在每個節點進行執行以下命令 |
mysql -S /data/3307/mysql.sock -e “stop slave; reset slave all;” |
mysql -S /data/3308/mysql.sock -e “stop slave; reset slave all;” |
mysql -S /data/3309/mysql.sock -e “stop slave; reset slave all;” |
mysql -S /data/3310/mysql.sock -e “stop slave; reset slave all;” |
“` |
|
|
## mysql分佈式架構介紹 |
|
3.png |
分佈式架構介紹 |
|
|
|
## mycat基礎應用 |
|
“`bash |
|
|
|
range |
取模 |
枚舉 |
hash |
時間 |
等等 |
“` |
|
### 主要配置文件介紹 |
|
“`basic |
rule.xml |
schema.xml *****,主配置文件 |
server.xml |
log4j2.xml *** ,記錄日誌有關 |
*.txt |
“` |
|
|
## mycat安裝 |
|
### 安裝Mycat |
|
“`basic |
# 預先安裝Java運行環境 |
yum install -y java |
|
# 下載 |
Mycat-server-xxxxx.linux.tar.gz |
//dl.mycat.io/ |
|
# 解壓文件 |
[root@db01 application]# tar xf Mycat-server-1.6.7.1-release-20190627191042-linux.tar.gz |
|
# 軟件目錄結構 |
ls |
bin catlet conf lib logs version.txt |
|
# 啟動和連接 |
配置環境變量 |
vim /etc/profile.d/mycat.sh |
export PATH=/application/mycat/bin:$PATH |
source /etc/profile |
啟動 |
mycat start |
連接mycat: |
mysql -uroot -p123456 -h 127.0.0.1 -P8066 |
“` |
|
|
### 數據導入 |
|
“`basic |
# 這裡僅作為參考,也可以用其他數據 |
[root@db01 ~]# mysql -uroot -p123 |
mysql> source /root/world.sql; |
[root@db07 ~]# mysql -uroot -p123 |
mysql> source /root/world.sql; |
“` |
|
### mycat配置文件濃縮 |
|
“`basic |
# mycat配置文件有很多多餘的,可以進行濃縮 |
cd /application/mycat/conf |
mv schema.xml schema.xml.bak |
vim schema.xml |
|
|
<mycat:schema xmlns:mycat=”//io.mycat/“> |
|
|
|
|
select user() |
|
|
|
|
</mycat:schema> |
“` |
|
|
### 配置文件介紹 |
|
“`xml |
# 前期介紹: |
邏輯庫schema: |
|
|
|
數據節點: |
|
|
數據主機: |
|
select user() |
|
|
|
|
|
TESTDB:邏輯庫名 |
balance屬性 |
負載均衡類型,目前的取值有3種: |
1. balance=”0″, 不開啟讀寫分離機制,所有讀操作都發送到當前可用的writeHost上。 |
2. balance=”1″,全部的readHost與standby writeHost參與select語句的負載均衡,簡單的說, |
當雙主雙從模式(M1->S1,M2->S2,並且M1與 M2互為主備),正常情況下,M2,S1,S2都參與select語句的負載均衡。 |
3. balance=”2″,所有讀操作都隨機的在writeHost、readhost上分發。 |
|
writeType屬性 |
負載均衡類型,目前的取值有2種: |
1. writeType=”0″, 所有寫操作發送到配置的第一個writeHost, |
第一個掛了切到還生存的第二個writeHost,重新啟動後已切換後的為主,切換記錄在配置文件中:dnindex.properties . |
2. writeType=「1」,所有寫操作都隨機的發送到配置的writeHost,但不推薦使用 |
|
|
switchType屬性 |
-1 表示不自動切換 |
1 默認值,自動切換 |
2 基於MySQL主從同步的狀態決定是否切換 ,心跳語句為 show slave status |
datahost其他配置 |
|
|
|
maxCon=”1000″:最大的並發連接數 |
minCon=”10″ :mycat在啟動之後,會在後端節點上自動開啟的連接線程 |
|
tempReadHostAvailable=”1″ |
這個一主一從時(1個writehost,1個readhost時),可以開啟這個參數,如果2個writehost,2個readhost時 |
select user() 監測心跳 |
“` |
|
## Mycat使用 |
|
### 讀寫分離配置 |
|
“`xml |
vim schema.xml |
|
|
|
<mycat:schema xmlns:mycat=”//io.mycat/“> |
|
|
|
|
select user() |
|
|
|
|
</mycat:schema> |
|
重啟mycat |
mycat restart |
|
讀寫分離測試 |
mysql -uroot -p -h 127.0.0.1 -P8066 |
show variables like ‘server_id’; |
begin; |
show variables like ‘server_id’; |
|
總結: |
|
“` |
|
|
### 讀寫分離和高可用 |
|
“`xml |
[root@db01 conf]# mv schema.xml schema.xml.rw |
[root@db01 conf]# vim schema.xml |
|
|
|
<mycat:schema xmlns:mycat=”//io.mycat/“> |
|
|
|
|
select user() |
|
|
|
|
|
|
|
</mycat:schema> |
|
真正的 writehost:負責寫操作的writehost |
standby writeHost :和readhost一樣,只提供讀服務 |
|
當寫節點宕機後,後面跟的readhost也不提供服務,這時候standby的writehost就提供寫服務, |
後面跟的readhost提供讀服務 |
|
測試: |
mysql -uroot -p123456 -h 127.0.0.1 -P 8066 |
show variables like ‘server_id’; |
讀寫分離測試 |
mysql -uroot -p -h 127.0.0.1 -P8066 |
show variables like ‘server_id’; |
show variables like ‘server_id’; |
show variables like ‘server_id’; |
begin; |
show variables like ‘server_id’; |
對db01 3307節點進行關閉和啟動,測試讀寫操作 |
“` |
|
|
### 垂直分表 |
|
“`xml |
mv schema.xml schema.xml.ha |
vim schema.xml |
|
|
<mycat:schema xmlns:mycat=”//io.mycat/“> |
|
|
|
|
|
select user() |
|
|
|
|
|
|
|
|
select user() |
|
|
|
|
|
|
|
</mycat:schema> |
|
創建測試庫和表: |
[root@db01 conf]# mysql -S /data/3307/mysql.sock -e “create database taobao charset utf8;” |
[root@db01 conf]# mysql -S /data/3308/mysql.sock -e “create database taobao charset utf8;” |
[root@db01 conf]# mysql -S /data/3307/mysql.sock -e “use taobao;create table user(id int,name varchar(20))”; |
[root@db01 conf]# mysql -S /data/3308/mysql.sock -e “use taobao;create table order_t(id int,name varchar(20))” |
|
# 測試: |
可登陸到mycat中對表中插入數據,看是否對插入不同表時,數據放入到不同服務器中 |
“` |
|
|
### 分片(水平拆分) |
|
“`xml |
1.前期說明 |
分片:對一個”bigtable”,比如說t3表 |
|
(1)行數非常多,800w |
(2)訪問非常頻繁 |
|
分片的目的: |
(1)將大數據量進行分佈存儲 |
(2)提供均衡的訪問路由 |
|
分片策略: |
範圍 range 800w 1-400w 400w01-800w |
取模 mod 取餘數 |
枚舉 |
哈希 hash |
時間 流水 |
|
優化關聯查詢 |
全局表 |
ER分片 |
|
Copy |
2.配置操作 |
比如說t3表 |
(1)行數非常多,2000w(1-1000w:sh1 1000w01-2000w:sh2) |
(2)訪問非常頻繁,用戶訪問較離散 |
mv schema.xml schema.xml.1 |
vim schema.xml |
|
|
|
|
|
vim rule.xml |
|
|
id |
rang-long |
|
<function name=”rang-long” |
class=”io.mycat.route.function.AutoPartitionByLong”> |
autopartition-long.txt |
|
=================================== |
vim autopartition-long.txt |
0-10=0 |
11-20=1 |
|
創建測試表: |
mysql -S /data/3307/mysql.sock -e “use taobao;create table t3 (id int not null primary key auto_increment,name varchar(20) not null);” |
|
mysql -S /data/3308/mysql.sock -e “use taobao;create table t3 (id int not null primary key auto_increment,name varchar(20) not null);” |
|
測試: |
重啟mycat |
mycat restart |
mysql -uroot -p123456 -h 127.0.0.1 -P 8066 |
insert into t3(id,name) values(1,’a’); |
insert into t3(id,name) values(2,’b’); |
insert into t3(id,name) values(3,’c’); |
insert into t3(id,name) values(4,’d’); |
insert into t3(id,name) values(11,’aa’); |
insert into t3(id,name) values(12,’bb’); |
insert into t3(id,name) values(13,’cc’); |
insert into t3(id,name) values(14,’dd’); |
“` |
|
|
### 取模分片(mod-long) |
|
“`xml |
取余分片方式:分片鍵(一個列)與節點數量進行取余,得到餘數,將數據寫入對應節點 |
vim schema.xml |
vim rule.xml |
2 |
|
準備測試環境 |
|
創建測試表: |
mysql -S /data/3307/mysql.sock -e “use taobao;create table t4 (id int not null primary key auto_increment,name varchar(20) not null);” |
mysql -S /data/3308/mysql.sock -e “use taobao;create table t4 (id int not null primary key auto_increment,name varchar(20) not null);” |
|
重啟mycat |
mycat restart |
|
測試: |
mysql -uroot -p123456 -h10.0.0.52 -P8066 |
|
use TESTDB |
insert into t4(id,name) values(1,’a’); |
insert into t4(id,name) values(2,’b’); |
insert into t4(id,name) values(3,’c’); |
insert into t4(id,name) values(4,’d’); |
|
分別登錄後端節點查詢數據 |
mysql -S /data/3307/mysql.sock |
use taobao |
select * from t4; |
|
mysql -S /data/3308/mysql.sock |
use taobao |
select * from t4; |
“` |
|
|
### 枚舉分片 |
|
“`xml |
t5 表 |
id name telnum |
1 bj 1212 |
2 sh 22222 |
3 bj 3333 |
4 sh 44444 |
5 bj 5555 |
|
sharding-by-intfile |
vim schema.xml |
|
vim rule.xml |
|
name |
hash-int |
|
|
|
|
partition-hash-int.txt |
1 |
0 |
|
|
partition-hash-int.txt 配置: |
bj=0 |
sh=1 |
DEFAULT_NODE=1 |
columns 標識將要分片的表字段,algorithm 分片函數, 其中分片函數配置中,mapFile標識配置文件名稱 |
|
準備測試環境 |
mysql -S /data/3307/mysql.sock -e “use taobao;create table t5 (id int not null primary key auto_increment,name varchar(20) not null);” |
|
mysql -S /data/3308/mysql.sock -e “use taobao;create table t5 (id int not null primary key auto_increment,name varchar(20) not null);” |
重啟mycat |
mycat restart |
mysql -uroot -p123456 -h10.0.0.51 -P8066 |
use TESTDB |
insert into t5(id,name) values(1,’bj’); |
insert into t5(id,name) values(2,’sh’); |
insert into t5(id,name) values(3,’bj’); |
insert into t5(id,name) values(4,’sh’); |
insert into t5(id,name) values(5,’tj’); |
|
“` |
|
|
### Mycat全局表 |
|
“`xml |
a b c d |
join |
t |
|
select t1.name ,t.x from t1 |
join t |
select t2.name ,t.x from t2 |
join t |
select t3.name ,t.x from t3 |
join t |
|
# 使用場景: |
如果你的業務中有些數據類似於數據字典,比如配置文件的配置, |
常用業務的配置或者數據量不大很少變動的表,這些表往往不是特別大, |
而且大部分的業務場景都會用到,那麼這種表適合於Mycat全局表,無須對數據進行切分, |
要在所有的分片上保存一份數據即可,Mycat 在Join操作中,業務表與全局表進行Join聚合會優先選擇相同分片內的全局表join, |
避免跨庫Join,在進行數據插入操作時,mycat將把數據分發到全局表對應的所有分片執行,在進行數據讀取時候將會隨機獲取一個節點讀取數據。 |
|
vim schema.xml |
|
後端數據準備 |
mysql -S /data/3307/mysql.sock |
use taobao |
create table t_area (id int not null primary key auto_increment,name varchar(20) not null); |
|
mysql -S /data/3308/mysql.sock |
use taobao |
create table t_area (id int not null primary key auto_increment,name varchar(20) not null); |
|
重啟mycat |
mycat restart |
|
測試: |
mysql -uroot -p123456 -h10.0.0.52 -P8066 |
|
use TESTDB |
insert into t_area(id,name) values(1,’a’); |
insert into t_area(id,name) values(2,’b’); |
insert into t_area(id,name) values(3,’c’); |
insert into t_area(id,name) values(4,’d’); |
“` |
|
|
### E-R分片 |
|
“`xml |
A |
join |
B |
為了防止跨分片join,可以使用E-R模式 |
A join B |
on a.xx=b.yy |
join C |
on A.id=C.id |
|
“` |
|
1 |
|
|
|
|
|
|