[shardingsphere]分表分庫概念及實戰

產品簡介

什麼是分佈式數據庫

分佈式數據庫系統通常使用較小的計算機系統,每臺計算機可單獨放在一個地方,每臺計算機中都可能有DBMS(Database Management System)的一份完整拷貝副本,或者部分拷貝副本,並具有自己局部的數據庫,位於不同地點的許多計算機通過網絡互相連接,共同組成一個完整的、全局的邏輯上集中、物理上分佈的大型數據庫。

爲什麼要做分佈式數據存儲

傳統的將數據集中存儲至單一數據節點的解決方案,在性能可用性運維成本這三方面已經難於滿足互聯網的海量數據場景。
性能方面,由於關係型數據庫大多采用B+樹模型,導致數據量超過閾值的情況下,索引深度的增加導致磁盤IO訪問次數增加,導致查詢性能下降;同時高併發的訪問請求也使得集中式數據庫成爲系統最大的瓶頸。
可用性方面,服務化的無狀態能達到較小成本的隨意擴容,但是導致所有壓力都落在數據庫,單一架構甚至簡單的主從模式已經無力支撐。
運維成本方面考慮,當數據庫達到單一數據庫的閾值,對於DBA的運維壓力就會增大,數據備份時間、恢復時間都會隨着數據量增大變大,單一數據庫應把數據量控制在1TB範圍內。

什麼是ShardingSphere

shardingsphere定位爲關係型數據庫中間件透明化的數據庫代理端,旨在充分合理地在分佈式的場景下利用關係型數據庫的計算和存儲能力,而並非實現一個全新的關係型數據庫,提供封裝了數據庫二進制協議的服務端版本,用於完成對異構語言的支持。
目前提供MySQL/PostgreSQL版本,它可以使用任何兼容MySQL/PostgreSQL協議的訪問客戶端(如:MySQL Command Client, MySQL Workbench, Navicat等)操作數據。

產品架構

在這裏插入圖片描述

名詞解釋

SQL

邏輯表

水平拆分的數據庫表的相同邏輯和數據結構表的總稱。
例如:
醫院信息表被拆分爲biz_yy_info_0 ... biz_yy_info_9,他們對應的邏輯表爲biz_yy_info

真實表

在分片數據庫中真實存在的物理表。例如邏輯表中介紹的biz_yy_info_0...biz_yy_info_9

數據節點

數據源名稱和數據表組成的數據分片最小單元。例如ds_0.biz_yy_info_0

綁定表

指分片規則相同的主表和子表。例如兩張表,tbordertbperson,都按照同一個字段——person_id分片,因此這兩張表互爲綁定表。兩張綁定表在關聯時不會出現笛卡爾積,關聯效率較高。

廣播表

指所有分片數據源中都存在的表,表結構、數據在每個節點都完全一致。適用於數據量不大,需要與海量數據的表關聯的場景。

分片

分片鍵

用於分片的數據庫字段,用於將數據水平拆分的關鍵字段。sharding-sphere支持多個字段分片鍵。

分片算法(四種)

通過分片算法將數據分片,支持通過=>=<=><BETWEENIN分片。
注意:分片算法需要自行實現。
例如,下圖是我實現的一個分片算法。
在這裏插入圖片描述
在這裏插入圖片描述

  • 精確分片算法
    對應PreciseShardingAlgorithm,用於處理使用單一鍵作爲分片鍵的=IN進行分片的場景。需要配合StandardShardingStrategy使用。

  • 範圍分片算法
    對應RangeShardingAlgorithm,用於處理使用單一鍵作爲分片鍵的BETWEEN AND><>=<=進行分片的場景。需要配合StandardShardingStrategy使用。

  • 複合分片算法
    對應ComplexKeysShardingAlgorithm,用於處理使用多鍵作爲分片鍵進行分片的場景,包含多個分片鍵的邏輯較複雜,需要應用開發者自行處理其中的複雜度。需要配合ComplexShardingStrategy使用。

  • Hint分片算法
    對應HintShardingAlgorithm,用於處理使用Hint行分片的場景。需要配合HintShardingStrategy使用。

分片策略

