饿了么经过了10年的发展,日订单量从几十万到了千万,数据增长如此之快,数据库管理人员如何保障业务快速发展,实现高可用以及数据安全并且提高运维效率呢?本文中饿了么数据技术部负责人虢国飞就为大家揭晓答案。
饿了么的数据库需求背景
对于创业公司或者高速发展的行业而言,访问量或者数据量都是呈指数级别地上升的,饿了么也是其中的一个案例。那么在业务数据增长如此之快的情况下,如何保证数据库的容量、高可用、数据安全以及运维的效率呢?
这次分享主要谈以下几点:首先需要有好的数据架构,这样能够保证容量的充足;其次需要提高数据库的可用性,以及对于数据流的控制和对于数据安全的保证,再有就是如何高效地完成大规模的数据运维,最后一点就是应该如何充分借助阿里云的力量。
可能大家对于饿了么的了解也是在最近三四年的时间,但是饿了么已经创办10年了。在2015年的时候,饿了么每天也就只有几十万个订单,而到了2016年因为出现O2O热点,订单规模就到了每天百万级,到2016年底,每日订单量就到了8、9百万,并且有了上百万的商户。2017年到现在,无论是订单还是运单都是每天千万级别的规模,还有几百万商户加上百万骑手。整个链路还是比较深的,我们称之为“CBD”,所谓“C”就是用户,“B”就是商户,“D”就是物流。整个的链条非常长,每个环节都是千万级的规模,因此沉淀的数据也是非常大的。
饿了么数据库架构演进之路
那么饿了么数据库架构是如何演进的呢?首先在2015年~2016年,订单从几十万到了几百万,饿了么就做了数据库垂直拆分的方案。对于核心系统,预估它有多少QPS和TPS,原有的数据库架构无法支撑这样量级,就需要对于业务中相对独立的模块进行拆分,这样就可以用多套环境来支持访问压力,在这个结构下就支撑了两三百万单的规模。但是到了2016年,从业务预估的趋势来看,这套架构系统将会很快再次面临这样的瓶颈。为了解决容量的问题需要过渡到下一个阶段,就是把数据库的核心表进行水平的切分。因为垂直拆分是无法突破核心系统的瓶颈的,为了支撑上面的容量,那么就必须对核心的表进行拆解分压。一张逻辑表可能拆分成数千张小表,这样就能够保证核心系统的压力能够合理地分散到多张表不同集群中去,为业务的发展提供了比较好的底层技术扩容支持。
但是这样就足够了吗?在2017年的时候,饿了么数据库架构底层也面临新的问题,虽然能够在技术层面支撑技术扩容,但是机房的容量却是有限的,能放入的机器数量是有限的,此时瓶颈就又出现了。因此,在2017年饿了么做了“多活”的架构,可以用多个机房来支持业务发展。
在这个过程中,有两个与数据库紧密相关的组件。一个是自研的DB Proxy层面的DAL组件,它主要完成了分表和分库的功能,通过这个组件就实现了底层数据的切片扩容以及读写分离功能,在它上面还实现了连接池和连接隔离,还可以对数据层做更多的保护,比如销峰、限流以及黑白名单等机制。另外业务上可能有多维度分表需求,比如对于饿了么订单而言,有商户维度,也有用户维度,当下单的时候他们都是高频操作,此时就需要实现多维的切片,既满足用户也满足商户。当然,DAL组件对于业务也有一定的侵入性,会要求限制某些SQL的操作。
第二个重要的组件就是在做多活的时候有一个跨机房的数据同步的DRC组件,其主要实现的功能就是监控机房的数据变更,也就是BinLog的变化,再将这些变化Push到对端的机房中去,这样就能完成跨机房的数据同步,还可以做数据压缩、回放、幂等的处理以及过滤传输的工作,相对于MySQL原生的数据同步而言会有很大的优势。
当解决了容量的瓶颈之后,对于网站或者数据库而言,还需要提升整体的可用性。这里可以从几个大层面来讲,首先任何的机器和设备都可能出问题,好的HA方案是必备的,饿了么使用开源的MHA,但是也做了相应的封装和改造,保证当主库挂掉的时候能够快速切换和批量管理,也能够完成各个组件之间消息的通讯(改造后我们叫EMHA),这样就解决了单台机器出现问题时造成的可用性问题。第二种提升可用性的方式就是将核心业务分为多片,当单片数据出问题,对于业务的影响就是1/N,所以也提升了整体可用性。此外,通过异地多活带来了机房级别或者地域级别的可用性,同时也给大型的维护操作提供了Online的支持。
下面看下数据流,首先需要对它足够可控,流入的数据需要确保是没有风险的,对于数据流异常过大的时候能对底层环境进行相应的保护。在DAL组件中就可做这样的工作,包括有风险的SQL语句就需要被拒绝掉。当数据进入之后,在落地的时候需要有一些规则和规范,这样就能保证数据的高效性。还有资源需要进行相应的隔离,不能因为因为某一业务的问题导致其他业务出现问题。再有在数据处理完成之后,需要将数据及时推送给其他的消费方进行消费,比较典型的就是搜索和大数据。比方对于大数据而言,之前抽取数据做报表的时效性非常低,而通过DRC组件的消息订阅能够做到分钟甚至秒级别的延迟,及时地看到业务数据变化。最后一点就是落地的数据在很多时候需要与其他环境互通,如经常需要从开发向测试导入数据,此时需要给出一些数据导出规范,对于一些敏感内容需要进行脱敏和过滤。
解决完容量、可用性以及数据流的问题,可以看到有很多组件出现。在大规模数据的情况下,如果没有相应的流程规范支持以及运维效率工具,是很再通过人力进行数据库维护的。这里我抽取了一些在做数据库运维时可能会频繁遇到的关键点。比如SQL治理,前期SQL在建表以及编写的过程中需要有一个自动审核机制,保证符合规则以及设计高效率原则。另外,上到生产环境的SQL就必须要有对应的SQL跟踪监控机制,能够及时发现有问题的SQL。此外,对于数据库变更和发布而言,饿了么多的时候每天可能有几百个DDL表的变更,前期DBA压力比较大,后面我们实现了研发自助发布的平台,DBA就不需要参与发布的过程了,但是需要保证平台的稳定和发布风险可控。还有冷热数据的分离,在生产环境中存放数据的硬件成本都是很高的,因此需要进行数据的冷热分离,将用户经常访问的数据留在生产环境中,而将不经常访问的数据转移到比较便宜的存储上面去,实现数据归档,保证生产的高效和成本降低,目前这一块我们平台也让研发能够自助了。为了保证数据安全,饿了么实现了数据备份救援的系统,包含自动备份、闪回和备份自动验证等功能。此外,还有需求就是经常需要做数据迁移,因此我们研发了D-Bus工具,DBA只需要配置好规则,系统就能自动进行数据搬迁了。
数据库架构演进之后仍然存在的问题
以上就是饿了么在处理数据这部分所做的一些关键点。其实,以上对于问题的解决目前来看仍然是存在很多问题的。首先,投入非常大,无论是DAL还是DRC组件的设计研发再到成熟运行所花费的成本非常高,投入的资源、人员以及验证周期花费都非常高;整体来看目前运转效率和利用率并不是非常高,在业务的高峰时资源需要加入进去,但是在业务低谷时却退不下来,所以就使得业务低峰时利用率非常低,并且伸缩性也非常差。此外,新技术的迭代非常快,而饿了么并不具备技术的规模效应,一些技术问题可能代价过高自身难以解决。饿了么目前期望是资源随时要随时有,可以弹性伸缩,有足够丰富的生态来支持,维护简单并且使用的产品有相应的规模效应,经过了大规模的验证。
饿了么如今已经成为了阿里云的重度用户,首先目前我们的开发测试环境完全基于阿里云,因为需求提出很快,但是生命周期很短。其次由于饿了么的业务特点就是中午和晚上是两个订单的尖峰,所以资源在高峰时需求比较大,但是高峰过了之后就相对平缓,因此饿了么希望通过云的能力实现弹性扩缩容,提高资源利用率。再次我们目前的多活架构实现很大部分也是在阿里云的机房中的,使用阿里云机房的好处就是能逐步地调整在阿里云上的流量,而不用一开始就投入大量的资源,稳定后就可以逐步让云承载主要的流量,最终成为主力节点。最后虽然饿了么做了很多的组件和产品,但是对于阿里云的产品而言其实只是一个子集而已,整套的解决方案在阿里云上都能找到。对于高速发展的行业而言,大多数公司技术还是为业务服务的,不能够让技术成为限制业务发展的阻碍,而应该让技术快速满足业务发展需求,促进业务更快发展,所以云的成熟方案应该是性价比很高的选择。