美文网首页
一次sharding-jdbc 5.0 踩坑历程

一次sharding-jdbc 5.0 踩坑历程

作者: 烧霞 | 来源:发表于2022-01-16 12:32 被阅读0次

这天霞妹又来找烧哥了。

“烧哥,帮我看下这个分库分表,升级5.0后不能用了呢?”
“Let me c c?哇,Sharding-jdbc刚推出的最新版?”

背景

关系数据库当今依然占有巨大市场份额,前期通常会存储至单一节点。为提高性能和可用性,一种方案是迁移到NoSQL ,但会有较大技术成本。另一种则考虑数据分片,按照某个维度将数据分散地存储到多个库或表,来有效的避免大数据量产生的查询瓶颈。

数据分片也有两种。垂直分片讲究专库专用,通常按业务模块划分。水平分片则是按字段,通过某种规则拆分到不同库或表。通过搭建多主多从的数据库架构,读写分离,配合水平拆分,实际场景中较为常见。

ShardingSphere则同时提供了这两种解决方案,2020.4.16成为 Apache 软件基金会的顶级项目。Sharding-jdbc作为子产品,以Jar包形式提供服务,可理解为增强版的 JDBC 驱动,能够几乎不改动代码的情况下实现架构迁移,2021.11.10推出了5.0.0版。


问题重现

首先看之前的配置文件:
pom.xml

<dependency>
    <groupId>org.apache.shardingsphere</groupId>
    <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
    <version>4.1.1</version>
</dependency>

application.yml

spring:
  shardingsphere:
    datasource:
      names: master1,slave1
      master1:
        driver-class-name: com.mysql.cj.jdbc.Driver
        password: 
        type: com.alibaba.druid.pool.DruidDataSource
        url: 
        username: 
      slave1:
        driver-class-name: com.mysql.cj.jdbc.Driver
        password: 
        type: com.alibaba.druid.pool.DruidDataSource
        url: 
        username: 
    props:
      sql:
        show: true
    sharding:
      tables:
        b_gcg_content:
          actual-data-nodes: ds.b_gcg_content_$->{0..1}
          table-strategy:
            inline:
              sharding-column: content_id
              algorithm-expression: b_gcg_content_$->{content_id % 2}
              key-generator:
                column: content_id
                type: SNOWFLAKE
      master-slave-rules:
        ds:
          load-balance-algorithm-type: round_robin
          master-data-source-name: master1
          slave-data-source-names: slave1

主库master1,从库slave1,对content表根据content_id取模拆分为两个表。

查询,插入,运行正常。

再看之后的:
pom.yml

<dependency>
    <groupId>org.apache.shardingsphere</groupId>
    <artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId>
    <version>5.0.0</version>
</dependency>

application.yml

spring:
  shardingsphere:
    datasource:
      names: master1,slave1
      master1:
        type: com.zaxxer.hikari.HikariDataSource
        driverClassName: com.mysql.cj.jdbc.Driver
        jdbcUrl: 
        username: 
        password: 
      slave1:
        type: com.zaxxer.hikari.HikariDataSource
        driverClassName: com.mysql.cj.jdbc.Driver
        jdbcUrl: 
        username: 
        password: 
    props:
      sql-show: true
    rules:
      sharding:
        tables: # 数据分片规则配置
          b_gcg_content: # 逻辑表名称
            actualDataNodes: ds.b_gcg_content_$->{0..1} # 由数据源名 + 表名组成(参考Inline语法规则)
            tableStrategy: # 分表策略,同分库策略
              standard: # 用于单分片键的标准分片场景
                shardingColumn: content_id # 分片列名称
                shardingAlgorithmName: my # 分片算法名称
            keyGenerateStrategy: # 分布式序列策略
              column: content_id # 自增列名称,缺省表示不使用自增主键生成器
              keyGeneratorName: my # 分布式序列算法名称
        shardingAlgorithms:
          my: # 分片算法名称
            type: INLINE  # 分片算法类型
            props: # 分片算法属性配置
              algorithm-expression: b_gcg_content_$->{content_id % 2}
        keyGenerators:
          my: # 分布式序列算法名称
            type: SNOWFLAKE # 分布式序列算法类型
      readwriteSplitting:
        dataSources:
          ds:
           loadBalancerName: my
           writeDataSourceName: master1
           readDataSourceNames: slave1
        loadBalancers:
          my: # 负载均衡算法名称
             type: ROUND_ROBIN # 负载均衡算法类型