包含分片鍵和分片算法,由於分片算法的獨立性,將其獨立抽離。真正可用於分片操作的是分片鍵 + 分片算法,也就是分片策略。

  • 標準分片策略
    對應StandardShardingStrategy。提供對SQL語句中的=,>, <, >=, <=, INBETWEEN AND的分片操作支持。StandardShardingStrategy只支持單分片鍵,提供PreciseShardingAlgorithmRangeShardingAlgorithm兩個分片算法。PreciseShardingAlgorithm是必選的,用於處理=IN的分片。RangeShardingAlgorithm是可選的,用於處理BETWEEN AND, >,<, >=, <=分片,如果不配置RangeShardingAlgorithm,SQL中的BETWEEN AND將按照全庫路由處理。
  • 複合分片策略
    對應ComplexShardingStrategy。複合分片策略。提供對SQL語句中的=, >,<, >=, <=, INBETWEEN AND的分片操作支持。ComplexShardingStrategy支持多分片鍵,由於多分片鍵之間的關係複雜,因此並未進行過多的封裝,而是直接將分片鍵值組合以及分片操作符透傳至分片算法,完全由應用開發者實現,提供最大的靈活度。
  • 行表達式分片策略
    對應InlineShardingStrategy。使用Groovy的表達式,提供對SQL語句中的=和IN的分片操作支持,只支持單分片鍵。對於簡單的分片算法,可以通過簡單的配置使用,從而避免繁瑣的Java代碼開發,如: t_user_$->{u_id % 8} 表示t_user表根據u_id模8,而分成8張表,表名稱爲t_user_0到t_user_7。
  • Hint分片策略
    對應HintShardingStrategy。通過Hint而非SQL解析的方式分片的策略。
  • 不分片策略
    對應NoneShardingStrategy。不分片的策略。

SQL Hint

對於分片字段非SQL決定,而由其他外置條件決定的場景,可使用SQL Hint靈活的注入分片字段。例:內部系統,按照員工登錄主鍵分庫,而數據庫中並無此字段。SQL Hint支持通過Java APISQL註釋(待實現)兩種方式使用。

配置

分片規則

分片規則配置的總入口。包含數據源配置、表配置、綁定表配置以及讀寫分離配置等。
在這裏插入圖片描述

數據源配置

真實數據源列表。
在這裏插入圖片描述

表配置

邏輯表名稱、數據節點與分表規則的配置。

數據節點配置

用於配置邏輯表與真實表的映射關係。可分爲均勻分佈自定義分佈兩種形式。

  • 均勻分佈
    指數據表在每個數據源內呈現均勻分佈的態勢,例如:
db0
  ├── t_order0 
  └── t_order1 
db1
  ├── t_order0 
  └── t_order1

那麼數據節點的配置如下:

db0.t_order0, db0.t_order1, db1.t_order0, db1.t_order1
  • 自定義分佈
    指數據表呈現有特定規則的分佈,例如:
db0
  ├── t_order0 
  └── t_order1 
db1
  ├── t_order2
  ├── t_order3
  └── t_order4

那麼數據節點的配置如下:

db0.t_order0, db0.t_order1, db1.t_order2, db1.t_order3, db1.t_order4

分片策略配置

對於分片策略存有數據源分片策略和表分片策略兩種維度。

  • 數據源分片策略
    對應於DatabaseShardingStrategy。用於配置數據被分配的目標數據源。

  • 表分片策略
    對應於TableShardingStrategy。用於配置數據被分配的目標表,該目標表存在與該數據的目標數據源內。故表分片策略是依賴與數據源分片策略的結果的。

兩種策略的API完全相同。

自增主鍵生成策略

通過在客戶端生成自增主鍵替換以數據庫原生自增主鍵的方式,做到分佈式主鍵無重複。內置的分佈式主鍵實現有UUIDSNOWFLAKE以及LEAF

編排治理

配置中心

集中實時的管理shardingsphere中的配置信息,默認支持zookeeper,其他可通過實現SPI接口實現。

數據脫敏

對敏感隱私數據信息的可靠保護手段。

讀寫分離

主庫

添加、更新以及刪除操作所使用的數據庫,目前僅支持單主庫。

從庫

查詢數據操作所使用的數據庫,可支持多從庫。

主從同步

主庫通過mysql/postgresql的同步配置,將數據異步的同步到從庫上面的操作(由於異步性可能導致主從庫技間的短暫不一致性)。

負載均衡策略

通過負載均衡策略將查詢疏導到不同的從庫

事務類型

本地事務

事務是解決數據併發操作處理的模型 ,旨在滿足多用戶(多線程、進程)對數據操作的場景下,依然能保證邏輯正確執行,狀態持久。
本地事務是相對於分佈式事務的一個概念。本地事務滿足A(Atomictiy)C(Consistency)I(Isolation)D(Durabilit)四個特性。

