为啥要分库分表
业务随着变化,表的内容变得越来越多,一个表里面的数据会日积月累的增加,而且之前的数据很少在看了,并降低了查询的效率。业务只关注前几个月的数据,统计数据,所以很多数据现代没有用了,所以可以在后期再去定时生成汇总。目前要分表分库只有一个业务库,工单工作量,把每天的项目工作情况进行分析下来,并记录下来,也就是日工作量。出现了大量无用项目信息工单信息。
已有数据表结构
已经跑了几个月的数据,表突然涌现出一天千万数据,原来业务数据上来了,一些不看好的项目开始录入系统了,系统突然卡死了,被大屏系统每5秒就拉去数据,把系统搞垮了,查询一下子慢了30秒。分析原因,找到事故接口。
开始操作了
大屏里面的数据进行查询,你频繁我就加缓存,数据来的并不快,可是他们查询的快,导致无效查询次数太多,这样我加入缓存,减少了数据库查询的次数。
统计和业务功能界面,我添加了日期查询的策略,先看到是一周的日期,进行日期添加索引,原来的20秒,瞬间回到1秒左右。
总算扛过了。但是业务还在涨啊,数据还在增加啊。
我提出,可以把已完成的项目数据进行归档处理可以吗?业务部门不乐意,他们觉得现在查询就符合他们的业务情况。
我的单表让我如何撑住。
引入ShardingSphere 将它原来不变,进行季度分表处理吧,当这个库10个的时候在分表,这个还有点时间,先把季度库创建,当然表结构一样。
为啥用它ShardingSphere ,就是觉得它基本上业务代码和库表都不用改,只改配置即可。
ShardingSphere 很坑
1、demo example基本上不全。
2、官网 https://shardingsphere.apache.org/document/current/cn/quick-start/shardingsphere-jdbc-quick-start/ 简单的如没有写一样。
3、版本坑,我使用4x 还是5x 呢? 有啥区别呢?
4、我用的还是国产数据库,是否支持。
5、我使用的dynamic 已经查询了好多库了,是否还能支持。让我感觉道路一片空白。
ShardingSphere 真好用
使用ShardingSphere-JDBC数据分片功能即可。其他 ShardingSphere-Proxy 它支持性不好,数据库基本不用想了放弃。
使用 ShardingSphere-JDBC 先正常的 配置pom
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-jdbc</artifactId>
<version>${latest.release.version}</version>
<exclusions>
<exclusion>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>1.33</version>
</dependency>
yml 里面配置
datasource:
dynamic:
datasource:
master: ##原来的
url: ‘’
driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
username:
password:
master2: ## 新增的
driver-class-name: org.apache.shardingsphere.driver.ShardingSphereDriver
url: jdbc:shardingsphere:classpath:shading-auto-tables-algorithm.yaml
shading-auto-tables-algorithm.yaml的添加即可
# JDBC 逻辑库名称。在集群模式中,使用该参数来联通 ShardingSphere-JDBC 与 ShardingSphere-Proxy。
# 默认值:logic_db
databaseName (?):
mode:
dataSources:
rules:
- !FOO_XXX
...
- !BAR_XXX
...
props:
key_1: value_1
key_2: value_2
这个就是官网给的,我反增思考了半天
我不把我的yaml 贴出来了,但是把坑读者也看不到,我找到一个很全的,分库还分表的情况了,还有多表进行同步并读写分离的情况都分析到了,比我的好多了。
dataSources:
ds0:
dataSourceClassName: com.zaxxer.hikari.HikariDataSource
driverClassName: com.mysql.cj.jdbc.Driver
jdbcUrl: jdbc:mysql://127.0.0.1:3306/ds_0?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8&useTimezone=true
username: root
password: ilxw
ds1:
dataSourceClassName: com.zaxxer.hikari.HikariDataSource
driverClassName: com.mysql.cj.jdbc.Driver
jdbcUrl: jdbc:mysql://127.0.0.1:3306/ds_1?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8&useTimezone=true
username: root
password: ilxw
ds2:
dataSourceClassName: com.zaxxer.hikari.HikariDataSource
driverClassName: com.mysql.cj.jdbc.Driver
jdbcUrl: jdbc:mysql://127.0.0.1:3306/ds_2?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8&useTimezone=true
username: root
password: ilxw
ds3:
dataSourceClassName: com.zaxxer.hikari.HikariDataSource
driverClassName: com.mysql.cj.jdbc.Driver
jdbcUrl: jdbc:mysql://127.0.0.1:3306/ds_3?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8&useTimezone=true
username: root
password: ilxw
rules:
- !SHARDING
tables:
# 订单表基础表
t_ent_order:
# 真实表
actualDataNodes: ds$->{0..3}.t_ent_order
# 分库策略
databaseStrategy:
complex:
shardingColumns: id,ent_id
shardingAlgorithmName: hash-slot-algorithm
# 订单详情表
t_ent_order_detail:
actualDataNodes: ds$->{0..3}.t_ent_order_detail
# 分库策略
databaseStrategy:
complex:
shardingColumns: id,ent_id
shardingAlgorithmName: hash-slot-algorithm
# 订单条目表
t_ent_order_item:
actualDataNodes: ds$->{0..3}.t_ent_order_item_$->{0..7}
# 分库策略
databaseStrategy:
complex:
shardingColumns: id,ent_id
shardingAlgorithmName: hash-slot-algorithm
# 分表策略
tableStrategy:
complex:
shardingColumns: id,ent_id
shardingAlgorithmName: hash-slot-table-algorithm
# 绑定表
bindingTables:
- t_ent_order,t_ent_order_detail
# 分片算法
shardingAlgorithms:
hash-slot-algorithm:
type: CLASS_BASED
props:
strategy: complex
algorithmClassName: cn.javayong.shardingjdbc5.spring.common.sharding.HashSlotAlgorithm
hash-slot-table-algorithm:
type: CLASS_BASED
props:
strategy: complex
algorithmClassName: cn.javayong.shardingjdbc5.spring.common.sharding.HashSlotAlgorithm
# 非默认值,直接对分片数取余
directIndex: true
# 广播
- !BROADCAST
tables:
- t_city
props:
# 日志显示 SQL
sql-show: true
我只需要改的地方还有一个在哪个方法的service里面添加@DS("master2") 即可。启动失败问题收集
1、找不到表提示不存在表 配置
actualDataNodes: ds$->{0..3}.t_ent_order_detail
这个参数错误。
2、HashSlotAlgorithm 这个算法
如果没有什么特殊表,基本初始化即可。
3、版本和spring 不适应怎么办。那就从低到高测试一遍,基本不是代码问题,都是版本问题。
4、druid 的版本问题。只有升级升级。
其他
基本稳定运行了,按照时间查询解决我一半的问题。
actualDataNodes 有个问题,我只能创建一年的四个表结构,如何我让程序生成表结构,插入数据没有问题,就是查询不出来,就得手动添加actualDataNodes 里面的表结构重启程序就可以了,好难受啊。
当然这个框架好牛的,影子库提供的影子算法,然后测试了好多次都没有成功。学习还在路上。加油各位。