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最佳实践的更多相关文章

  1. mysql数据库分库分表shardingjdbc

    分库分表理解 分库分表应用于互联网的两个场景;大量数据和高并发,通常策略有两种:垂直分库,水平拆分 垂直拆分:是根据业务将一个库拆分为多个库,将一个表拆分为多个表,例如:将不常用的字段和经常访问的字段 ...

  2. 基于代理的数据库分库分表框架 Mycat实践

    192.168.199.75 MySQL . MyCAT master 192.168.199.74 MySQL slave 192.168.199.76 MySQL standby master 如 ...

  3. 分库分表实践-Sharding-JDBC

    最近一段时间在研究分库分表的一些问题,正好周末有点时间就简单做下总结,也方便自己以后查看. 关于为什么要做分库分表,什么是水平分表,垂直分表等概念,相信大家都知道,这里就不在赘述了. 本文只讲述使用S ...

  4. (二)基于shard-jdbc中间件,实现数据分库分表

    基于shard-jdbc中间件,实现数据分库分表 Sharding-JDBC简介 Sharding配置示意图 1.水平分割 1.1 水平分库 1.2 水平分表 2.Shard-jdbc中间件 2.1 ...

  5. 【大数据和云计算技术社区】分库分表技术演进&最佳实践笔记

    1.需求背景 移动互联网时代,海量的用户每天产生海量的数量,这些海量数据远不是一张表能Hold住的.比如 用户表:支付宝8亿,微信10亿.CITIC对公140万,对私8700万. 订单表:美团每天几千 ...

  6. 分库分表技术演进&最佳实践

    每个优秀的程序员和架构师都应该掌握分库分表,这是我的观点. 移动互联网时代,海量的用户每天产生海量的数量,比如: 用户表 订单表 交易流水表 以支付宝用户为例,8亿:微信用户更是10亿.订单表更夸张, ...

  7. 【分库分表】sharding-jdbc实践—分库分表入门

    一.准备工作 1.准备三个数据库:db0.db1.db2 2.每个数据库新建两个订单表:t_order_0.t_order_1 DROP TABLE IF EXISTS `t_order_x`; CR ...

  8. SpringBoot+MybatisPlus+Mysql+Sharding-JDBC分库分表实践

    一.序言 在实际业务中,单表数据增长较快,很容易达到数据瓶颈,比如单表百万级别数据量.当数据量继续增长时,数据的查询性能即使有索引的帮助下也不尽如意,这时可以引入数据分库分表技术. 本文将基于Spri ...

  9. 解读分库分表中间件Sharding-JDBC

    [编者按]数据库分库分表从互联网时代开启至今,一直是热门话题.在NoSQL横行的今天,关系型数据库凭借其稳定.查询灵活.兼容等特性,仍被大多数公司作为首选数据库.因此,合理采用分库分表技术应对海量数据 ...

  10. 分库分表中间件Sharding-JDBC

    数据库分库分表从互联网时代开启至今,一直是热门话题.在NoSQL横行的今天,关系型数据库凭借其稳定.查询灵活.兼容等特性,仍被大多数公司作为首选数据库.因此,合理采用分库分表技术应对海量数据和高并发对 ...

随机推荐

  1. 在自定义Flink1.10 Sql Sink遇到的问题

    1.org.apache.flink.table.api.TableException: Table sink does not implement a table schema. 问题:在Redis ...

  2. SQL-运算

    dual表可以进行运算select * from dual; 算数运算 + - * /select 5 + 6 as aaa ,6 - 3 as bbb ,5 * 7 as ccc ,9/2 as d ...

  3. git常用命令查询手册

    默认已经连接到远程仓库的情况下 本地文件夹初始化成git仓库.提交本地仓库并添加注释 git init git add 文件1(文件夹1) 文件2(文件夹2)... git commit -m &qu ...

  4. C语言——函数

    C 语言中的函数定义形式: return_type function_name( parameter list ) //函数头 { //函数体 body of the function } 返回类型: ...

  5. Python 错误:ModuleNotFoundError: No module named 'conf'

    问题描述: 编译器无法使用cmd命令来执行py文件,结果可能报ModuleNotFoundError的错误. 比如在cmd任务栏执行:python E:\myProgram\Python\spider ...

  6. python 添加文件模板,默认添加作者时间等必要信息

    1.模板设置 配置路径:Setting-Editor-File and Code Templates-Python-Script 2.示例输入 代码如下(示例): #!/usr/bin/env pyt ...

  7. 根据id 删除树结构中的数据

    根据id 删除树结构中的数据  filterHandle(data, id) {                         var newData = data.filter(x => x ...

  8. 浙里办微信小程序总结

    浙里办微信小程序单点登录流程 1.获取浙里办跳转地址中ticket或者微信小程序中的ticketId let ticket = getQueryString("ticket", w ...

  9. HTTPS的实现原理 ---- 核心 SSL/TLS协议

    是在应用层和 传输层之间 添加的 安全层(SSL/TLS协议) 端口号 :HTTP 默认是 80,HTTPS 默认是 443. URL 前缀 :HTTP 的 URL 前缀是 http://,HTTPS ...

  10. 9.29 2020 实验 4:Open vSwitch 实验——Mininet 中使用 OVS 命令

    一.实验目的 Mininet 安装之后,会连带安装 Open vSwitch,可以直接通过 Python 脚本调用Open vSwitch 命令,从而直接控制 Open vSwitch,通过实验了解调 ...