兩階段事務(XA)

兩階段事務提交採用的是X/OPEN組織所定義的DTP模型,通過抽象出來的AP(應用程序), TM(事務管理器), RM(資源管理器,通常是數據庫)的概念可以保證事務的強一致性。 其中TM和RM間採用XA的協議進行雙向通信。 與傳統的本地事務相比,XA事務增加了prepare階段,數據庫除了被動接受提交指令外,還可以反向通知調用方事務是否可以被提交。 因此TM可以收集所有分支事務的prepare結果,最後進行原子的提交,保證事務的強一致性。

柔性事務

互聯網場景下誕生,滿足基本可用(Basically Available)柔性狀態(Soft State)最終一致性(Eventual Consistency)的分佈式事務類型。

產品優勢

  • 上手容易,配置簡單

  • 提供封裝了數據庫二進制協議的服務端版本,可以使用任何兼容MySQL/PostgreSQL協議的訪問客戶端操作數據

  • 對於開發者無需在意後端的實現,僅需要將其作爲單個數據庫看待

  • 提供豐富的SPI接口,可以在其上開發兼容屬於自己的註冊中心、SQL監控等

  • 提供分表分庫算法接口,使用者可以設計滿足自己的業務場景的分表分庫算法

快速上手

1. 規則配置

編輯%shardingsphere%\conf\config-xxx.yaml。詳情請參見配置說明。

編輯%shardingsphere%\conf\server.yaml。詳情請參見配置說明。

2. 啓動服務

使用默認配置項

${shardingsphere}\bin\start.sh

配置端口

${shardingsphere}\bin\start.sh ${port}

操作指南

1.配置說明

shardingsphere主目錄下的conf目錄中有如下幾個配置文件:

[root@node15 conf]# ll
總用量 24
-rw-r--r-- 1 app app 3019 7月  30 2019 config-encrypt.yaml
-rw-r--r-- 1 app app 3582 4月  22 2019 config-master_slave.yaml
-rw-r--r-- 1 app app 6572 2月  18 18:04 config-sharding.yaml
-rw-r--r-- 1 app app 1322 4月  22 2019 logback.xml
-rw-r--r-- 1 app app 1888 2月   4 13:57 server.yaml

從上至下分別是:

config-encrypt.yaml (數據脫敏配置)
config-master_slave.yaml (讀寫分離配置)
config-sharding.yaml (數據分片配置)
logback.xml (日誌輸出配置)
server.yaml (全局信息配置)

這裏拋去日誌輸出配置暫且不表(spring默認集成logback,配置比較簡單),以下按照常用程度和重要性排序,對shardingsphere主要的配置進行說明。

server.yaml

用於配置註冊中心、認證信息以及公用屬性。

治理
orchestration:
  name: orchestration_ds #治理實例名稱
  overwrite: true #是否覆蓋本地配置
  registry: #註冊中心配置
    type: zookeeper #配置中心類型
    serverLists: localhost:2181 #連接註冊中心的服務器列表,多個地址逗號分隔
    namespace: orchestration #註冊中心的命名空間
    digest: #連接註冊中心的權限令牌
    operationTimeoutMilliseconds: 500 #操作超時的毫秒數,默認500毫秒
    maxRetries: 3 #連接失敗後的最大重試次數,默認3次
    retryIntervalMilliseconds: 500 #重試間隔毫秒數,默認500毫秒
    timeToLiveSeconds: 60 #臨時節點存活秒數,默認60秒
認證信息
authentication:
  users:
    root: #自定義用戶名
      password: root #用戶密碼
    sharding: #自定義用戶名
      password: sharding #用戶密碼
      authorizedSchemas: sharding_db #該用戶授權訪問的數據庫,逗號分隔,如果缺省將擁有root用戶的權利,訪問所有數據庫
公共屬性
props:
  max.connections.size.per.query: 1 #每個查詢的最大連接數
  acceptor.size: 16  #用於設置接收客戶端請求的工作線程個數,默認爲CPU核數*2
  executor.size: 16  #工作線程數量
  proxy.frontend.flush.threshold: 128  # 對於單個大查詢,每多少個網絡包返回一次
    # LOCAL: 代理使用本地事務
    # XA: 代理使用XA事務.
    # BASE: Proxy will run with B.A.S.E transaction.
  proxy.transaction.type: LOCAL #默認爲LOCAL事務,允許LOCAL,XA,BASE三個值,XA採用Atomikos作爲事務管理器,BASE類型需要拷貝實現ShardingTransactionManager的接口的jar包至lib目錄中
  proxy.opentracing.enabled: false #是否開啓鏈路追蹤功能,默認爲不開啓。
  query.with.cipher.column: true #是否使用密文列查詢
  sql.show: false #是否開啓SQL顯示

