Sharding Sphere基于复合分片键分表实战
文章目录
一. 背景需求
笔者所在系统经过了若干年的数据积累, 出现了众多Mysql大表, 这些大表的数据量从 6000w ~ 30000w不等.
经分析, 数据库实例平时使用率不高, 但是单表已经达到瓶颈, 对于单表的频繁复杂查询, 会逐步拖垮数据库实例.
最终决定对大表进行拆分(只分表不分库), 以此来减轻单表压力, 提升系统查询时性能.
二. 分片键选取
2.1 分库/分表时机
一般来说, MySQL推荐的单表数据量在500w ~ 800w, 超过800w则建议分表.
或是在系统接口响应时间明显变慢, 并且通过代码优化, 改写sql等形式无法获得明显提升, 且明确了性能瓶颈在数据库时, 建议分表.
分库则是在分表后单库性能到达瓶颈后进行, 如果个人或项目有钱任性的除外.
2.2 分片键的选取原则
分片键应选取原有的每个sql都有的查询条件(或者是通过改写原有sql能带上的查询条件)
如果不能保证所有sql都有的查询条件作为分片键, 那么至少也要保证绝大部分, 否则分库分表没有任何意义.
一般的分片键可以取id或者创建时间, 类似于更新时间一类频繁变动的字段不适合作为分片键, 分片键应当是长时间保持不变的字段.
另外分片键最好是便于计算, 有一定规律的字段, 利于我们用尽可能简单的算法去实现分片, 简单的算法容错率更高, 执行效率更快.
2.3 分完片的后续工作
分片后面临以下几个主要的工作:
- 历史数据的迁移
- sql的重写
- 代码的重构
其中历史数据的迁移可以使用一些ETL工具或者是DATAX实现.
sql重写要求DBA改写之前的sql来尽可能使用到分片键路由.
代码的重构包括数据源变更, 分片算法实现等.
2.4 数据增长较快系统建议
对于数据增长较快的系统, 在使用传统关系型数据库的前提下, 单表很快就会达到性能瓶颈.
对于这类系统, 应当在设计初期, 及时制定sql规范, 合理设计每张表的分片键, 适当做出一些业务和设计上的妥协.
这样能为将来的平滑分库分表打下基础.当然如果没有强事务要求的系统可以考虑非关系型数据库, 或者支持事务以及天然支持分布式的TiDB.
2.5 分片后的常见问题
分片后的问题很多, 无法一一列举.
一般来说, 系统越庞杂, 分片越晚, 问题就会更多.
当然这里面还有一些现实因素: 没钱加数据库实例, 需求的不妥协, coder们水平的良莠不齐等等.
所以分片不是银弹, 具体的情况还是需要结合实际情况来采取最适合的方案.
以下是笔者遇到或者是业内常见的一些问题:
-
分片后的数据倾斜
这个几乎是无法避免的, 即使是id取模, 也会因为数据的删除导致每张分表的数据不一样, 或者id是UUID, 取模也会导致数据发生倾斜.
但是一般来说倾斜只要不是太离谱, 都在我们的接受范围以内.
-
分片后的id生成策略
如果分片之前你的id是递增的, 那么分片后你就无法保证id的全局唯一性, 这时比较常见的业内方案就是UUID或者SnowFlake.
当然如果想要排序和分页, 就需要有个id生成器去统一集中生成连续的id(参考下文).
-
分片后的全路由
这个是最糟糕的情况, 这种情况会让我们的查询比分片之前还要慢, 可以在自定义的分片算法中校验这种情况直接抛出异常, 然后coder们根据日志中的报错来统计这部分sql加以改写.
-
jpa级联
如果jpa级联中包含分表, 则需要拆除这种级联关系, 以免导致上述全路由情况发生.
-
分片后的排序&分页
如果只是单独分页, Sharding Sphere会剔除数据不写入内存, 实际上不会导致内存的大量占用, 但如果加上排序, 那情况就不容乐观了, 官方建议通过可以保证连续性的id去加以限制.
三. 自定义复合分片算法
3.1 四种分片算法&五种分片策略
Sharding Sphere为我们提供了4种分片算法和5种分片策略(下面都是官网抄来的, 感兴趣可以在文末找到原文链接)
4种分片算法
精确分片算法
对应PreciseShardingAlgorithm,用于处理使用单一键作为分片键的=与IN进行分片的场景。需要配合StandardShardingStrategy使用。
范围分片算法
对应RangeShardingAlgorithm,用于处理使用单一键作为分片键的BETWEEN AND、>、<、>=、<=进行分片的场景。需要配合StandardShardingStrategy使用。
复合分片算法
对应ComplexKeysShardingAlgorithm,用于处理使用多键作为分片键进行分片的场景,包含多个分片键的逻辑较复杂,需要应用开发者自行处理其中的复杂度。需要配合ComplexShardingStrategy使用。
Hint分片算法
对应HintShardingAlgorithm,用于处理使用Hint行分片的场景。需要配合HintShardingStrategy使用。
5种分片策略
标准分片策略
对应StandardShardingStrategy。提供对SQL语句中的=, >, <, >=, <=, IN和BETWEEN AND的分片操作支持。StandardShardingStrategy只支持单分片键,提供PreciseShardingAlgorithm和RangeShardingAlgorithm两个分片算法。PreciseShardingAlgorithm是必选的,用于处理=和IN的分片。RangeShardingAlgorithm是可选的,用于处理BETWEEN AND, >, <, >=, <=分片,如果不配置RangeShardingAlgorithm,SQL中的BETWEEN AND将按照全库路由处理。
复合分片策略
对应ComplexShardingStrategy。复合分片策略。提供对SQL语句中的=, >, <, >=, <=, IN和BETWEEN AND的分片操作支持。ComplexShardingStrategy支持多分片键,由于多分片键之间的关系复杂,因此并未进行过多的封装,而是直接将分片键值组合以及分片操作符透传至分片算法,完全由应用开发者实现,提供最大的灵活度。
行表达式分片策略
对应InlineShard

本文详细阐述了如何在ShardingSphere中利用复合分片键对大表进行分表,包括选择分片时机、原则,以及自定义算法实现。讨论了数据倾斜、ID生成策略等问题,并提供了分片策略和算法的实践指导。

3328

被折叠的 条评论
为什么被折叠?



