分库分表及shardingjdbc

一 序

关于分库分表,网上有很多文章了,沈剑老师也有专门的文章介绍。

数据库拆分简单来说,就是指通过某种特定的条件,按照某个维度,将我们存放在同一个数据库中的数据分散存放到多个数据库(主机)上面以达到分散单库(主机)负载的效果。 

从理论到自己动手写demo还是有差别的。尤其是调研后发现shardingjdbc的官网例子不能直接用。

有点错位的感觉:官网的文档是基于java的。实际上以yaml或者spring + mybatis配置的多。

所以还是觉得有必要整理一篇。本篇是理论部分,下一篇是demo.

二 垂直拆分

通常是一张大表拆成多张小表,是按照列拆的。举个例子,假设现在交易相关的在一张表。

包含了订单,支付信息,退款等。可以按照垂直拆分为更细的小表,如:订单,支付,退款。

优点:

小表业务逻辑更清晰,容易维护,有的订单表都上百列,有的如状态会有修改,大部分字段不变,还是能拆开的。

缺点:

查询以前是在一个库一张表,如果拆为同一库不同的表需要关联join查询,如果拆为不同的库无法join需要依赖接口。

所以通常的这种垂直拆分是在设计阶段都拆好了。

三 水平拆分

水平分表也称为横向分表,比较容易理解,就是将表中不同的数据行按照一定规律分布到不同的数据库表中(或者保存在同一个数据库中),这样来降低单表数据量,优化查询性能。通常是取模或者hash.


这里hash多说一句,了解负载均衡的同学,通常会想到一致性hash,为数据迁移考虑。但是实际业务场景不太一致:

1  一致性hash是负载均衡下,为了增加减少节点尽量减少数据移动。

2 对于水平拆分的来说,假设这次分了8个表,下一次单表数据量达到上限1000W,又要进行再次扩容到16个,

数据量是从8个表迁移一半到8个新表,一共是16个表。迁移量没有本质的减少。所以这里不适合一致性hash。

扩容方案可以跟dba讨论细节,通常规划是分表后一年内规划好容量,不再进行扩容。


如果是在同一个库,单表的数据量少了,数据库级别的IO还是有的。所以通常更建议是拆分到不同的库。


优点:

       1. 不存在单库大数据,高并发的性能瓶颈。         
        2. 按照合理拆分规则拆分,join操作基本避免跨库。

缺点:

      1. 分片事务一致性难以解决。

      2. 数据多次扩展难度跟维护量极大。每次扩容2倍,比如:8,16,32这种

四 水平拆分相关

拆分原则
    
        1. 尽量不拆分,架构是进化而来,不是一蹴而就。(SOA)
        2. 最大可能的找到最合适的切分维度。
        3. 由于数据库中间件对数据Join 实现的优劣难以把握,而且实现高性能难度极大,业务读取  尽量少使用多表Join -尽量通过数据冗余,分组避免数据垮库多表join。
        4. 尽量避免分布式事务。
        5. 单表拆分到数据1000万以内。

切分方案
    
        范围、 枚举、 时间、 取模、 哈希、 指定等

考虑因素:

历史数据
写多都少
越近日期查询越频繁?
什么业务数据?重不重要?
有没有大规模分析查询?
数据量多大?
保留多久?
机器资源有多少?

分布式全局唯一ID

而在分库分表的环境中,数据分布在不同的分片上,不能再借助数据库自增长特性直接生成,否则会造成不同分片上的数据表主键会重复。

常见的id生成算法:

UUID、snowflake等。

补充一句,这里需要自己评估效果,比如snowflake,除了机器数,时间因素等。生成的唯一id要测试,比如考虑到时间到毫秒,生成的id偶数多,这样情况不处理直接取模水平拆分就容易不均匀。

还要考虑多对多情况下,如何设计拆分原则。比如订单id最好包含uid,即使按照Oderid拆分的情况下,同一用户的订单会落到同一个库,不会宽阔查询,这需要一开始的情况就要设计好。

参考沈剑老师的文章:https://blog.csdn.net/qq_18145031/article/details/77867853

扩库的问题不展开说了,查询,函数都需要关注。

五 相关开源组件

这里离不开最原始的jdbc,

  • jdbc层:实现复杂,属于轻量级,对应用基本没有侵入性;缺点是跨库事务不如mycat强大。类似当当网的sharding-jdbc.
  • ORM层:比如蘑菇街TSharding框架封装mybatis,实现简单。缺点是必须依赖ORM层,侵入性比较大。
  • DBProxy层:如cobar和mycat,可以做到连接复用,性能不错,完全没侵入性。缺点是实现复杂,框架比较重,维护工作量大。
  • DAO层:实现简单,缺点是分表比较麻烦。美团的框架dbproxy,貌似发版本到0.25,最近大半年都没有维护新版本。

shardingjdbc使用客户端直连数据库,以jar包形式提供服务,未使用中间层,无需额外部署,无其他依赖,DBA也无需改变原有的运维方式,可理解为增强版的JDBC驱动,旧代码迁移成本几乎为零。满足目前业务需求,采用这个了。下一篇整理demo。

当当的开源地址:https://github.com/sharding-sphere/sharding-sphere

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值