config-sharding.yaml

這個配置文件是使用的最多的配置文件,裏面定義實際的數據源、分片規則等。

dataSources: #數據源配置,可配置多個data_source_name
  <data_source_name>: #<!!數據庫連接池實現類> `!!`表示實例化該類
    driverClassName: #數據庫驅動類名
    url: #數據庫url連接
    username: #數據庫用戶名
    password: #數據庫密碼
    # ... 數據庫連接池的其它屬性

shardingRule:
  tables: #數據分片規則配置,可配置多個logic_table_name
    <logic_table_name>: #邏輯表名稱
      actualDataNodes: #由數據源名 + 表名組成,以小數點分隔。多個表以逗號分隔,支持inline表達式。缺省表示使用已知數據源與邏輯表名稱生成數據節點。用於廣播表(即每個庫中都需要一個同樣的表用於關聯查詢,多爲字典表)或只分庫不分表且所有庫的表結構完全一致的情況
        
      databaseStrategy: #分庫策略,缺省表示使用默認分庫策略,以下的分片策略只能選其一
        standard: #用於單分片鍵的標準分片場景
          shardingColumn: #分片列名稱
          preciseAlgorithmClassName: #精確分片算法類名稱,用於=和IN。。該類需實現PreciseShardingAlgorithm接口並提供無參數的構造器
          rangeAlgorithmClassName: #範圍分片算法類名稱,用於BETWEEN,可選。。該類需實現RangeShardingAlgorithm接口並提供無參數的構造器
        complex: #用於多分片鍵的複合分片場景
          shardingColumns: #分片列名稱,多個列以逗號分隔
          algorithmClassName: #複合分片算法類名稱。該類需實現ComplexKeysShardingAlgorithm接口並提供無參數的構造器
        inline: #行表達式分片策略
          shardingColumn: #分片列名稱
          algorithmInlineExpression: #分片算法行表達式,需符合groovy語法
        hint: #Hint分片策略
          algorithmClassName: #Hint分片算法類名稱。該類需實現HintShardingAlgorithm接口並提供無參數的構造器
        none: #不分片
      tableStrategy: #分表策略,同分庫策略
      keyGenerator: 
        column: #自增列名稱,缺省表示不使用自增主鍵生成器
        type: #自增列值生成器類型,缺省表示使用默認自增列值生成器。可使用用戶自定義的列值生成器或選擇內置類型:SNOWFLAKE/UUID/LEAF_SEGMENT
        props: #屬性配置, 注意:使用SNOWFLAKE算法,需要配置worker.id與max.tolerate.time.difference.milliseconds屬性。若使用此算法生成值作分片值,建議配置max.vibration.offset屬性
          <property-name>: 屬性名稱
      
  bindingTables: #綁定表規則列表
  - <logic_table_name1, logic_table_name2, ...> 
  - <logic_table_name3, logic_table_name4, ...>
  - <logic_table_name_x, logic_table_name_y, ...>
  broadcastTables: #廣播表規則列表
  - table_name1
  - table_name2
  - table_name_x
  
  defaultDataSourceName: #未配置分片規則的表將通過默認數據源定位  
  defaultDatabaseStrategy: #默認數據庫分片策略,同分庫策略
  defaultTableStrategy: #默認表分片策略,同分庫策略
  defaultKeyGenerator: #默認的主鍵生成算法 如果沒有設置,默認爲SNOWFLAKE算法
    type: #默認自增列值生成器類型,缺省將使用org.apache.shardingsphere.core.keygen.generator.impl.SnowflakeKeyGenerator。可使用用戶自定義的列值生成器或選擇內置類型:SNOWFLAKE/UUID/LEAF_SEGMENT
    props:
      <property-name>: #自增列值生成器屬性配置, 比如SNOWFLAKE算法的worker.id與max.tolerate.time.difference.milliseconds

  masterSlaveRules: #讀寫分離規則,詳見讀寫分離部分
    <data_source_name>: #數據源名稱,需要與真實數據源匹配,可配置多個data_source_name
      masterDataSourceName: #詳見讀寫分離部分
      slaveDataSourceNames: #詳見讀寫分離部分
      loadBalanceAlgorithmType: #詳見讀寫分離部分
      props: #讀寫分離負載算法的屬性配置
        <property-name>: #屬性值
      
