加入收藏 | 设为首页 | 会员中心 | 我要投稿 辽源站长网 (https://www.0437zz.com/)- 云专线、云连接、智能数据、边缘计算、数据安全!
当前位置: 首页 > 站长学院 > MySql教程 > 正文

阿里巴巴数据库分库分表的实践

发布时间:2019-02-01 01:43:54 所属栏目:MySql教程 来源:钟华
导读:1、阿里巴巴分布式数据层平台发展和演变 业务数据从原来的单库单表模式变成了数据被拆分到多个数据库,甚至多个表中,如果在数据访问层做一下功能的封装和管控,所有分库分表的逻辑和数据的跨库操作都交给应用的开发人员来实现,则对开发人员的要求变得相

很多人对于全表扫描会有一些误解,甚至认为出现全表扫描对于系统来说是完全不能接受的。其实全表扫描在真实的业务场景中很难完全避免(也可以做到完全避免,但会带来其他方面的问题,后面会有说明),对于在分布式数据层的内存中进行数据量不大的聚合这类的SQL请求,如果不是高并发同时请求的情况下,比如对订单进行复杂的条件检索,如图5-9所示,就一定需要采用全表扫描的方式,将查询语句同时推送到后端的数据库中才能实现该场景的要求,但因为调用不会特别频繁,而且计算的数据量不会太大,所以整体不会给数据库整体性能带来太大的影响。

阿里巴巴数据库分库分表的实践

图5-9 订单搜索是典型的多条件查询场景

如果是高并发情况下同时请求的话,为了数据库整体的扩展能力,则要考虑下面描述的异构索引手段来避免这样的情况发生。对于在内存中要进行大数据量聚合操作和计算的SQL请求,如果这类SQL的不是大量并发或频繁调用的话,平台本身的性能影响也不会太大,如果这类SQL请求有并发或频繁访问的要求,则要考虑采用其他的平台来满足这一类场景的要求,比如Hadoop这类做大数据量离线分析的产品,如果应用对请求的实时性要求比较高,则可采用如内存数据库或HBase这类平台,这一部分的内容不在本书中讨论。

4、异构索引表尽量降低全表扫描频率

还是基于订单数据的分库分表场景,按照订单ID取模虽然很好地满足了订单数据均匀地保存在后端数据库中,但在买家查看自己订单的业务场景中,就出现了全表扫描的情况,而且买家查看自己订单的请求是非常频繁的,必然给数据库带来扩展或性能的问题,有违“尽量减少事务边界”这一原则。其实这类场景还有很多,比如卖家要查看与自己店铺相关的订单信息,同样也会出现上述所说的大量进行全表扫描的SQL请求。

针对这类场景问题,最常用的是采用“异构索引表”的方式解决,即采用异步机制将原表内的每一次创建或更新,都换另一个维度保存一份完整的数据表或索引表。本质上这是互联网公司很多时候都采用的一个解决思路:“拿空间换时间”。

也就是应用在创建或更新一条按照订单ID为分库分表键的订单数据时,也会再保存一份按照买家ID为分库分表键的订单索引数据,如图5-10所示,其结果就是同一买家的所有订单索引表都保存在同一数据库中,这就是给订单创建了异构索引表。

阿里巴巴数据库分库分表的实践

图5-10 订单异构索引表

这时再来看看买家test1在获取订单信息进行页面展现时,应用对于数据库的访问流程就发生了如图的5-11变化。

在有了订单索引表后,应用首先会通过当前买家ID(以图示中test1为例),首先到订单索引表中搜索出test1的所有订单索引表(步骤①),因为步骤②SQL请求中带了以buyer_ID的分库分表键,所以一次是效率最高的单库访问,获取到了买家test1的所有订单索引表列表并由DRDS返回到了前端应用(步骤③和④),应用在拿到返回的索引列表后,获取到订单的ID列表(1,5,8),在发送一次获取真正订单列表的请求(步骤⑤),同样在步骤⑥的SQL语句的条件中带了分库分表键order_ID的列表值,所以DRDS可以精确地将此SQL请求发送到后端包含in列表值中订单ID的数据库,而不会出现全表扫描的情况,最终通过两次访问效率最高的SQL请求代替了之前需要进行全表扫描的问题。

阿里巴巴数据库分库分表的实践

图5-11 基于订单索引表实现买家订单列表查看流程示意

这时你可能会指出,为什么不是将订单的完整数据按照买家ID维度进行一次分库保存,这样就只需要进行一次按买家ID维度进行数据库的访问就获取到订单的信息?这是一个好问题,其实淘宝的订单数据就是在异构索引表中全复制的,即订单按照买家ID维度进行分库分表的订单索引表跟以订单ID维度进行分库分表的订单表中的字段完全一样,这样确实避免了多一次的数据库访问。但一般来说,应用可能会按照多个维度创建多个异构索引表,比如为了避免买家查看自己的订单时频繁进行全表扫描,实际中还会以买家ID的维度进行异构索引表的建立,所以采用这样数据全复制的方法会带来大量的数据冗余,从而增加不少数据库存储成本。

另外,在某些场景中,在获取主业务表的列表时,可能需要依赖此业务表所在数据库的子业务表信息,比如订单示例中的主、子订单,因为是以订单ID的维度进行了分库分表,所以该订单相关的子订单、订单明细表都会保存在同一个数据库中,如果我们仅仅是对主订单信息做了数据全复制的异构保存,还是通过一次对这张异构表的数据进行查询获取包含了子订单信息的订单列表时,就会出现跨库join的问题,其对分布式数据层带来的不良影响其实跟之前所说的全表扫描是一样的。所以我们还是建议采用仅仅做异构索引表,而不是数据全复制,同时采用两次SQL请求的方式解决出现全表扫描的问题。

实现对数据的异步索引创建有多种实现方式,一种是从数据库层采用数据复制的方式实现;另一种是如图5-12所示在应用层实现,在这一层实现异构索引数据的创建,就必然会带来分布式事务的问题。

阿里巴巴数据库分库分表的实践

图5-12 精卫实现数据同步的流程图

(编辑:辽源站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

推荐文章
    热点阅读