背景:
簡單的分庫、分表有時候並不能有效抵擋大流量的查詢,除去緩存的存在,僅僅考慮數據庫層面上。可以搭建主從複製架構,可以使寫操作在主庫進行,主庫和從庫之間通過異步複製、半同步複製保持數據一致。所有的讀操作都在主庫的N個從庫上進行。通過負載均衡使得每一次查詢均勻的落在每一個從庫上
由於硬件資源有限,爲了模擬主從讀寫分離,在一臺機器上搭建多個MySQL實例,並配置主從關係。如果不知道怎麼部署、配置,可參考單機部署MySQL多實例和主從複製搭建
上一篇文章已經有了兩個主庫,3306、3310。爲3306實例部署兩個從庫,3307、3308。
Sharding-Jdbc讀寫分離也僅需要簡單的配置即可使用
一、配置文件修改:
server:
port: 8999
spring:
application:
name: mybatis-demo
shardingsphere:
datasource:
# 數據庫的別名
names: ds0,ds1,ds0-slave0,ds0-slave1
ds0:
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/dhb?serverTimezone=UTC
password: 12345
username: root
ds0-slave0:
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3307/dhb?serverTimezone=UTC
password: 12345
username: root
ds0-slave1:
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3308/dhb?serverTimezone=UTC
password: 12345
username: root
ds1:
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3310/dhb?serverTimezone=UTC
password: 12345
username: root
sharding:
# 默認分庫策略
default-database-strategy:
inline:
sharding-column: id
algorithm-expression: ds$->{id % 2}
# 默認分表策略
default-table-strategy:
inline:
sharding-column: age
algorithm-expression: user_$->{age % 2}
# 數據節點
tables:
user:
actual-data-nodes: ds$->{0..1}.user_$->{0..1}
# 默認數據庫
default-data-source-name: ds0
master-slave-rules:
ds0:
master-data-source-name: ds0
slave-data-source-names: ds0-slave0,ds0-slave1
#從庫負載均衡算法類型,可選值:ROUND_ROBIN,RANDOM。
#若`load-balance-algorithm-class-name`存在則忽略該配置
load-balance-algorithm-type: ROUND_ROBIN
#從庫負載均衡算法類名稱。該類需實現MasterSlaveLoadBalanceAlgorithm接口且提供無參數構造器
#load-balance-algorithm-class-name=
props:
# 打印SQL
sql.show: true
check:
table:
metadata:
# 是否在啓動時檢查分表元數據一致性
enabled: true
aop:
proxy-target-class: false
# 因爲Druid數據源和默認的數據源衝突,添加此配置
main:
allow-bean-definition-overriding: true
mybatis-plus:
configuration:
map-underscore-to-camel-case: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
db-config:
logic-not-delete-value: 0
logic-delete-value: 1
mapper-locations: classpath:/mapper/*.xml
typeAliasesPackage: com.example.mybatis.demomybatis.entity
讀寫分離主要配置在master-salve-rules配置下面,關於讀數據時的從庫負載均衡策略可使用 ROUND_ROBIN、RANDOM兩種。如果這兩種不能滿足需求,還可以自定義負載均衡算法,實現MasterSlaveLoadBalanceAlogorithm接口。更多細節可參考官方讀寫分離文檔部分
二、測試:
分別進行四次查詢,可以看到sharding-jdbc每一次都是在兩個從庫之間切換,如下圖:
總的來說,無論是數據分片、還是讀寫分離,sharding-sphere都幫我們屏蔽了底層細節,並且讓我們使用起來就像對單表操作一樣。特別方便
疑惑:
在讀寫分離時,第一次的查詢總是很慢,目前還不知道什麼原因,哪位同學知道原因希望留言一下,十分感謝!
示例代碼已放到GitHub上,如有需要,請自取。示例代碼地址