props: #屬性配置
  sql.show: #是否開啓SQL顯示,默認值: false
  executor.size: #工作線程數量,默認值: CPU核數
  max.connections.size.per.query: # 每個查詢可以打開的最大連接數量,默認爲1
  check.table.metadata.enabled: #是否在啓動時檢查分表元數據一致性,默認值: false

config-master_slave.yaml

這個配置文件主要是讀寫分離的配置文件。

schemaName: master_slave_db #邏輯庫名

dataSources:#定義數據源
  master_ds:#數據源名稱,這裏最好以名字區分主和從
    url: jdbc:mysql://127.0.0.1:3306/demo_ds_master?serverTimezone=UTC&useSSL=false
    username: root
    password:
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 50
  slave_ds_0:#同上
    url: jdbc:mysql://127.0.0.1:3306/demo_ds_slave_0?serverTimezone=UTC&useSSL=false
    username: root
    password:
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 50
  slave_ds_1:#同上
    url: jdbc:mysql://127.0.0.1:3306/demo_ds_slave_1?serverTimezone=UTC&useSSL=false
    username: root
    password:
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 50

masterSlaveRule:#主從之間的綁定規則
  name: ms_ds #規則名稱
  masterDataSourceName: master_ds #指定主數據源名稱
  slaveDataSourceNames: #指定主對應的從數據源
    - slave_ds_0
    - slave_ds_1

config-encrypt.yaml

數據脫敏配置。

dataSource: #省略數據源配置

encryptRule:
  encryptors:
    <encryptor-name>:
      type: #加解密器類型,可自定義或選擇內置類型:MD5/AES 
      props: #屬性配置, 注意:使用AES加密器,需要配置AES加密器的KEY屬性:aes.key.value
        aes.key.value: 
  tables:
    <table-name>:
      columns:
        <logic-column-name>:
          plainColumn: #存儲明文的字段
          cipherColumn: #存儲密文的字段
          assistedQueryColumn: #輔助查詢字段,針對ShardingQueryAssistedEncryptor類型的加解密器進行輔助查詢
          encryptor: #加密器名字
props:
  query.with.cipher.column: true #是否使用密文列查詢

複雜配置範例

該範例集合了分表分庫及讀寫分離,是比較有說服性的較爲複雜的例子,對於實戰使用有一定的借鑑意義:

schemaName: sharding_db

dataSources:
  ds_0:
    url: jdbc:mysql://192.168.133.15:3306/demo_1?serverTimezone=UTC&useSSL=false
    username: pcloud
    password: pcloud
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 50
  ds_0_slave:
    url: jdbc:mysql://192.168.133.15:3306/demo_1_slave?serverTimezone=UTC&useSSL=false
    username: pcloud
    password: pcloud
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 50
  ds_1:
    url: jdbc:mysql://192.168.133.15:3306/demo_2?serverTimezone=UTC&useSSL=false
    username: pcloud
    password: pcloud
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 50
  ds_1_slave:
    url: jdbc:mysql://192.168.133.15:3306/demo_2_slave?serverTimezone=UTC&useSSL=false
    username: pcloud
    password: pcloud
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 50
shardingRule:
  tables:
    tborder:
      actualDataNodes: ms_ds${0..1}.tborder
      databaseStrategy:
        standard:
          shardingColumn: personId
          preciseAlgorithmClassName: org.apache.shardingsphere.api.sharding.impl.HashShardingAlgorithm
    tbperson:
      actualDataNodes: ms_ds${0..1}.tbperson
      databaseStrategy:
        standard:
          shardingColumn: personId
          preciseAlgorithmClassName: org.apache.shardingsphere.api.sharding.impl.HashShardingAlgorithm
      #tableStrategy:
        #complex:
          #shardingColumns: orderId,createTime
          #algorithmClassName: org.apache.shardingsphere.api.sharding.impl.ECComplexShardingAlgorithm
      #keyGenerator:
          #type: SNOWFLAKE
          #column: personId
  bindingTables:
    - tborder,tbperson
  defaultDatabaseStrategy:
    none:
  defaultTableStrategy:
    none:

  masterSlaveRules:
    ms_ds0:
      masterDataSourceName: ds_0
      slaveDataSourceNames:
        - ds_0_slave
      loadBalanceAlgorithmType: ROUND_ROBIN
    ms_ds1:
      masterDataSourceName: ds_1
      slaveDataSourceNames:
        - ds_1_slave
      loadBalanceAlgorithmType: ROUND_ROBIN

