聊聊 Sharding-JDBC 分库分表(一)

love374
发布于 2022-7-8 17:27
浏览
0收藏

 

大家好,我是不才陈某~

 

这是《ShardingSphere 进阶》专栏的第一篇文章,介绍一下Sharding-JDBC实现分库分表的详细配置。

 

分库分表带来的问题

 

关于什么是分库分表这里不再细说了,相信大家都知道,有不清楚的可以看我之前的文章:聊聊分库分表

 

从单一表、单一库切分成多库、多表对于性能的提升是必然的,但是同时也带来了一些问题。

 

1. 分布式事务问题
由于垂直分库、水平分库,将数据分摊在不同库中,甚至不同的服务器上,势必带来了分布式事务的问题。

 

对于单库单表的事务很好控制,分布式事务的控制却是非常头疼,但是好在现在已经有成熟的解决方案,想要了解的可以看我之前的文章:七种分布式事务解决方案

 

2. 跨节点关联join问题
在切分之前关联查询非常简单,直接SQL JOIN便能解决,但是切分之后数据分摊在不同的节点上,此时JOIN就比较麻烦了,因此切分之后尽量避免JOIN。

 

解决这一问题的有些方法:

1、全局表

这种很好理解,对于一些全局需要关联的表可以在每个数据节点上都存储一份,一般是一些数据字典表。

“全局表在Sharding-JDBC称之为广播表”


2、字段冗余

这是一种典型的反范式设计,为了避免关联JOIN,可以将一些冗余字段保存,比如订单表保存userId时,可以将userName也一并保存,这样就避免了和User表的关联JOIN了。

“字段冗余这种方案存在数据一致性问题”


3、数据组装

这种还是比较好理解的,直接不使用JOIN关联,分两次查询,从第一次的结果集中找出关联数据的唯一标识,然后再次去查询,最后对得到的数据进行组装

“需要进行手动组装,数据很大的情况对CPU、内存有一定的要求”


4、绑定表

对于相互关联的数据节点,通过分片规则将其切分到同一个库中,这样就可以直接使用SQL的JOIN 进行关联查询。

“Sharding-JDBC中称之为绑定表,比如订单表和用户表的绑定”


3. 跨节点分页、排序、函数问题
对于跨数据节点进行分页、排序或者一些聚合函数,筛选出来的仅仅是针对当前节点,比如排序,仅仅能够保证在单一数据节点上是有序,并不能保证在所有节点上都是有序的,需要将各个节点的数据的进行汇总重新手动排序。

 聊聊 Sharding-JDBC 分库分表(一)-鸿蒙开发者社区
“Sharding-JDBC 正是 按照上述流程进行分页、排序、聚合”


4. 全局主键避重问题
单库单表一般都是使用的自增主键,但是在切分之后每个自增主键将无法使用,因为这样会导致数据主键重复,因此必须重新设计主键。

目前主流的分布式主键生成方案如下:

 

1、UUID

UUID应该是大家最为熟悉的一种方案,优点非常明显本地生成,性能高,缺点也很明显,太长了存储耗空间,查询也非常耗性能,另外UUID的无序性将会导致InnoDB下的数据位置变动。

 

2、Snowflake

Twitter开源的由64位整数组成分布式ID,性能较高,并且在单机上递增。

“不再详细介绍,更多信息自行查找资料”


3、UidGenerator

UidGenerator是百度开源的分布式ID生成器,其基于雪花算法实现。具体参考:

“https://github.com/baidu/uid-generator/blob/master/README.zh_cn.md”


4、Leaf

Leaf是美团开源的分布式ID生成器,能保证全局唯一,趋势递增,但需要依赖关系数据库、Zookeeper等中间件。具体参考:

“https://tech.meituan.com/2017/04/21/mt-leaf.html”

 

5. 数据迁移、扩容问题
当业务高速发展,面临性能和存储的瓶颈时,才会考虑分片设计,此时就不可避免的需要考虑历史数据迁移的问题。一般做法是先读出历史数据,然后按指定的分片规则再将数据写入到各个分片节点中。此外还需要根据当前的数据量和QPS,以及业务发展的速度,进行容量规划,推算出大概需要多少分片。

如果采用数值范围分片,只需要添加节点就可以进行扩容了,不需要对分片数据迁移。如果采用的是数值取模分片,则考虑后期的扩容问题就相对比较麻烦。

“分库分表虽然提升了性能,但是在切分过程中一定要考虑上述总结的5种问题。”
 

文章转自公众号:码猿技术专栏

标签
已于2022-7-8 17:27:05修改
收藏
回复
举报
回复
    相关推荐