也谈分库分表在实际应用的实践(上)

简介: 也谈分库分表在实际应用的实践(上)

作者介绍:张克欣,目前供职于招商银行信用卡中心,负责app营销平台的研发,曾经在易迅、腾讯、京东工作过,多年电商平台相关经验。


长久以来,自己一直是一个在技术和管理之间寻找平衡并不断摸爬滚打的人,自认为在易迅、腾讯、京东、招行的经历中,还是汲取了一些营养,大部分时间都是在获取和实践。 自我也深知贡献的重要性,但由于各种各样的原因和借口(简称懒癌),付诸指尖的并不多,就连之前答应右总文章也一直未能成行。 且自以为还算是个有追求之人,答应的事情势必要做到,否则终日惴惴不安,不能入睡。



约定共同语言: 个人不大喜欢去套用一些让人听不懂的专业名词,即使是在专业领域,相同的名词,不同人的理解也不尽相同,如果遇到一个和你理解一致的人,得之吾幸;如果遇到一个理解不一致的人,大家讨论半天,不在一个频道,完全没意义。 比如在分库分表的做法中,最常见的两个套路叫垂直拆分和水平拆分,百度了一把,真的是各种理解都有。 鉴于此,我尽量不用这些名词,如果非得用,我会尽量在这里先把注释写清楚。

  • [分布式事务]:基于支持两阶段提交协议的数据库,提供的跨应用及数据库的解决数据一致性解决方案。
  • [幂等]:为了保证保证数据一致性,在跨服务或者服务内部进行数据交换时,通过交换唯一ID来保证数据一致的机制。


1. 背景


1.1. 业务背景


笔者当时接手的业务是一个存量的业务,每日业务数据在百万的规模,查询和写的操作都比较频繁,读写比大概在。。。存量数据在几亿规模,在互联网行业,这个规模不算很大,但是业务也面临着快速增长,预期业务规模将有几个数量级的增长。


1.2. 系统背景


原有系统是属于一个单体大应用,业务数据也基本处于单表存取的情况,数据一致性靠强事务来保证,仅靠一个单库、单体应用来承担这个规模,用事务保证数据强一致性,性能方面已经捉襟见肘,彼时,数据中间件还不够完善,对业务支撑也有限,好在消息系统还算比较完善。


拆分前:


image.png


2. 策略


2.1. 原则



策略选择上,我们基于以下原则:


  • a. 尽量保留现有数据结构,减少迁移成本。


  • b. 在现有数据结构下,可以通过数据冗余,拿空间换时间。


  • c. 进行数据隔离。


  • d. 所有变更对外部系统透明,攘外必先安内,自己的问题解决后,再推动外部升级和迁移,并且提供兼容的迁移方案。


2.2. 分库策略


对于分库,我们基于业务按照业务领域进行了拆分,这个拆分不仅包括应用,也包括对应的数据库。具体业务不方便再次赘述,大致说说拆分的思路,基本是按照领域模型以及职责进行拆分,把相对独立,并且可以独立提供能力出来的部分拆出来,从数据库依赖转为服务依赖,粒度粗细看自己业务来定。这其中代价也是非常大的,也并非所有的业务都可以简单粗暴的这额直接来拆分。


领域的本质还是数据的拆分,是随着业务的复杂程度逐步沉淀下来的,比如电商系统的订单,在系统设计初期通常都只是一笔单子,包括支付、退换货状态甚至都在一起,随着业务的扩展,会把订单和售后单拆开,订单本身也会拆成订单和交易,订单本身也会拆成用户订单、后台订单、物流单、配送单、配送包裹等等,当然,这里写的都非常粗,写的是单,其实背后都是系统。总结下来有以下几个场景:


  • 可以直接从数据库依赖转为服务依赖:功能相对独立的部分,可以直接拆分,从数据库的操作,转为服务依赖,原来只需要考虑数据库的异常,现在要考虑的是对于网络异常的处理,同时对于写场景要考虑幂等的处理。


  • 部分数据交叉的场景: 体现在代码层面存在多个业务表之间存在关联操作的场景,这里用了操作,包括了读写,这种情况下,对于数据一致性的要求就比较高,同时也对业务处理流程有了较高的要求。


  • 复杂的业务场景: 对于在业务逻辑上下文有太多数据依赖的场景,改造原有的逻辑代价非常大,风险也非常高,这种情况我们选择了重写,按照新的结构来重写这部分逻辑,并根据业务场景,选择一定的策略来进入不同的新旧流程,一方面解耦,另一方面能够比较方便做灰度验证。


  • 跨库的数据一致性:


  1. 分布式事务:通常做法有分布式事务采用两阶段提交来保证,分布式事务如果有封装好的框架,对于开发使用来说,可能会简单很多,但是对于异常情况排查起来就会复杂很多,并且在我们的场景里,我们不仅是数据隔离,服务也做了拆分,分布式事务不太适合。


  1. 消息队列+幂等:基于服务的场景,我们觉得分布式事务不太适合我们,我们选择了比较土的方案,就是消息队列和幂等。我们把每一步的用户操作都做了详细分解,拆分出来每个上下文中最核心的操作,核心的操作同步处理,其余的都走消息,同时通过幂等来保证数据的一致性,其余写操作都基于事件广播,同时业务上下文中要处理好异步带来的副作用,无序性及延迟。


image.png




相关文章
|
7月前
|
Java 中间件 数据库连接
分库分表的4种方案
分库分表的4种方案
213 0
|
8月前
|
弹性计算 Java 关系型数据库
分库分表比较推荐的方案
ShardingSphere 绝对可以说是当前分库分表的首选!ShardingSphere 的功能完善,除了支持读写分离和分库分表,还提供分布式事务、数据库治理等功能。另外,ShardingSphere 的生态体系完善,社区活跃,文档完善,更新和发布比较频繁
117 0
|
4月前
|
数据库
分库分表是一种数据库优化方式
分库分表是一种数据库优化方式
30 1
|
6月前
|
SQL 缓存 关系型数据库
什么情况下需要考虑分库分表?
什么情况下需要考虑分库分表?
98 0
|
10月前
|
算法 测试技术 Apache
分库分表实战
分库分表实战
156 0
|
存储 SQL 运维
2、【ShardingSphere】做优化上来就分库分表?请慎重分库分表
读写分离,基本是目前商业开发最可靠的手段了。让我们有了更好的数据查询效率。最大的缺陷在于读写分离会增加MySQL服务器的预算。同时MySQL在高并发的情况下,slave也会有延迟,错误等。
218 0
|
存储 算法 数据库
一次难得的分库分表实践(上)
一次难得的分库分表实践
|
消息中间件 存储 Dubbo
一次难得的分库分表实践(下)
一次难得的分库分表实践