2.實現自己的分表分庫算法並應用到shardingsphere

上面名詞介紹裏面已經介紹,shardingsphere有四種分片算法,因此shardingsphere提供了4種類型的接口,在sharding-core-api模塊下的org.apache.shardingsphere.api.sharding包內,類名爲PreciseShardingAlgorithm(精準分片)、RangeShardingAlgorithm(範圍分片)、HintShardingAlgorithm(Hint分片)、ComplexKeysShardingAlgorithm(複雜分片)。
以下舉例說明,通過實現精準分片接口,算法對拆分鍵進行hash算法後路由到指定的節點,演示如何將自己的分片算法集成到shardingsphere中並使用。

(1)首先,完成自己的分片算法

package org.apache.shardingsphere.api.sharding.impl;

import lombok.extern.slf4j.Slf4j;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;

import java.util.Collection;
import java.util.Iterator;

/*
 * @author: YoungLu
 * @date: 2020/2/4 10:23
 * @description:
*/
@Slf4j
public class HashShardingAlgorithm implements PreciseShardingAlgorithm<String> {
    @Override
    public String doSharding(final Collection<String> availableTargetNames, final PreciseShardingValue<String> shardingValue) {
        String columnName = shardingValue.getColumnName();
        String tableName = shardingValue.getLogicTableName();
        String value = shardingValue.getValue();
        log.debug("column:{},tableName:{},value:{}", new Object[]{columnName, tableName, value});
        int shardingCount = availableTargetNames.size();
        log.debug("shardingCount:{}", shardingCount);
        int hashNum = this.hash(value, shardingCount);
        Iterator it = availableTargetNames.iterator();

        String targetName;
        do {
            if (!it.hasNext()) {
                throw new UnsupportedOperationException();
            }

            targetName = (String) it.next();
        } while (!targetName.endsWith(hashNum + ""));

        log.debug("recent return target is : {}", targetName);
        return targetName;
    }

    private int hash(final String text, final int shardsNum) {
        return Math.abs(text.hashCode() % shardsNum);
    }
}

(2)將分片算法打成jar包,jar包的目錄結構需要根據你的類所在的包決定,例如上述的算法包名爲:
package org.apache.shardingsphere.api.sharding.impl;則對應需要創建的目錄結構爲:
在這裏插入圖片描述
(3)將打包好的jar包放入服務器部署的%shardingsphere%\lib\目錄下:
在這裏插入圖片描述

常見問題

1.除了支持自帶的分佈式自增主鍵之外,還能否支持原生的自增主鍵?

回答:是的,可以支持。但原生自增主鍵有使用限制,即不能將原生自增主鍵同時作爲分片鍵使用。

由於shardingsphere並不知曉數據庫的表結構,而原生自增主鍵是不包含在原始SQL中內的,因此shardingsphere無法將該字段解析爲分片字段。如自增主鍵非分片鍵,則無需關注,可正常返回;若自增主鍵同時作爲分片鍵使用,shardingsphere無法解析其分片值,導致SQL路由至多張表,從而影響應用的正確性。

而原生自增主鍵返回的前提條件是INSERT SQL必須最終路由至一張表,因此,面對返回多表的INSERT SQL,自增主鍵則會返回零。

2.Windows環境下,通過Git克隆shardingsphere源碼時爲什麼提示文件名過長,如何解決?

回答:

爲保證源碼的可讀性,shardingsphere編碼規範要求類、方法和變量的命名要做到顧名思義,避免使用縮寫,因此可能導致部分源碼文件命名較長。由於Windows版本的Git是使用msys編譯的,它使用了舊版本的Windows Api,限制文件名不能超過260個字符。

解決方案如下:

打開cmd.exe(你需要將git添加到環境變量中)並執行下面的命令:

git config --global core.longpaths true

3.如果SQL在ShardingSphere中執行不正確,該如何調試?

回答:

shardingsphere提供了sql.show的配置,可以將解析上下文和改寫後的SQL以及最終路由至的數據源的細節信息全部打印至info日誌。 sql.show配置默認關閉,如果需要請通過配置開啓。

發佈了49 篇原創文章 · 獲贊 5 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章