文章目錄
一、數據切分
數據切分,簡單的說,就是通過某種條件,將我們之前存儲在一臺數據庫上的數據,分散到多臺數據庫中,從而達到降低單臺數據庫負載的效果。數據切分,根據其切分的規則,大致分爲兩種類型:
- 垂直切分
- 水平切分
1、垂直切分
垂直切分就是按照不同的表或者Schema切分到不同的數據庫中,比如:在我們的課程中,訂單表(order)和商品表(product)在同一個數據庫中,而我們現在要對其切分,使得訂單表(order)和商品表(product)分別落到不同的物理機中的不同的數據庫中,使其完全隔離,從而達到降低數據庫負載的效果。
一句話概括:將不同的業務數據放到不同的庫中
垂直切分的特點就是規則簡單,易於實施,可以根據業務模塊進行劃分,各個業務之間耦合性低,相互影響也較小。
一個架構設計較好的應用系統,其總體功能肯定是有多個不同的功能模塊組成的。每一個功能模塊對應着數據庫裏的一系列表。
意味着垂直拆分往往伴隨着,系統程序分佈式化、微服務化,當然單機的項目一般情況下也是用不到分庫分表的。
在架構設計中,各個功能模塊之間的交互越統一、越少越好。這樣,系統模塊之間的耦合度會很低,各個系統模塊的可擴展性、可維護性也會大大提高。這樣的系統,實現數據的垂直切分就會很容易。
但是,在實際的系統架構設計中,有一些表很難做到完全的獨立,往往存在跨庫join的現象。比如我們接到了一個需求,要求查詢某一個類目產生了多少訂單,如果在單體數據庫中,我們直接連表查詢就可以了。但是現在垂直切分成了兩個數據庫,跨庫連表查詢是十分影響性能的,也不推薦這樣用,只能通過接口去調取服務,這樣系統的複雜度又升高了。
優點:
- 拆分後業務清晰,拆分規則明確;
- 系統之間容易擴展和整合;
- 數據維護簡單
缺點:
- 部分業務表無法join,只能通過接口調用,提升了系統的複雜度;
- 跨庫事務難以處理;
- 垂直切分後,某些業務數據過於龐大,仍然存在單體性能瓶頸;
2、水平切分
水平切分相比垂直切分,更爲複雜。它需要將一個表中的數據,根據某種規則拆分到不同的數據庫中,例如:訂單尾號爲奇數的訂單放在了訂單數據庫1中,而訂單尾號爲偶數的訂單放在了訂單數據庫2中。這樣,原本存在一個數據庫中的訂單數據,被水平的切分成了兩個數據庫。在查詢訂單數據時,我們還要根據訂單的尾號,判斷這個訂單在數據庫1中,還是在數據庫2中,然後將這條SQL語句發送到正確的數據庫中,查出訂單。
優點:
- 解決了單庫大數據、高併發的性能瓶頸;
- 拆分規則封裝好,對應用端幾乎透明,開發人員無需關心拆分細節;
- 提高了系統的穩定性和負載能力;
缺點:
- 拆分規則很難抽象;
- 分片事務一致性難以解決;
- 二次擴展時,數據遷移、維護難度大。比如:開始我們按照用戶id對2求模,但是隨着業務的增長,2臺數據庫難以支撐,還是繼續拆分成4個數據庫,那麼這時就需要做數據遷移了。
3、分庫分表的兩種模式
- 客戶端模式,在每個應用模塊內,配置自己需要的數據源,直接訪問數據庫,在各模塊內完成數據的整合;例如:sharding-jdbc
- 中間代理模式,中間代理統一管理所有的數據源,數據庫層對開發人員完全透明,開發人員無需關注拆分的細節。例如:MyCat
二、使用MyCat分庫分表
1、系統環境
- 使用VMware做虛擬機,創建3臺機器
- 操作系統使用Linux CentOS7
- 採用yum方式,在兩臺機器上安裝mysql
- 在第三臺機器上安裝MyCat,並修改配置文件
2、mysql安裝
(1)下載mysql的yum引導
下載地址:
https://dev.mysql.com/downloads/repo/yum/
注意選擇對應的linux版本,這裏採用linux7的,mysql 版本是8.0
(2)將文件上傳到linux系統上
(3)安裝mysql
yum localinstall mysql80-community-release-el7-3.noarch.rpm
yum install mysql-community-server
(4)啓動mysql
service mysqld start
(5)查詢登錄的默認密碼
查詢結果最後一個冒號之後的就是密碼
grep 'temporary password' /var/log/mysqld.log
(6)登錄mysql
mysql -uroot -p
然後輸入密碼
(7)修改默認密碼
ALTER USER 'root'@'localhost' IDENTIFIED BY '這裏想要的密碼';
修改的密碼需要複雜一點,一個大寫字母、一個小寫字母、一個數字和一個特殊字符,並且密碼的總長度至少爲8個字符,否則不符合密碼策略無法修改成功
(8)創建用戶並授權
創建用戶
由於我們使用的是mysql8,密碼的默認加密方式改變Navicat無法連接,需要指定爲老的加密方式:identified with mysql_native_password
當我們指定了老的加密方式後,控制檯的客戶端連接時需要指定連接的加密方式:mysql -uroot -p --default-auth=mysql_native_password
create user '用戶名'@'%' identified with mysql_natice_password by '密碼';
授權所有權限
grant all on *.* to '用戶名'@'%';
然刷新一下配置
flush privileges;
如果還是無法連接,嘗試關閉linux的防火牆
3、mycat安裝
(1)下載地址
dl.mycat.io/1.6.7.3
(2)將文件上傳到linux系統上
(3)解壓壓縮包
tar -zxvf Mycat-server-1.6.7.3-release-20190828135747-linux.tar.gz
(4)修改server.xml
進入mycat根目錄下的
vim config/server.xml
將root的schemas屬性改成user
<user name="root" defaultAccount="true">
<property name="password">123456</property>
<property name="schemas">user</property>
</user>
下面還有個user的配置可以直接刪掉,或者把schemas屬性也改成user
(5)修改schema.xml
vim config/schema.xml
配置分鍵表
<!-- 這個name要和server.xml配置中的schemas屬性一致 />
<!-- sqlMaxLimit會默認在查詢語句之後添加limit,防止一下查詢多個庫,數據量過大,想要額外查詢需要自己添加limit />
<schema name="user" checkSQLschema="true" sqlMaxLimit="100">
<table name="表名" dataNode="dn200,dn201" rule="auto-sharding-long">
</schema>
配置數據節點
<!-- dataHost需要和下面的配置的dataHost的name屬性一致 />
<dataNode name="dn200" dataHost="db200" database="庫名">
<dataNode name="dn201" dataHost="db201" database="庫名">
修改dataHost
<!-- 配置第一個數據 />
<!-- balance:負載均衡類型:0不開啓讀寫分離,1和2讀寫均勻分配,3讀落在readHast上 />
<dataHost name="db200" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<!-- 添加一個寫庫 />
<writeHost host="M1" url="192.168.85.200:3306" user="用戶名" password="密碼">
<!-- 添加一個讀庫 ,讀寫分離的時候使用,佔時不需要 />
<!-- <readHost host="S1" url="192.168.85.203" user="用戶名" password="密碼"> />
</writeHost>
</dataHost>
<!-- 配置第二個數據 />
<dataHost name="db201" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<!-- 添加一個寫庫 />
<writeHost host="M2" url="192.168.85.201:3306" user="用戶名" password="密碼">
</writeHost>
</dataHost>
(6)修改分鍵規則
在schema.xml中配置的分鍵規則爲"auto-sharding-long"查看rule.xml,找到對應的規則
<tableRule name="auto-sharding-long">
<rule>
#分鍵的字段爲id,就是表中必須有一個名爲id的字段
<columns>id</columns>
<algorithm>rang-long</algorithm>
</rule>
</tableRule>
看配置可以知道分鍵規則的計算方式爲"algorithm",在文件的下面找到對應的計算方式
<function name="rang-long" class="io.mycat.route.function.AutoPartitionByLong">
<property name="mapFile">autopartition-long.txt</property>
</function>
具體的執行的類叫AutoPartitionByLong,配置文件叫autopartition-long.txt,在config目錄下可以找到autopartition-long.txt,打開文件,並刪除掉最後一行
#rang start-end,data node index
# K=1000,M=10000
0-500M=0
500M-1000M=1
這裏的意思是,id在0-500*10000的時候放到第一個庫,500*10000-1000*10000的時候放在第二個庫,並且這裏的規則要和schema.xml中配置的dataNode的數量一致
(7)在mysql中創建庫和表
- 創建庫的時候,庫名需要和 schema.xml配置文件中dataNode的database屬性一致
- 創建表的時候,表名需要和 schema.xml配置文件中schema下的table裏的name屬性一致
(8)啓動mycat
#所有信息打到控制檯
./bin/mycat console
#後臺啓動
./bin/mycat start
(9)使用Navicat進行連接
直接創建一個mysql的連接
連接地址:填寫mycat的地址,我這裏爲192.168.85.202
端口:8066(mycat默認端口)
用戶名:root(用戶名密碼都配置在server.xml中)
密碼:123456
插入數據測試一下,可以根據id的規則分別插入不同的數據,再去對應的mysql裏面查看數據是否分庫成功
(10)使用Navicat連接mycat管理
直接創建一個mysql的連接
連接地址:填寫mycat的地址,我這裏爲192.168.85.202
端口:9066(mycat管理端口)
用戶名:root(用戶名密碼都配置在server.xml中)
密碼:123456
這裏面有個user庫,雙擊是打不開的右鍵連接-》命令列介面,不要右鍵庫,
#幫助
show @@help;
#刷新配置 這樣就不用重啓mycat,就能更變配置了
reload @@config_all;
4、mysql主從配置
(1)修改主配置文件
主機地址:192.168.85.200
打開mysql的配置文件
vim /etc/my.cnf
在mysqld添加兩個配置
log-bin=test_mysql
server-id=1
重啓mysql
service mysqld restart
(2)修改從配置文件
從機地址:192.168.85.204
打開mysql的配置文件
vim /etc/my.cnf
在mysqld添加兩個配置
server-id=2
重啓mysql
service mysqld restart
(3)主創建備份賬號並授權REPLICATION SLAVE
主機上登錄mysql客戶端
mysql -uroot -p
創建replication的賬號
create user 'repl'@'%' identified by '密碼';
進行授權
grant replication slave on *.* to 'repl'@'%';
刷新權限
flush privileges;
(4)主進行鎖表,用於向從庫同步數據,鎖表之後就無法進行寫操作
主數客戶端控制檯中進行鎖表
flush tables with read lock;
查詢bin-log的日誌定位,查詢出來的東西需要記住,後面配置需要使用
show master status;
(5)主庫原本就有的數據需要手動的複製到從庫中
備份主庫數據
複製一個新的會話界面,在linux下執行下面語句,之前的mysql客戶端不能關閉,關閉後會釋放表鎖
在當前文件夾下會生成dbdump.db文件,根據數據量大小,執行時間會有所不同,可能會很長時間
mysqldump --all-databases --master-data > dbdump.db -uroot -p
將dbdump.db複製到從機上,什麼方法都行復制過去就可以了,我這裏使用scp命令
scp [email protected]:~/dbdump.db .
將數據還原到從數據庫中,從數據原本的數據會被覆蓋掉
mysql < dbdump.db -uroot -p
(6)解鎖主庫的表鎖
在主機mysql的客戶端裏輸入
unlock tables;
(7)在從上設置主的配置
在從機mysql的客戶端裏輸入
CHANGE MASTER TO
MASTER_HOST='主機ip地址',
MASTER_USER='主從同步的用戶(這裏是repl)',
MASTER_PASSWORD='密碼',
MASTER_LOG_FILE='第四部要記住的file名稱',
MASTER_LOG_POS=第四部要記住的Positon(這裏沒有單引號的);
完整的如下
CHANGE MASTER TO
MASTER_HOST='192.168.85.200',
MASTER_USER='repl',
MASTER_PASSWORD='123456',
MASTER_LOG_FILE='test-mysql.000001',
MASTER_LOG_POS=1460;
然後激活從庫
start slave;
mysql的主從搭建完成!!
(8)mycat配置讀寫分離
修改schema.xml
vim config/schema.xml
修改dataHost
<!-- balance:負載均衡類型:0不開啓讀寫分離,1和2讀寫均勻分配,3讀落在readHast上 />
<!-- 這裏的balance改成 1,2,3都沒有問題>
<dataHost name="db200" maxCon="1000" minCon="10" balance="3" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<!-- 添加一個寫庫 />
<writeHost host="M1" url="192.168.85.200:3306" user="用戶名" password="密碼">
<!-- 添加一個讀庫/>
<readHost host="S1" url="192.168.85.204" user="用戶名" password="密碼"> />
</writeHost>
</dataHost>
連接的時候需要連接的mycat,這樣寫入操作mycat會分配給192.168.85.200來完成,然後192.168.85.200通過mysql的主從功能將數據同步給192.168.85.204,讀操作mycat全部分配給192.168.85.204
5、mycat全局表和父子表
(1)全局表
在分片的情況下,當業務表因爲規模而進行分片以後,業務表與這些附屬的字典表之間的關聯,就成了比較棘手的問題,考慮到字典表具有以下幾個特性:
• 變動不頻繁
• 數據量總體變化不大
• 數據規模不大,很少有超過數十萬條記錄。
鑑於此,MyCAT 定義了一種特殊的表,稱之爲“全局表”,全局表具有以下特性:
• 全局表的插入、更新操作會實時在所有節點上執行,保持各個分片的數據一致性
• 全局表的查詢操作,只從一個節點獲取
• 全局表可以跟任何一個表進行 JOIN 操作
打開schema.xml
vim schema.xml
再添加一個table標籤
<table name="表名" dataNode="dn200,dn201" type="global" />
type爲global的就是全局表
(2)父子表
在實際工作中經常會遇到父子級表或者叫詳情表,例如:訂單表和訂單詳情表,但是分庫分表後,很有可能父表信息錄入到了db1中,而子表信息錄入進了db2中,這樣就無法join查詢了,mycat考慮到了這個問題,提供了父子表關係建立,讓父子表的數據錄入到同一個庫中。
創建兩張表,所有的數據庫中都要創建
o_order表(order是關鍵字,這裏使用o_order):
字段 | 中文解釋 |
---|---|
id | id |
total_amount | 價格 |
order_status | 訂單狀態 |
order_item表:
字段 | 中文解釋 |
---|---|
id | id |
order_id | order表的id |
product_name | 商品名稱 |
num | 購買數量 |
修改mycat配置,打開schema.xml
vim schema.xml
再添加一個table標籤
<table name="o_order" dataNode="dn200,dn201" type="auto-sharding-long">
<childTable name="order_item" joinKey="order_id" parentKey="id"/>
</table>
三、MyCat-Ha
1、mycat高可用架構圖
2、mycat高可用架構搭建
(1)在兩臺機器上安裝mycat
我這裏安裝的機器ip分別爲:192.168.85.205和192.168.85.206
配置保持一致
(2)在兩臺機器上安裝haproxy
我這裏安裝的機器ip分別爲:192.168.85.210和192.168.85.211
#查詢
yum search haproxy
#安裝
yum -y install haproxy x86_64
修改配置文件
vim /etc/haproxy/haproxy.cfg
修改以下的配置,其他的保持不變
defaults
mode tcp
option tcplog
#option http-server-close
#option forwardfor except 127.0.0.0/8
....
#這個5000是連接端口號
frontend main *:5000
#ac | url_static path_beg -i /static /images /javascript /stylesheets
#ac | url_static path_end -i .jpg .gif .png .css .js
#這個是使用http的時候的配置,對應下方的backend static
#use_backend static if url_static
#這個是使用tcp的時候的配置,對應下方的backend app
default_packend app
...
#配置連接的mycat
backend app
balance roundrobin
server app1 192.168.85.205:8066 check
server app2 192.168.85.206:8066 check
啓動haproxy,會爆一些警告無所謂
haproxy -f /etc/haproxy/haproxy.cfg
(3)在兩臺機器上安裝keepalived
安裝keepalived,這裏簡單的安裝一下
詳細的可以參考,裏面有詳細的keepalived安裝和說明:
https://blog.csdn.net/qq_34886352/article/details/103581973
#搜索
yum search keepalived
#安裝
yum -y install keepalived.x86_64
修改keepalived配置文件
vim /etc/keepalived/keepalived.conf
註釋掉vrrp_strict
#vrrp_strict
配置master節點
這裏添加一個監聽haproxy進程的腳本
vrrp_script chk_happroxy{
#檢測使用的語句 不存在返回1 存在返回0
script "killall -0 haproxy"
#兩秒檢測一次
interval 2
}
#多餘的vrrp_instance刪除掉
vrrp_instance VI_1{
state MASTER
#網卡 這個需要自己查一下自己的網卡,推薦的文章裏面有說明
interface etc33
...(這些都不用改)
virtual_ipaddress{
192.168.85.20
}
#添加監聽
track_script{
chk_haproxy
}
}
#多餘的virtual_server刪除掉
virtual_server 192.168.85.20 6000{
...(這些都不用改)
#對應的真實的主機的地址
real_server 192.168.85.210 5000{
weight 1
TCP_CHECK{
connect_port 5000
connect_timeout 10000
}
}
}
配置slave節點
這裏添加一個監聽haproxy進程的腳本
vrrp_script chk_happroxy{
#檢測使用的語句 不存在返回1 存在返回0
script "killall -0 haproxy"
#兩秒檢測一次
interval 2
}
#多餘的vrrp_instance刪除掉
vrrp_instance VI_1{
state SLAVE
#網卡 這個需要自己查一下自己的網卡,推薦的文章裏面有說明
interface etc33
...(這些都不用改)
virtual_ipaddress{
192.168.85.20
}
#添加監聽
track_script{
chk_haproxy
}
}
#多餘的virtual_server刪除掉
virtual_server 192.168.85.20 6000{
...(這些都不用改)
#對應的真實的主機的地址
real_server 192.168.85.211 5000{
weight 1
TCP_CHECK{
connect_port 5000
connect_timeout 10000
}
}
}
啓動keepalived
keepalived -f /ect/keepalived/keepalived.conf
#或者
service keepalived start
(4)使用Navicat連接keepalived的虛擬ip
直接創建一個mysql的連接
連接地址:192.168.85.20(keepalivd的虛擬ip)
端口:6000(keepalived的監聽端口)
用戶名:root(用戶名密碼都配置在mycat的server.xml中)
密碼:123456
四、基於Sharding-JDBC的讀寫分離和分庫分表
官方文檔:https://shardingsphere.apache.org/document/current/cn/quick-start/sharding-jdbc-quick-start/
Sharding-JDBC是ShardingSphere的第一個產品,也是ShardingSphere的前身。 它定位爲輕量級Java框架,在Java的JDBC層提供的額外服務。它使用客戶端直連數據庫,以jar包形式提供服務,無需額外部署和依賴,可理解爲增強版的JDBC驅動,完全兼容JDBC和各種ORM框架。
每個庫都創建2個t_order表,分別叫做t_order_1和t_order_2
t_order表:
字段 | 中文解釋 |
---|---|
order_id | 訂單id |
total_amount | 價格 |
order_status | 訂單狀態 |
user_id | 用戶id |
1、Spring整合sharding-jdbc
(1)引入maven依賴
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-namespace</artifactId>
<version>4.0.0-RC2</version>
</dependency>
(2)springxml的配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:sharding="http://shardingsphere.apache.org/schema/shardingsphere/sharding"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://shardingsphere.apache.org/schema/shardingsphere/sharding
http://shardingsphere.apache.org/schema/shardingsphere/sharding/sharding.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 添加數據源 -->
<bean id="ds0" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
<!-- 數據庫驅動 -->
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver" />
<property name="username" value="用戶名"/>
<property name="password" value="密碼"/>
<property name="jdbcUrl" value="jdbc:mysql://192.168.85.200:3306/sharding_order?serverTimezone=Asia/Shanghai&useSSL=false"/>
</bean>
<!-- 第二個數據源 -->
<bean id="ds1" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
<!-- 數據庫驅動 -->
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver" />
<property name="username" value="用戶名"/>
<property name="password" value="密碼"/>
<property name="jdbcUrl" value="jdbc:mysql://192.168.85.201:3306/sharding_order?serverTimezone=Asia/Shanghai&useSSL=false"/>
</bean>
<!-- 配置sharding-jdbc -->
<sharding:data-source id="sharding-data-source">
<!-- 配置數據源 -->
<sharding:sharding-rule data-source-name="ds0,ds1">
<sharding:table-rules>
<!-- logic-table :分片表的邏輯表名 -->
<!-- atcual-data-nodes :實際的數據節點 ds$->{0..1}:分爲兩個部分ds是數據源的前綴,$->{0..1}是佔位符,等同於${} -->
<!-- database-strategy-ref :庫的分片策略 -->
<!-- table-strategy-ref :表的分片策略 -->
<sharding:table-rule logic-table="t_order"
atcual-data-nodes="ds$->{0..1}.t_order_$->{1..2}"
database-strategy-ref="databaseStrategy"
table-strategy-ref="tableStrategy"
/>
</sharding:table-rules>
</sharding:sharding-rule>
</sharding:data-source>
<!-- 數據庫的分片規則 -->
<!-- sharding-column:分庫使用的字段 -->
<!-- algorithm-expression:分片規則,對user_id取模 -->
<sharding:inline-strategy id="databaseStrategy" sharding-column="user_id" algorithm-expression="ds$->{user_id%2}"/>
</beans>
<!-- 表的分片規則 -->
<sharding:inline-strategy id="tableStrategy" sharding-column="id" algorithm-expression="t_order_$->{id%2+1}"/>
<bean class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="sharding-data-source"/>
<property name="mapperLocations" value="classpath*:/mybatis/*.xml"/>
</bean>
</beans>
(3)mybatis的注意事項
mybatis的xml文件裏的表需要使用邏輯表名
- @MapperScan不要忘記加了,不知道的回頭看看mybatis的配置
- 和正常使用mybatis一樣就行了,會自動的去識別分庫分表
2、SpringBoot整合sharding-jdbc
(1)引入maven依賴
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
<version>4.0.0-RC2</version>
</dependency>
(2)application.properties配置
spring.shardingsphere.datasource.names=ds0,ds1
spring.shardingsphere.datasource.ds0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds0.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds0.jdbcUrl=jdbc:mysql://192.168.85.200:3306/sharding_order?serverTimezone=Asia/Shanghai&useSSL=false
spring.shardingsphere.datasource.ds0.username=
spring.shardingsphere.datasource.ds0.password=
spring.shardingsphere.datasource.ds1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds1.jdbcUrl=jdbc:mysql://192.168.85.201:3306/sharding_order?serverTimezone=Asia/Shanghai&useSSL=false
spring.shardingsphere.datasource.ds1.username=
spring.shardingsphere.datasource.ds1.password=
spring.shardingsphere.sharding.tables.t_order.actual-data-nodes=ds$->{0..1}.t_order_$->{1..2}
spring.shardingsphere.sharding.tables.t_order.database-strategy.inline.sharding-column=user_id
spring.shardingsphere.sharding.tables.t_order.database-strategy.inline.algorithm-expression=ds$->{user_id%2}
spring.shardingsphere.sharding.tables.t_order.table-strategy.inline.sharding-column=id
spring.shardingsphere.sharding.tables.t_order.table-strategy.inline.algorithm-expression=t_order_$->{id % 2+1}
mybatis.mapper-locations=/mybatis/*.xml
logging.pattern.dateformat=HH:mm:ss
3、廣播表(全局表)配置
(1)創建表
所有數據庫都創建一個地址表
字段 | 中文解釋 |
---|---|
id | id |
name | 地區名 |
(2)設置廣播表
spring修改xml文件
<!-- 配置sharding-jdbc -->
<sharding:data-source id="sharding-data-source">
<!-- 配置數據源 -->
<sharding:sharding-rule data-source-name="ds0,ds1">
<sharding:table-rules>
<!-- logic-table :分片表的邏輯表名 -->
<!-- atcual-data-nodes :實際的數據節點 ds$->{0..1}:分爲兩個部分ds是數據源的前綴,$->{0..1}是佔位符,等同於${} -->
<!-- database-strategy-ref :庫的分片策略 -->
<!-- table-strategy-ref :表的分片策略 -->
<sharding:table-rule logic-table="t_order"
atcual-data-nodes="ds$->{0..1}.t_order_$->{1..2}"
database-strategy-ref="databaseStrategy"
table-strategy-ref="tableStrategy"
/>
</sharding:table-rules>
<!-- 這裏就是廣播表的配置 -->
<sharding:broadcast-table-rules>
<sharding:broadcast-table-rule table="area"/>
</sharding:broadcast-table-rules>
</sharding:sharding-rule>
</sharding:data-source>
springboot,修改application.properties配置
# 添加廣播表配置
spring.shardingsphere.sharding.broadcast-tables=area
這樣在插入和修改的時候,就會同時更新所有庫中的這張表,也可以進行join查詢了
4、綁定表(父子表)配置
(1)創建表
所有數據庫都創建2個t_order_item表,分別叫做t_order_item_1和t_order_item_2
字段 | 中文解釋 |
---|---|
id | id |
order_id | 訂單表id |
pruduct_name | 商品名 |
user_id | 用戶id |
(2)設置綁定表
spring修改xml文件
<!-- 配置sharding-jdbc -->
<sharding:data-source id="sharding-data-source">
<!-- 配置數據源 -->
<sharding:sharding-rule data-source-name="ds0,ds1">
<sharding:table-rules>
<!-- logic-table :分片表的邏輯表名 -->
<!-- atcual-data-nodes :實際的數據節點 ds$->{0..1}:分爲兩個部分ds是數據源的前綴,$->{0..1}是佔位符,等同於${} -->
<!-- database-strategy-ref :庫的分片策略 -->
<!-- table-strategy-ref :表的分片策略 -->
<sharding:table-rule logic-table="t_order"
atcual-data-nodes="ds$->{0..1}.t_order_$->{1..2}"
database-strategy-ref="databaseStrategy"
table-strategy-ref="tableStrategy"
/>
</sharding:table-rules>
<!-- 這裏就是廣播表的配置 -->
<sharding:broadcast-table-rules>
<sharding:broadcast-table-rule table="area"/>
</sharding:broadcast-table-rules>
<!-- 這裏就是綁定表的配置 ,與mycat不同,sharding-jdbc 不需要指定,關聯關係的字段,是通過兩種表之間相同的字段進行關聯的-->
<sharding:binding-table-rules>
<sharding:binding-table-rule logic-tables="t_order,t_order_item"/>
</sharding:binding-table-rules>
</sharding:sharding-rule>
</sharding:data-source>
這裏可能會有個bug,會提示廣播表爲空,主要原因是因爲在初始化幫點表的時候,會檢測是否同時是廣播表,但是廣播表尚未初始化,就會拋出空指針
如果以後問題解決,這裏我再補上
5、讀寫分離
(1)springxml的配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:sharding="http://shardingsphere.apache.org/schema/shardingsphere/sharding"
xmlns:master-slave="http://shardingsphere.apache.org/schema/shardingsphere/masterslave"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://shardingsphere.apache.org/schema/shardingsphere/sharding
http://shardingsphere.apache.org/schema/shardingsphere/sharding/sharding.xsd
http://shardingsphere.apache.org/schema/shardingsphere/masterslave
http://shardingsphere.apache.org/schema/shardingsphere/masterslave/master-slave.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 添加數據源 -->
<bean id="ds0" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
<!-- 數據庫驅動 -->
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver" />
<property name="username" value="用戶名"/>
<property name="password" value="密碼"/>
<property name="jdbcUrl" value="jdbc:mysql://192.168.85.200:3306/sharding_order?serverTimezone=Asia/Shanghai&useSSL=false"/>
</bean>
<!-- 添加一個從數據源 -->
<bean id="slave0" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
<!-- 數據庫驅動 -->
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver" />
<property name="username" value="用戶名"/>
<property name="password" value="密碼"/>
<property name="jdbcUrl" value="jdbc:mysql://192.168.85.203:3306/sharding_order?serverTimezone=Asia/Shanghai&useSSL=false"/>
</bean>
<!-- 第二個數據源 -->
<bean id="ms1" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
<!-- 數據庫驅動 -->
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver" />
<property name="username" value="用戶名"/>
<property name="password" value="密碼"/>
<property name="jdbcUrl" value="jdbc:mysql://192.168.85.201:3306/sharding_order?serverTimezone=Asia/Shanghai&useSSL=false"/>
</bean>
<!-- 主從的讀寫規則 random:在所有的從庫中隨機查詢-->
<master-slave:load-balance-algorithm id="msStrategy" type="random">
<!-- 配置sharding-jdbc -->
<sharding:data-source id="sharding-data-source">
<!-- 配置數據源 -->
<sharding:sharding-rule data-source-name="ds0,slave0,ds1">
<!-- 主從配置 -->
<sharding:master-slave-rules>
<sharding:master-slave-rule id="ms0" master-data-source-name="ds0" slave-data-source-names="slave0" strategy-ref="msStrategy"/>
</sharding:master-slave-rules>
<sharding:table-rules>
<sharding:table-rule logic-table="t_order"
atcual-data-nodes="ms$->{0..1}.t_order_$->{1..2}"
database-strategy-ref="databaseStrategy"
table-strategy-ref="tableStrategy"
/>
</sharding:table-rules>
</sharding:sharding-rule>
</sharding:data-source>
<!-- 數據庫的分片規則 -->
<!-- sharding-column:分庫使用的字段 -->
<!-- algorithm-expression:分片規則,對user_id取模 -->
<sharding:inline-strategy id="databaseStrategy" sharding-column="user_id" algorithm-expression="ms$->{user_id%2}"/>
</beans>
<!-- 表的分片規則 -->
<sharding:inline-strategy id="tableStrategy" sharding-column="id" algorithm-expression="t_order_$->{id%2+1}"/>
<bean class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="sharding-data-source"/>
<property name="mapperLocations" value="classpath*:/mybatis/*.xml"/>
</bean>
</beans>
(2)springboot,修改application.properties配置
spring.shardingsphere.datasource.names=ds0,ms1,slave0
spring.shardingsphere.datasource.ds0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds0.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds0.jdbcUrl=jdbc:mysql://192.168.85.200:3306/sharding_order?serverTimezone=Asia/Shanghai&useSSL=false
spring.shardingsphere.datasource.ds0.username=
spring.shardingsphere.datasource.ds0.password=
spring.shardingsphere.datasource.slave0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.slave0.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.slave0.jdbcUrl=jdbc:mysql://192.168.85.203:3306/sharding_order?serverTimezone=Asia/Shanghai&useSSL=false
spring.shardingsphere.datasource.slave0.username=
spring.shardingsphere.datasource.slave0.password=
spring.shardingsphere.datasource.ms1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ms1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ms1.jdbcUrl=jdbc:mysql://192.168.85.201:3306/sharding_order?serverTimezone=Asia/Shanghai&useSSL=false
spring.shardingsphere.datasource.ms1.username=
spring.shardingsphere.datasource.ms1.password=
spring.shardingsphere.sharding.master-slave-rules.ms0.master-data-source-name=ds0
spring.shardingsphere.sharding.master-slave-rules.ms0.slave-data-source-name=slave0
spring.shardingsphere.sharding.master-slave-rules.ms0.load-balance.algorithm-type=RANDOM
spring.shardingsphere.sharding.tables.t_order.actual-data-nodes=ms$->{0..1}.t_order_$->{1..2}
spring.shardingsphere.sharding.tables.t_order.database-strategy.inline.sharding-column=user_id
spring.shardingsphere.sharding.tables.t_order.database-strategy.inline.algorithm-expression=ms$->{user_id%2}
spring.shardingsphere.sharding.tables.t_order.table-strategy.inline.sharding-column=id
spring.shardingsphere.sharding.tables.t_order.table-strategy.inline.algorithm-expression=t_order_$->{id % 2+1}
mybatis.mapper-locations=/mybatis/*.xml
logging.pattern.dateformat=HH:mm:ss