image.png

Sharding-JDBC内部结构

image.png

表类型

  • 真实表
  • 逻辑表
  • 绑定表
    • order和order_item,都按照order_id分片。
  • 广播表

    分片算法

    PreciseShardingAlgorithm:精确分片

  • 返回数据源名称

    1. public class CustomTablePreciseShardingAlgorithm implements PreciseShardingAlgorithm<Long> {
    2. /**
    3. *
    4. * @param dataSourceNames 数据源集合
    5. * 在分库时值为所有分片库的集合 databaseNames
    6. * 分表时为对应分片库中所有分片表的集合 tablesNames
    7. *
    8. * @param shardingValue 分片属性,包括
    9. * logicTableName 为逻辑表,
    10. * columnName 分片健(字段),
    11. * value 为从 SQL 中解析出的分片健的值
    12. * @return
    13. */
    14. @Override
    15. public String doSharding(Collection<String> dataSourceNames, PreciseShardingValue<Long> preciseShardingValue) {
    16. for(String datasourceName : dataSourceNames){
    17. String value = preciseShardingValue.getValue() % dataSourceNames.size() + "";
    18. //product_order_0
    19. if(datasourceName.endsWith(value)){
    20. return datasourceName;
    21. }
    22. }
    23. return null;
    24. }
    25. }

    RangeShardingAlgorithm:范围分片

    ComplexKeysShardingAlgorithm:复合分片

    HintShardingAlgorithm:Hint分片

分片策略【策略包含算法】

  • 一个分片策略,可以包含一个或多个分片算法。

    StandardShardingStrategy:标准分片策略

    Sharding-sphere - 图3

    ComplexShardingStrategy

    image.png

    InlineShardingStrategy

  • 支持=、in

  • 使用Groovy表达式:tuser$->{u_id%8}
  • image.png
  • image.png

    HintShardingStrategy:人工指定分片

  • hint:暗示、提示。

  • 通过Hint指定分片值,而非从SQL中提取。

    不支持的sql示例

    image.png

配置

配置数据源

  1. # 打印执行的数据库以及语句
  2. spring.shardingsphere.props.sql.show=true
  3. # 数据源 db0
  4. spring.shardingsphere.datasource.names=ds0,ds1
  5. # 第一个数据库
  6. spring.shardingsphere.datasource.ds0.type=com.zaxxer.hikari.HikariDataSource
  7. spring.shardingsphere.datasource.ds0.driver-class-name=com.mysql.cj.jdbc.Driver
  8. spring.shardingsphere.datasource.ds0.jdbc-url=jdbc:mysql://120.25.217.15:3306/xdclass_shop_order_0?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
  9. spring.shardingsphere.datasource.ds0.username=root
  10. spring.shardingsphere.datasource.ds0.password=xdclass.net168
  11. # 第二个数据库
  12. spring.shardingsphere.datasource.ds1.type=com.zaxxer.hikari.HikariDataSource
  13. spring.shardingsphere.datasource.ds1.driver-class-name=com.mysql.cj.jdbc.Driver
  14. spring.shardingsphere.datasource.ds1.jdbc-url=jdbc:mysql://120.25.217.15:3306/xdclass_shop_order_1?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
  15. spring.shardingsphere.datasource.ds1.username=root
  16. spring.shardingsphere.datasource.ds1.password=xdclass.net168

配置虚拟表、分库策略、分表策略、id生成器

image.png

配置默认分库策略

image.png

自定义分库规则

  1. public class CustomComplexKeysShardingAlgorithm implements ComplexKeysShardingAlgorithm<Long> {
  2. /**
  3. *
  4. * @param dataSourceNames 数据源集合
  5. * 在分库时值为所有分片库的集合 databaseNames
  6. * 分表时为对应分片库中所有分片表的集合 tablesNames
  7. *
  8. * @param shardingValue 分片属性,包括
  9. * logicTableName 为逻辑表,
  10. * columnName 分片健(字段),
  11. * value 为从 SQL 中解析出的分片健的值
  12. * @return
  13. */
  14. @Override
  15. public Collection<String> doSharding(Collection<String> dataSourceNames, ComplexKeysShardingValue<Long> complexKeysShardingValue) {
  16. // 得到每个分片健对应的值
  17. Collection<Long> orderIdValues = this.getShardingValue(complexKeysShardingValue, "id");
  18. Collection<Long> userIdValues = this.getShardingValue(complexKeysShardingValue, "user_id");
  19. List<String> shardingSuffix = new ArrayList<>();
  20. // 对两个分片健取模的方式 product_order_0_0、product_order_0_1、product_order_1_0、product_order_1_1
  21. for (Long userId : userIdValues) {
  22. for (Long orderId : orderIdValues) {
  23. String suffix = userId % 2 + "_" + orderId % 2;
  24. for (String databaseName : dataSourceNames) {
  25. if (databaseName.endsWith(suffix)) {
  26. shardingSuffix.add(databaseName);
  27. }
  28. }
  29. }
  30. }
  31. return shardingSuffix;
  32. }
  33. /**
  34. * shardingValue 分片属性,包括
  35. * logicTableName 为逻辑表,
  36. * columnNameAndShardingValuesMap 存储多个分片健 包括key-value
  37. * key:分片key,id和user_id
  38. * value:分片value,66和99
  39. *
  40. * @return shardingValues 集合
  41. */
  42. private Collection<Long> getShardingValue(ComplexKeysShardingValue<Long> shardingValues, final String key) {
  43. Collection<Long> valueSet = new ArrayList<>();
  44. Map<String, Collection<Long>> columnNameAndShardingValuesMap = shardingValues.getColumnNameAndShardingValuesMap();
  45. if (columnNameAndShardingValuesMap.containsKey(key)) {
  46. valueSet.addAll(columnNameAndShardingValuesMap.get(key));
  47. }
  48. return valueSet;
  49. }
  50. }

自定义key生成算法

实现ShardingKeyGenerator
image.png
配置SPI
image.png
配置

spring.shardingsphere.sharding.tables.position.key-generator.type=LAGOUKEY

配置主从

image.png
多套主从:
image.png

不同mapper下使用不同的数据源,做主从

image.png

配置使用Hint

image.png
image.png

注解强制走主库

image.png
image.png

如何解决主从延迟,读不到

  • 插入同时,插入缓存。先读缓存,缓存没有读从库。

sharding-jdbc配置中心

image.png