Sharding-JDBC 讀寫分離和綁定表的使用


  面對日益增加的系統訪問量,數據庫的吞吐量面臨着巨大瓶頸。 對於同一時刻有大量並發讀操作和較少寫操作類型的應用系統來說,將數據庫拆分為主庫和從庫,主庫負責處理事務性的增刪改操作,從庫負責處理查詢操作,能夠有效的避免由數據更新導致的行鎖,使得整個系統的查詢性能得到極大的改善。

  通過一主多從的配置方式,可以將查詢請求均勻的分散到多個數據副本,能夠進一步的提升系統的處理能力。 使用多主多從的方式,不但能夠提升系統的吞吐量,還能夠提升系統的可用性,可以達到在任何一個數據庫宕機,甚至磁盤物理損壞的情況下仍然不影響系統的正常運行。

  讀寫分離的數據節點中的數據內容是一致的,而水平分片的每個數據節點的數據內容卻並不相同。將水平分片和讀寫分離聯合使用,能夠更加有效的提升系統的性能。

  Sharding-JDBC讀寫分離則是根據SQL語義的分析,將讀操作和寫操作分別路由至主庫與從庫。它提供透明化讀寫分離,讓使用方盡量像使用一個數據庫一樣使用主從數據庫集群。Sharding-JDBC不提供主從數據庫的數據同步功能,需要采用其他機制支持(如果使用MySQL,可以用MySQL本身提供的主從同步機制)。
    

 實現sharding-jdbc讀寫分離:

  修改分片規則:

# sharding-jdbc分片規則配置
# 數據源,新增s0,s0對應的是從庫
spring.shardingsphere.datasource.names = m0,m1,m2,s0

# s0數據源
spring.shardingsphere.datasource.s0.type = com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.s0.driver-class-name = com.mysql.jdbc.Driver
spring.shardingsphere.datasource.s0.url = jdbc:mysql://localhost:3307/user_db?useUnicode=true
spring.shardingsphere.datasource.s0.username = root
spring.shardingsphere.datasource.s0.password = root
...... # 主庫從庫邏輯數據源定義 ds0為user_db spring.shardingsphere.sharding.master
-slave-rules.ds0.master-data-source-name = m0 spring.shardingsphere.sharding.master-slave-rules.ds0.slave-data-source-names = s0 # 從庫有多個用逗號分隔 s0,s1,s2 #spring.shardingsphere.sharding.master-slave-rules.ds0.slave-data-source-names = s0,s1,s2 ...... # t_user分表策略,固定分配至m0的t_user真實表 #spring.shardingsphere.sharding.tables.t_user.actual-data-nodes = m0.t_user # t_user分表策略,固定分配至ds0的t_user真實表 spring.shardingsphere.sharding.tables.t_user.actual-data-nodes = ds0.t_user

  如果在水平分庫基礎上再進行讀寫分離,配置水平分庫策略需要注意:

# sharding-jdbc分片規則配置
# 數據源
spring.shardingsphere.datasource.names = m0,m00,m1,m2,s0,s00
# m0數據源
spring.shardingsphere.datasource.m0.type = com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m0.driver-class-name = com.mysql.jdbc.Driver
spring.shardingsphere.datasource.m0.url = jdbc:mysql://localhost:3306/user_db_1?useUnicode=true
spring.shardingsphere.datasource.m0.username = root
spring.shardingsphere.datasource.m0.password = root
# s0數據源 spring.shardingsphere.datasource.s0.type
= com.alibaba.druid.pool.DruidDataSource spring.shardingsphere.datasource.s0.driver-class-name = com.mysql.jdbc.Driver spring.shardingsphere.datasource.s0.url = jdbc:mysql://localhost:3307/user_db_1?useUnicode=true spring.shardingsphere.datasource.s0.username = root spring.shardingsphere.datasource.s0.password = root