查询正常,插入时报错:

Insert statement does not support sharding table routing to multiple data nodes.

解谜

1.是否符合官方标准?(不熟悉的话常犯)

首先看到配置文件的语法,升级后有很大改变,根据官方文档挨个排查,确认格式全部正确。

2.是否新版本有缺陷?(最近经常有新闻,xx又有重大漏洞)

搜索这个报错,全网都没有。到官方仓库issue,有大把。引起的原因有很多,但都已修复。
那就下最新源码,5.0.1-SNAPSHOT,重新编译放入私服,岂不简单?
编译比较麻烦,不过最终还是成功了,更改maven版本,奇怪了,依然报错。

3.化繁为简,缩小范围,精准定位(首要思路)

报错中提到了data nodes,配置里同时有读写分离和分表,那就去掉一个,只要分表

    rules:
      sharding:
        tables: # 数据分片规则配置
          b_gcg_content: # 逻辑表名称
            actualDataNodes: master1.b_gcg_content_$->{0..1} # 由数据源名 + 表名组成(参考Inline语法规则)
            tableStrategy: # 分表策略,同分库策略
              standard: # 用于单分片键的标准分片场景
                shardingColumn: content_id # 分片列名称
                shardingAlgorithmName: my # 分片算法名称
            keyGenerateStrategy: # 分布式序列策略
              column: content_id # 自增列名称,缺省表示不使用自增主键生成器
              keyGeneratorName: my # 分布式序列算法名称
        shardingAlgorithms:
          my: # 分片算法名称
            type: INLINE  # 分片算法类型
            props: # 分片算法属性配置
              algorithm-expression: b_gcg_content_$->{content_id % 2}
        keyGenerators:
          my: # 分布式序列算法名称
            type: SNOWFLAKE # 分布式序列算法类型

还是报错。
那不分表总可以吧?再来

    rules:
      sharding:
        tables: # 数据分片规则配置
          b_gcg_content: # 逻辑表名称
            actualDataNodes: master1.b_gcg_content # 由数据源名 + 表名组成(参考Inline语法规则)
            tableStrategy: # 分表策略,同分库策略
              standard: # 用于单分片键的标准分片场景
                shardingColumn: content_id # 分片列名称
                shardingAlgorithmName: my # 分片算法名称
            keyGenerateStrategy: # 分布式序列策略
              column: content_id # 自增列名称,缺省表示不使用自增主键生成器
              keyGeneratorName: my # 分布式序列算法名称
        shardingAlgorithms:
          my: # 分片算法名称
            type: INLINE  # 分片算法类型
            props: # 分片算法属性配置
              algorithm-expression: b_gcg_content
        keyGenerators:
          my: # 分布式序列算法名称
            type: SNOWFLAKE # 分布式序列算法类型

这下倒是可以,看来的确是分表有问题。

4.跟正常的对比,由外到内,等价替换(廉价快速手段)

那官方demo不会也报错吗?apache出品的不至于吧?怀疑人生。
4.x的shardingsphere-example项目已经停更,新demo合并到了主库。
但官方demo是正常的?那就蹊跷了。
难道我的表不行?换成demo的库试试,还是报错,奇葩。
再来看看上面配置,唯一的区别就在于名称改成了my,难不成名称是不能改的??
改成跟demo一样名称,竟然行了。。。

