一次sharding,shardingjdbc

【一次sharding,shardingjdbc】Sharding-JDBC,查询量大如何优化?

一次sharding,shardingjdbc


在互联网时代,随着业务数量的暴增和应用规模的不断扩大,无论是oracle还是mysql这样子的关系型数据库,都会面临服务器CPU、磁盘IO和内存的各种瓶颈问题 。基于此情况,各个业务团队迫切需要一种数据分片的方案将业务数据量存储成本分摊到成本可控的各个普通数据库服务器上,数据库切分的方案便应运而生 。本文将结合实际的业务场景进行分析(Java自学网推荐),详细阐述选型开源组件—ShardingJdbc时候的一些思考,并最终给读者呈现业务系统集成ShardingJdbc的最终设计方案 。
另外,本文仅为使用开源组件ShardingJdbc第一篇幅,后续篇幅还将继续介绍开源组件ShardingJdbc的一些其他进阶用法 。数据的切分方式一般,线上系统的业务量不是很大,比如说单库的数据量在百万级别以下,那么MySQL的单库即可完成任何增/删/改/查的业务操作 。随着业务的发展,单个DB中保存的数据量(用户、订单、计费明细和权限规则等数据)呈现指数级增长,那么各种业务处理操作都会面临单DB的IO读写瓶颈带来的性能问题 。
垂直切分方案这时候,我们会考虑使用对之前的整个单DB采用垂直数据切分的方案,根据不同的业务类型划分库表,比如订单相关若干表放在订单库,用户相关的表放在用户库,账务明细相关的表放在账务库等 。这样就将数据分担到了不同的库上,达到专库专用的效果 。使用垂直切分方案的主要优点如下:a.拆分后业务清晰,符合微服务的总体设计理念;b.子系统之间的整合与扩展相对容易;c.按照不同的业务类型,将不同的库表放在不同的数据库服务器上,便于管理;d.根据业务数据的“冷”、“热”状态,采用不同的缓存和数据库模式设计方案;垂直切分的缺点如下:a.跨库的Join查询,需要使用不同子系统的API接口读取后在内存中完成关联查询,提高系统复杂度;b.如果某一种类型的业务呈现爆发式地增长,该业务对应的库表还是会存在单DB的IO读写的瓶颈问题,从这一点来说垂直切分并未从根本解决单库单表数据量过大的问题;c.存在跨库事务的一致性问题,解决起来比较麻烦,当然也可以采用分布式事务来解决;水平切分方案由于本文主题讲的是利用开源组件ShardingJdbc进行数据水平切分的实践,因此对于垂直切分方案的一些细节问题就不做过多的详细介绍了 。
与垂直切分对比,这里讲的水平切分不是将库表根据业务类型进行分类存储,而是将其按照数据表中某个字段或某几个字段的某种规则切分存储至多个DB中,在每个库每个表中所包含的只是其中的一部分数据,所有库表加起来的才是全量的业务数据 。这种对数据的切分方式,基本可以保证经过水平切分后的单库单表存储的容量不会太大,从而保证了对单表的增/删/改/查的SQL执行效率和处理能力 。
其中,数据的分片规则也是需要重点考虑的,因为它会使得数据分片在多个库表中是否均匀分布存储 。然而,数据水平切分方案为业务系统带来福音的同时也给系统构建带来了一些值得思考的问题 。使用水平切分方案的主要优点如下:a.单库单表的数据容量可以维持在一个量级,有助于提高业务SQL的执行效率和系统性能;b.不管是利用ShardingJdbc组件还是MyCat框架,业务系统的应用层涉及改造得都较少,只需要根据实际的业务情况来设计数据分片的路由规则即可;c.可以提高业务系统的稳定性和负载能力;使用水平切分方案的主要缺点如下:a.数据水平切分后,分布在多库多表中,跨库Join查询比较复杂;b.分片数据的一致性较为难保证;c.对于历史数据的迁移和数据库的扩容需要较大的维护工作量;选型ShardingJdbc组件的分析对于,“流水”/“明细”一类的业务数据,通常的业务需求是准实时或者说相对滞后,这些数据是按小时、按日和按月汇总加工处理后生成最终业务需求的数据(比如用户账单、报表和话单) 。

推荐阅读