亿级流量架构之分布式事务思路及方法( 二 )


分库分表内容是数据切分(Sharding) , 以及切分后对数据的定位、整合 。具体来说, 数据切分就是将数据分散存储到多个数据库中 , 使得单一数据库中的数据量变小 , 通过扩充主机的数量缓解单一数据库性能问题 , 从而达到提升数据库操作性能的目的 。
数据切分根据其切分类型 , 可以分为两种方式:垂直(纵向)切分和水平(横向)切分 。
垂直拆分垂直切分常见有垂直分库和垂直分表两种,两种含义类似 。
垂直分库就是根据业务耦合性 , 将关联度低的不同表存储在不同的数据库 。做法与大系统拆分为多个小系统类似 , 按业务分类进行独立划分 。与"微服务治理"的做法相似 , 每个微服务使用单独的一个数据库 。如图:

亿级流量架构之分布式事务思路及方法

文章插图
 
垂直分表类似,例如将一张表包含一个人所有信息,例如姓名、身份证、性别、身高、体重、省、市、区、村、专业、G点等等,那么可以拆分成三个表:
第一个表只包含基本信息(姓名、身份证、性别、身高、体重);
第二个表包含籍贯信息(省、市、区、村);
第三个表包含学习信息(专业、G点) 。
垂直拆分优缺点垂直切分的优点:
  • 解决业务系统层面的耦合 , 业务清晰
  • 与微服务的治理类似 , 也能对不同业务的数据进行分级管理、维护、监控、扩展等
  • 高并发场景下 , 垂直切分一定程度的提升IO、数据库连接数、单机硬件资源的瓶颈
垂直切分的缺点:
  • 部分表无法join , 只能通过接口聚合方式解决 , 提升了开发的复杂度
  • 分布式事务处理复杂
  • 依然存在单表数据量过大的问题(需要水平切分)
水平拆分上面对数据库垂直拆分之后,如果某个库还是好大,比如存储的数据极其庞大,那么可以再对数据库进行水平的拆分:
亿级流量架构之分布式事务思路及方法

文章插图
 
上面的水平拆分时按照ID区间来切分 。例如:将userId为1~10000的记录分到第一个库 , 10001~20000的分到第二个库 , 以此类推 。某种意义上 , 某些系统中使用的"冷热数据分离" , 将一些使用较少的历史数据迁移到其他库中 , 业务功能上只提供热点数据的查询 , 也是类似的实践 。
除了上面按照用户ID区间拆分,也可以做Hash运算拆分,这儿就不详细展开了 。
水平拆分优缺点水平拆分优点在于:
  • 单表大小可控
  • 天然便于水平扩展 , 后期如果想对整个分片集群扩容时 , 只需要添加节点即可 , 无需对其他分片的数据进行迁移
  • 使用分片字段进行范围查找时 , 连续分片可快速定位分片进行快速查询 , 有效避免跨分片查询的问题 。
水平拆分缺点:
  • 热点数据成为性能瓶颈 。连续分片可能存在数据热点 , 例如按时间字段分片 , 有些分片存储最近时间段内的数据 , 可能会被频繁的读写 , 而有些分片存储的历史数据 , 则很少被查询
分库分表带来的问题分库分表能有效的缓解单机和单库带来的性能瓶颈和压力 , 突破网络IO、硬件资源、连接数的瓶颈 , 同时也带来了一些问题,前面说过,事务包含一组子操作,这些造作要么全部执行,要么全部不执行,但是分库之后,一个事务可能涉及多个数据库或者多个表扩库执行,而网络具有不稳定性,也就是事务执行难度加大,分表分库后事务为了与传统事务做出区别,叫做分布式事务(跨分片事务) 。
跨分片事务也是分布式事务 , 没有简单的方案 , 一般可使用"XA协议"和"两阶段提交"处理 。分布式事务能最大限度保证了数据库操作的原子性 。但在提交事务时需要协调多个节点 , 推后了提交事务的时间点 , 延长了事务的执行时间 。导致事务在访问共享资源时发生冲突或死锁的概率增高 。随着数据库节点的增多 , 这种趋势会越来越严重 , 从而成为系统在数据库层面上水平扩展的枷锁 。
最终一致性对于那些性能要求很高 , 但对一致性要求不高的系统 , 往往不苛求系统的实时一致性 , 只要在允许的时间段内达到最终一致性即可 , 可采用事务补偿的方式 。与事务在执行中发生错误后立即回滚的方式不同 , 事务补偿是一种事后检查补救的措施 , 一些常见的实现方法有:对数据进行对账检查 , 基于日志进行对比 , 定期同标准数据来源进行同步等等 。事务补偿还要结合业务系统来考虑 。


推荐阅读