5.避坑
spring:
  shardingsphere:
    datasource:
      names: master1,slave1
      master1:
        type: com.zaxxer.hikari.HikariDataSource
        driverClassName: com.mysql.cj.jdbc.Driver
        jdbcUrl: 
        username: 
        password: 
      slave1:
        type: com.zaxxer.hikari.HikariDataSource
        driverClassName: com.mysql.cj.jdbc.Driver
        jdbcUrl: 
        username: 
        password: 
    props:
      sql-show: true
    rules:
      sharding:
        tables: # 数据分片规则配置
          b_gcg_content: # 逻辑表名称
            actualDataNodes: ds.b_gcg_content_$->{0..1} # 由数据源名 + 表名组成(参考Inline语法规则)
            tableStrategy: # 分表策略,同分库策略
              standard: # 用于单分片键的标准分片场景
                shardingColumn: content_id # 分片列名称
                shardingAlgorithmName: my-table # 分片算法名称
            keyGenerateStrategy: # 分布式序列策略
              column: content_id # 自增列名称,缺省表示不使用自增主键生成器
              keyGeneratorName: my-key # 分布式序列算法名称
        shardingAlgorithms:
          my-table: # 分片算法名称
            type: INLINE  # 分片算法类型
            props: # 分片算法属性配置
              algorithm-expression: b_gcg_content_$->{content_id % 2}
        keyGenerators:
          my-key: # 分布式序列算法名称
            type: SNOWFLAKE # 分布式序列算法类型
      readwriteSplitting:
        dataSources:
          ds:
           loadBalancerName: my-load
           writeDataSourceName: master1
           readDataSourceNames: slave1
        loadBalancers:
          my-load: # 负载均衡算法名称
             type: ROUND_ROBIN # 负载均衡算法类型

“霞妹可以啦”
“烧哥好棒,我这有张券,中午一起嘛”

填坑

架构师的工作就是解决各种疑难杂症,思路的锻炼来自长期实战经历。
Apache的品质总体还是可信赖的,这算个小问题。源码应该是把某些名称放在了一个map下,或者是缓存时出了岔子,有空去提个issue.
又增加一条规范:复杂配置文件中,自定义名称不应该重复。

相关文章

  • 一次sharding-jdbc 5.0 踩坑历程

    这天霞妹又来找烧哥了。 “烧哥,帮我看下这个分库分表,升级5.0后不能用了呢?”“Let me c c?哇,Sha...

  • Python读取大文件的"坑“与内存占用检测

    python读写文件的api都很简单,一不留神就容易踩”坑“。笔者记录一次踩坑历程,并且给了一些总结,希望到大家在...

  • springboot集成swagger2深坑

    记录一次swagger2踩坑记,网上资料杂乱而不完整,自己踩的坑还算比较多,记录下自己的解决历程 一、首次来看看遇...

  • AndroidStudio 高版本deBug,无法安装或启动失败

    想要快速解决该问题可以直接看文章结尾,前面是我踩坑的历程 踩坑历程 最近公司入手了两台三台全新的测试手机,一台华为...

  • 装修踩坑历程

    今天写点不一样的,来聊聊最近装修遇到的坑。希望能够给打算装修的朋友提个醒吧,尤其是天津的朋友。 1. 直接找工人还...

  • Android日常踩坑之——自定义WiFi获取列表

    又到了程序猿日常踩坑的时间了,前段时间,做了一个定制化WiFi相关的功能,最近几天空闲,把踩坑的心路历程分享给大家...

  • Android共享元素

    在这里记录一下android共享元素的方法,踩了满多坑的,其实蛮简单的,Android共享是从Android5.0...

  • uniapp image app端不显示

    踩坑历程 事情是这个样子的~ uniapp 中的 image 组件中,mode 属性的默认值是 scaleToFi...

  • iOS tableView中链接的正确处理姿势

    前面是我的心路历程以及踩过的坑, 赶时间可以直接从5 textView开始看 1 NSMutableAttribu...

  • 踩坑历程(辛酸史)

    所遇到的坑,不计其数,为避免再次掉进入同一个坑,特此记录,同时如果也有哪位遇到和我一样的情况,也可作参考。 201...

网友评论

      本文标题:一次sharding-jdbc 5.0 踩坑历程

      本文链接:https://www.haomeiwen.com/subject/glsfhrtx.html