分库分表ShardingJDBC最佳实践
1 添加依赖
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-jdbc-core</artifactId>
<version>${sharding.version}</version>
</dependency>
2 分库分表数选择
根据未来两年的业务量,估算两年的业务总量M,单表数据量不能超过N(需要看具体业务场景,字段少的可以适量多一些,可与架构师及部门经验丰富的同事探讨,最大不要超过1000W);
总的分表数量K≥M/N,且K值向上取接近的最小2的次幂。
例如业务总量M=10亿,单表数量N≤700W,则M/N≈143,向上取最小的2次幂为:143<2的8次方=256,故总的分表数量为256。
可将分表数设定的尽可能的小,一台服务器存放多个库,业务增长后,磁盘不足时,可将该服务器上的整个库的数据迁移到新的服务器。
如总的分表数量为1024,可分为32个库:db0~db31,每个库分32张表:tb0~tb31,共16台服务器:server0~server15。
具体划分如下:
- server0上有db0库和db16库
- server1上有db1库和db17库
- ……
- server15上有db15库和db31库
如果业务发展一段时间后出现磁盘不足,可在申请16台服务器:server16~server31
- server0上的db16库迁移至server16
- server1上的db17库迁移至server17
- ……
- server15上的db31库迁移至server31
迁移后磁盘释放50%空间
3 分片键(拆分键)选择
分片键的选择一定要具有明显的业务特征,具体表现为:
- 常用的已知的具体值,查询条件中要包含分片键,需要根据分片键确定在哪个库表,如果查询条件里没有分片键,将会遍历所有库表,这种情况是不允许的;
- 分片键分辨度较高,比较分散,不能选择分辨度不高的的字段作为分片键,容易造成数据分布不均匀;
- 分片键不能有偏移,比如分片键某个值不能远远大于其他值,这种情况也会造成数据分布不均匀;
- 大小写,如果分片键在某些表里不区分大小写,那么分片键要统一大写或小写后用于分片,因此其他条件要考虑统一大小写后的情况;
目前项目里使用的分片键为商家编码,并统一为大写,因为:
- 在查询分库分表数据时,商家编码是已知的,所以查询条件中包含商家编码;
- 商家编码较多,能够保证按照商家编码分片后数据基本是均匀分布的;
- 系统中不存在某个或某几个商家编码的数据量占据大部分的数据量;
4 分片算法
inline: Groovy的Inline表达式,可以支持SQL语句中的=和IN的操作,InlineShardingStrategy只支持单分片键;这种方式是最常用的,也是目前项目中在使用的。
其他分片策略参考:Sharding-JDBC分片策略
4.1 分库算法
以32个库为例:Math.abs(库分片键.toUpperCase().hashCode()) % 32,将分片键商家编码统一大写后,取hashCode的绝对值,对32取模,32为分库数;
通用公式为:Math.abs(库分片键.toUpperCase().hashCode()) % 分库数
4.2 分表算法
以每个库32张表为例:(Math.abs(表分片键.toUpperCase().hashCode()) % 1024).intdiv(32),要保证分到某个库的数据,均匀分布到该库的每个表;
注意:此处不能直接用分库的公式,因为某个商家计算后分配到第i库,如果分表用同样的公式,则也只能落到第i表,导致一个库中只有一个表有数据。因此,需要先对一个较大的数取模,该较大的数为分库数*分表数,记为m,本例中=32*32=1024,将hash后的值分散到0-1023之间,在除以32,则最终结果被分配到0-31之间。
通用公式为:(Math.abs(表分片键.toUpperCase().hashCode()) % 分库数*分表数).intdiv(分库数)
5 全局(分布式)主键
分库分表,要求主键全局唯一,因为存在数据汇总的场景,如存放到ES、大数据等;因此不能使用数据库自增方式,需要一种全局唯一的主键生成方式;
5.1 shardingjdbc提供的主键
1. 添加maven依赖
<dependency>
<groupId>com.dangdang</groupId>
<artifactId>sharding-jdbc-self-id-generator</artifactId>
<version>1.4.2</version>
</dependency>
2. 在@Configuration类中创建Bean对象
@Bean
public IdGenerator getIdGenerator() {
return new CommonSelfIdGenerator();
}
3. 使用
@Autowired
private IdGenerator idGenerator;
@Test
public void generateId(){
long id = idGenerator.generateId().longValue();
......
}
5.2 雪花算法生成主键
很多插件如sharding-jdbc, mybatis-plus提供了雪花算法生成器,目前常用的是这种方式,生产的id时间上基本是有序的,使用很方便。
6 查询条件没有分片键如何处理
不允许没有分片键的查库操作;
查询或更新库操作条件里必须有分片键,否则就需要将分库分表数据存放到ES或建立查询条件与分片键的中间表;
ES或分片键中间表是为个别场景如页面多条件查询,用户获取不到分片键时采取的折中方案,绝大多数场景是能获取到分片键的,如果获取不到则可认为分片键的选取是不合理的,需要根据实际场景调整分片键。
分库分表ShardingJDBC最佳实践的更多相关文章
- mysql数据库分库分表shardingjdbc
分库分表理解 分库分表应用于互联网的两个场景;大量数据和高并发,通常策略有两种:垂直分库,水平拆分 垂直拆分:是根据业务将一个库拆分为多个库,将一个表拆分为多个表,例如:将不常用的字段和经常访问的字段 ...
- 基于代理的数据库分库分表框架 Mycat实践
192.168.199.75 MySQL . MyCAT master 192.168.199.74 MySQL slave 192.168.199.76 MySQL standby master 如 ...
- 分库分表实践-Sharding-JDBC
最近一段时间在研究分库分表的一些问题,正好周末有点时间就简单做下总结,也方便自己以后查看. 关于为什么要做分库分表,什么是水平分表,垂直分表等概念,相信大家都知道,这里就不在赘述了. 本文只讲述使用S ...
- (二)基于shard-jdbc中间件,实现数据分库分表
基于shard-jdbc中间件,实现数据分库分表 Sharding-JDBC简介 Sharding配置示意图 1.水平分割 1.1 水平分库 1.2 水平分表 2.Shard-jdbc中间件 2.1 ...
- 【大数据和云计算技术社区】分库分表技术演进&最佳实践笔记
1.需求背景 移动互联网时代,海量的用户每天产生海量的数量,这些海量数据远不是一张表能Hold住的.比如 用户表:支付宝8亿,微信10亿.CITIC对公140万,对私8700万. 订单表:美团每天几千 ...
- 分库分表技术演进&最佳实践
每个优秀的程序员和架构师都应该掌握分库分表,这是我的观点. 移动互联网时代,海量的用户每天产生海量的数量,比如: 用户表 订单表 交易流水表 以支付宝用户为例,8亿:微信用户更是10亿.订单表更夸张, ...
- 【分库分表】sharding-jdbc实践—分库分表入门
一.准备工作 1.准备三个数据库:db0.db1.db2 2.每个数据库新建两个订单表:t_order_0.t_order_1 DROP TABLE IF EXISTS `t_order_x`; CR ...
- SpringBoot+MybatisPlus+Mysql+Sharding-JDBC分库分表实践
一.序言 在实际业务中,单表数据增长较快,很容易达到数据瓶颈,比如单表百万级别数据量.当数据量继续增长时,数据的查询性能即使有索引的帮助下也不尽如意,这时可以引入数据分库分表技术. 本文将基于Spri ...
- 解读分库分表中间件Sharding-JDBC
[编者按]数据库分库分表从互联网时代开启至今,一直是热门话题.在NoSQL横行的今天,关系型数据库凭借其稳定.查询灵活.兼容等特性,仍被大多数公司作为首选数据库.因此,合理采用分库分表技术应对海量数据 ...
- 分库分表中间件Sharding-JDBC
数据库分库分表从互联网时代开启至今,一直是热门话题.在NoSQL横行的今天,关系型数据库凭借其稳定.查询灵活.兼容等特性,仍被大多数公司作为首选数据库.因此,合理采用分库分表技术应对海量数据和高并发对 ...
随机推荐
- [2002年NOIP提高组] 均分纸牌
有 N 堆纸牌,编号分别为 1,2,-, N.每堆上有若干张,但纸牌总数必为 N 的倍数.可以在任一堆上取若于张纸牌,然后移动.移牌规则为:在编号为 1 堆上取的纸牌,只能移到编号为 2 的堆上:在编 ...
- eclipse中同步git代码报错checkout conflict with files
1.Team--->Synchronize Workspace 2.在同步窗口找到冲突文件,把自己本地修改的复制出来 3.在文件上右键选择 Overwrite----->Yes , 4.再 ...
- C语言ll一作业01
1. 作业头 | 这个作业属于哪个课程 | https://edu.cnblogs.com/campus/zswxy/SE2020-3 | | ---- | ---- | ---- | | 这个作业目 ...
- bzoj 4195
并查集水题 离散化之后直接并查集合并,在不等时判断两者是否在同一个集合內即可 注意排序 贴代码: #include <cstdio> #include <cmath> #inc ...
- CSRF跨站点请求伪造(Cross Site Request Forgery)攻击
CSRF跨站点请求伪造(Cross Site Request Forgery)和XSS攻击一样,有巨大的危害性,就是攻击者盗用了用户的身份,以用户的身份发送恶意请求,但是对服务器来说这个请求是合理的, ...
- esxi的一些命令
今天本想在vcenter上建个分布式交换机,没想到在迁移主机端口时,由于主机只连了一个物理网卡,导致在迁移到分布式交换机而失去连接,几近周折,从网上找了几篇不错的文章,与众同乐 假如一台ESX主机先通 ...
- java 操作excel
需要引入的包 import org.apache.poi.hssf.usermodel.*; import org.apache.poi.ss.usermodel.HorizontalAlignmen ...
- Jmeter五、jmeter中的逻辑控制器
1.simple controller 提供一个块的结构和控制.更方便,更清晰. 嵌套其他的controller 2.loop controller 循环控制器 控制循环次数 可以使用变量 ${__t ...
- 终端命令mix
Jdk(1.7) java -version Maven是否安装 mvn -v MySQL(5.7) mysql -uroot -p /Users/zhanzhanyunjiu/Documents/a ...
- 【项目记录】3:pyinstaller打包之后tkcalendar无法使用的解决办法
PyInstaller 没有检测到二级导入这一事实.tkcalendar 的HowTos文档中解释了解决此问题的方法: 使用 PyInstaller 捆绑应用程序时, 检测 tkcalendar 的 ...