# m00數據源 spring.shardingsphere.datasource.m00.type = com.alibaba.druid.pool.DruidDataSource spring.shardingsphere.datasource.m00.driver-class-name = com.mysql.jdbc.Driver spring.shardingsphere.datasource.m00.url = jdbc:mysql://localhost:3306/user_db_2?useUnicode=true spring.shardingsphere.datasource.m00.username = root spring.shardingsphere.datasource.m00.password = root

# s00數據源 spring.shardingsphere.datasource.s00.type = com.alibaba.druid.pool.DruidDataSource spring.shardingsphere.datasource.s00.driver-class-name = com.mysql.jdbc.Driver spring.shardingsphere.datasource.s00.url = jdbc:mysql://localhost:3307/user_db_2?useUnicode=true spring.shardingsphere.datasource.s00.username = root spring.shardingsphere.datasource.s00.password = root ...... # 主庫從庫邏輯數據源定義 ds0為user_db_1 spring.shardingsphere.sharding.master
-slave-rules.ds0.master-data-source-name = m0 spring.shardingsphere.sharding.master-slave-rules.ds0.slave-data-source-names = s0
# ds1為user_db_2
spring.shardingsphere.sharding.master-slave-rules.ds1.master-data-source-name = m00 spring.shardingsphere.sharding.master-slave-rules.ds1.slave-data-source-names = s00 ...... # 分庫策略 spring.shardingsphere.sharding.default-database-strategy.inline.sharding-column = user_id spring.shardingsphere.sharding.default-database-strategy.inline.algorithm-expression = ds$->{user_id % 2 + 1}
......

# 指定user_db表的主鍵生成策略
spring.shardingsphere.sharding.tables.user_db.key-generator.column = user_id
spring.shardingsphere.sharding.tables.user_db.key-generator.type = SNOWFLAKE
....... # 分表策略
spring.shardingsphere.sharding.tables.user_db.actual-data-nodes = ds$->{1..2}.user_db_$->{1..2}
spring.shardingsphere.sharding.tables.user_db.table-strategy.inline.sharding-column = user_id
spring.shardingsphere.sharding.tables.user_db.table-strategy.inline.algorithm-expression = t_order_$->{user_db % 2 + 1}

綁定表:
  指分片規則一致的主表和子表。例如: t_order 表和 t_order_item 表,均按照 order_id 分片,綁定表之間的分區鍵完全相同,則此兩張表互為綁定表關系。綁定表之間的多表關聯查詢不會出現笛卡爾積關聯,關聯查詢效率將大大提升。舉例說明,如果SQL為:

SELECT i.* FROM t_order o JOIN t_order_item i ON o.order_id=i.order_id WHERE o.order_id in (10,11);

  在不配置綁定表關系時,假設分片鍵 order_id 將數值10路由至第0片,將數值11路由至第1片,那么路由后的SQL應該為4條,它們呈現為笛卡爾積:

SELECT i.* FROM t_order_0 o JOIN t_order_item_0 i ON o.order_id=i.order_id WHERE o.order_id in(1011);
SELECT i.* FROM t_order_0 o JOIN t_order_item_1 i ON o.order_id=i.order_id WHERE o.order_id in(1011);
SELECT i.* FROM t_order_1 o JOIN t_order_item_0 i ON o.order_id=i.order_id WHERE o.order_id in(1011);
SELECT i.* FROM t_order_1 o JOIN t_order_item_1 i ON o.order_id=i.order_id WHERE o.order_id in(1011);

  在配置綁定表關系后,路由的SQL應該為2條:

SELECT i.* FROM t_order_0 o JOIN t_order_item_0 i ON o.order_id=i.order_id WHERE o.order_id in(1011);
SELECT i.* FROM t_order_1 o JOIN t_order_item_1 i ON o.order_id=i.order_id WHERE o.order_id in(1011);

  配置方式:

# 設置綁定表
spring.shardingsphere.sharding.binding-tables[0] = t_order,t_order_item

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM