2017 年 12 月 7 - 9 日,一年一度的中国大数据技术大会(BDTC 2017)在北京召开,作为国内最具影响力的大数据领域技术盛会之一,今年大会围绕“大数据与智能”的主题,对大数据时代社会各行业的智能化进程和行业实践展开深度分享与讨论。
在本次大会上,蚂蚁金服高级研究员、OceanBase 分布式关系数据库负责人阳振坤发表了主题为《OceanBase—互联网时代的关系数据库实践》的演讲。本文是此次演讲的精华内容集合。
阳振坤:有这么多人在周末还来听数据库的讲座确实令人很高兴,特别感谢周傲英老师的邀请,让我有这个机会介绍做数据库的一点点感受。我的内容主要是三块,先给大家介绍一下我们过去几年开始在做数据库时候中对原先数据库一点点的分析,原先数据库面临什么样的困难和问题;然后是我们的方案能解决一些什么问题;最后以现在蚂蚁 OceanBase 中高可用的方案为例和大家做一个分享。
关系数据库的发展现状
关系数据库经历了差不多四十年的发展,与新兴的互联网相比,完全可以算得上是一个古典领域。这个行业的特别之处在于它处在一个重要底层的位置上,几十年过去了市场和技术格局都没有太大的变化。关系数据库面临的很多挑战至今都还存在,比如作为 IT 三个核心之一:处理器、操作系统、数据库,技术和产品都非常具有挑战性,尤其是做出一个真正能用的产品。再比如关系数据库的稳定可靠与业务使用,只有当数据库稳定可靠了业务系统才会使用,但是如何证明数据库的稳定可靠呢?只有业务系统使用了才能证明,这是一个鸡生蛋蛋生鸡的逻辑。
也是因为这些原因关系数据库新陈代谢特别困难。要换一个数据库,尤其是换做事务处理的数据库,代价和风险都非常大,但是一般来说收益又比较小。各个数据库的技术思路总体上是差不多的,如果说希望做一个比前人便宜十倍的数据库,这非常非常困难。
关系数据库之痛首要的是高成本,从用户来说,不论是高端服务器还是高端存储还是数据库软件及服务,都非常昂贵。第二就是数据库难以扩展。对于经历了 9 年双十一的蚂蚁金服,每年都和银行一起面临着挑战,系统总容量支持了双十一那一天非常高的访问量,之后这些资源本质来讲就大量闲置了,这是一个很大的成本。第三点是数据库主库备库的一致性。凡是做过金融系统服务的人都知道,银行数据库主库出问题了怎么办?那就是恢复主库。如果恢复不起来,就要赶紧做人工对账,然后才用备库把服务继续进行下去。
熟悉数据库的人都知道有 ACID,数据库的理论里面我觉得这是一个遗憾,缺了一个东西就是可用性,这对于在生产中实际使用的底层基础设施是个很可怕的事情。大家说你肯定弄错了,数据库是我们今天 IT 信息领域可用性最高的东西之一,这句话说得没错,但是这种可用性不是数据库自身带来的。这里更多指的是服务器、存储系统这些东西带来的高可靠性,而不是数据库系统自身。数据库不管是理论还是实践在这方面都存在遗憾,我们需要把数据库依靠自身的可用性能力做好。但是反过来讲这也是我今天能站在这里的原因,如果数据库理论研究早就做了高可用,可能今天我就没有机会站在这里。刚刚还提到了主库备库数据不一致,有人跟我辩论过,理论上能做到,但是不是在一个你可以接受的成本的情况下做到的。
今天数据库做数据增删改的时候,本质上原地更新,原地更新的性能,根本上是取决于磁盘的随机写性能,大家可以通过加内存做很多缓解,但从根本上还是逃不掉这一点。做数据库首先需要解决这一点,如果不解决就算把硬件成本降下来,但是性能没有提升,最终也没有活路。
关系数据库这些问题其实它们一直存在,但是在互联网比如说在双十一购物节之前它不突出,量变没有产生质变,但双十一的超大规模交易一下子把这些缺陷从量变变成质变。双十一刚开始的头一两年,交易并发量是从几千到几万,而现在是百万甚至千万。互联网把原来的关系数据库的缺陷千万倍地放大,放大到由量变到质变的地步。
OceanBase 解决方案
有了这些分析,我们就明确了 OceanBase 需要解决的问题:第一,通过分布式具备弹性能力并降低成本,这有可能带来十倍甚至更大的性价比的优势,并且能够水平地扩容和缩容。这一点我们刚刚入门,也有很长的路要走。第二点是并不完全依赖于或者并不依赖于硬盘的能力做到高性能,写事务(增删改)其实是数据库一个硬指标,所以我们对写来说做到了除了写日志没有别的硬盘操作。第三个是我们今天的重点,通过多库多活达到高可用和强一致。既要保证性价比也要保证可用性。因我们给自己设定了更高目标,只有超越前人才有机会在市场当中占领一席之地。
接下来我们看看传统主备镜像下主库备库一致性和可用性之间的矛盾:要保证备库与主库的数据一致,那么每一笔事务都需要实时从主库同步到备库后才能应答客户,那么一旦主库备库之间的网络异常或者备库异常,主库的写入就无法进行,即可用性失去了,这就是一个矛盾,主备一致性与服务可用性的矛盾。金融行业、证券行业要求数据千万不能丢,即使是那些能丢的行业也会产生许多麻烦,因为你会影响客户,影响业务,所以就逼着数据库这么多年来一直用高可靠的硬件来减少出故障的几率。单个硬件可以做到很高的可用性,比如五个九,但成本也会非常非常高。
OceanBase 高可用的关键是通过事务日志的多数派。在 OceanBase 之前,主库是人工指定的,我们就设定这个库是主库,然后它就会一直工作,直到它故障或者人工改变它。但在 OceanBase 里,所有主库都是机器自动选举出来的。与传统的主备镜像是一主一备不同,OceanBase 采用了一主多备,比如一主两备共三个库,主库执行事务,并把事务日志同步到备库,备库接收事务日志并应答主库(投票)。每一笔事务,只有其日志同步到所有库中超过半数的库,这个事务才真正成功(应答客户)。一主两备这种情况之下,我们允许任何一台机器故障,因为每一笔提交的事务,在剩下的两台机器中至少一台上存在,这样保证了事务不会丢失,并且业务也不停顿。
三个库通常部署在三个机房,其中通常有两个机房是部署应用程序的,这也是故障恢复的需要:主机房故障后备机房的应用程序和数据库可以继续提供服务。备库除了接收事务日志外,还要回放事务日志,这样万一主库坏了,它可以马上升级成主库继续提供服务,而且不会有任何的数据损失。检查并且确定主库故障需要一段时间,然后选举出新的主库也需要一段时间,最坏情况下总共要二十多秒,但也只是一台机器所在的主库会停这么一段时间。如果是备库出了故障,影响就更小,我们会在一定的时间之后就开始把在它上面的数据复制出去,以防万一再坏一台。
也许有人问,PC 服务器这么 low,万一坏了两台怎么办?这真的是非常好的问题,确实也有坏两台的,解决这个问题的办法是采用一主四备五个库,日志到达三个库事务才成功。
在 OceanBase 的主库选举上起初我们也想过通过分布式锁服务来实现,但是有一件事情阻止我们这样做,比如支付宝内部系统用这样一个服务,这个服务通过分布式选举也是能够恢复的,比如二十多秒就能恢复,但它在恢复期间对整个支付宝可用性的影响太大了。现在几千台机器,坏一台只是影响几百分之一,但是分布式锁服务停二十秒,有可能整个系统都要停二十多秒,这个对用户有非常大的影响,权衡这个利弊我们没有通过分布式锁服务来选举主备库,解决方案是每个库都在独立运行和选举的,一台机器坏了就是影响百分之一,它的影响会小的多。我们还实现了基于优先级的分布式选举,使得正常情况下主库在我们期望的机房,这可以提升效率并且便于管理。
分布式选举投票协议 Paxos 有一个简化的实现叫 Raft,由于实现简单,现在一些数据库就采用了它。OceanBase 0.5 在 2013 年底开发时也采用了类似的方法,但在 OceanBase 1.0 的时候,我们实现了真正的 Paxos,因为我们发现了类似于 Raft 的协议存在的性能瓶颈:因为 Raft 要求严格按照顺序对事务日志进行投票,而每一台机器都是多个线程在处理事务,网络收发包也是多个线程,很难保证这个严格的顺序,比如一台备机已经收到了事务四五六七八的日志,但因为没有收到事务三的日志,所以后续的四五六七八的日志也不能投票,这就像一个流水线被打断了。
2017 年开始我们在一部分核心系统中实施三地五中心的方案,这么多年来蚂蚁金服一直在努力做到任何一个城市机房真的出故障了,我们不停业务。今天仍然没有完全做到,重要原因是数据库。我们现在一部分核心系统已经开始做跨城市部署。在三个城市的五个机房里面,我们主库可以部署在其中四个机房里,这样能看到我们机器利用率其实比较高,达到 80%(传统的主备镜像只有 50%的利用率)。这样做的好处是当真的某个城市故障了,或者整个城市交换机的出口异常了,我们的业务还能够继续,既不需要人工的干预,也不会有数据上的丢失。
到这个阶段系统可用性是不是就非常完善了呢,其实可能还是不够的,有些情况下数据库的读请求非常多,我们需要单独的读库。读库没有选举权也没有被选举权,它的数据有略微的延时,但是它能够提供读服务。在特殊情况下,读库可以作为应急来用。读库还有其他作用,比如机房搬迁或者在某个地方增加一个机房,我们可以在新机房先建一个读库,因为这样整个都是自动化,会把数据、日志复制等这些事情都自动做好,完成后就可以把读库升级成备库。还有一种情况作为异地的灾备,比如主库备库都在一个城市的情况下,可以在另一个城市建立读库作为灾备。
蚂蚁金服到现在为止所有的核心系统今年双十一之前已经全部搬到 OceanBase 上,以前部分系统还有商业数据库兜底,但今年连兜底也没有了。万一有极端的意外导致系统不可用怎么办呢?我们还有一个机制即 Failover 库,它可以避免我们业务的停顿:当前系统因为某种特别的原因不可用的时候,就可以把业务的访问推送到 Failover 库,这保证了业务的可用。
多库多活可以提升服务器利用率,比如写五份日志需要五台机器,看起来似乎有一定的浪费。事实上,我们的机器利用率反而提高了,传统的主库备库是两个实体,它们只有一个库对外提供服务;OceanBase 虽然有五个库,但它们是一个实体,可以相互协调共同对外提供服务。比如三个库的情况下,可以有三分之二机器提供服务,五个库的情况下,则可以是 80%机器提供服务。
另一个好处是通过多库多活提升数据的压缩倍率。数据库今天数据量越来越大,存储的成本也越来越高,为了降低成本,用户希望对数据做一些压缩,但又不希望影响性能。传统数据库也有数据压缩的能力,但它是在提供服务过程中进行数据压缩的,但在业务的高峰期,CPU 可能非常紧张,能够用来进行数据压缩的 CPU 资源非常有限,无法进行复杂的数据压缩。我们的数据压缩是在业务的相对低谷期完成,并且在压缩前我们会自动把主库推走,这样整个机器就都空闲下来了,这样就可以进行比较复杂同时压缩倍率更高的数据压缩,只要解压缩足够快。
当年做 OceanBase 这个项目的时候,最大的担心是没做出来之前被拍死掉,因为从头做一个数据库需要很多年时间来做,你没有做出来之前被拍死的机率太高,所以我们还算运气。我们 2010 年开始做,从 2013 年蚂蚁金服决定把 OceanBase 用到交易系统上,2016 年账务系统正式上线,我们总共花了四年的时间把核心系统全部上线。数据库是一个非常重要又非常复杂的系统,稳定可靠非常关键却又非常困难,这样一个复杂的系统只能在使用中逐步成熟,所以阿里巴巴/蚂蚁金服成千上万的业务数据库对 OceanBase 非常关键:这么多的数据库系统,我们总能够找到一些运行 OceanBase,让 OceanBase 逐步成熟起来。今天成百上千的系统一天 24 小时跑在 OceanBase 上,有了这么多业务在验证和帮助,所以 OceanBase 数据库才能变得越来越成熟,越来越稳定。2017 年我们开始向公司外面走,因为我们觉得我们应该把这些年的积累赋能给银行等金融行业客户,像现在浙商银行、南京银行都已经开始用了,这给他们非常多的成本节省。最关键是容量随时可以扩大和缩小。
未来优化还有很长的路要走。也感谢现场所有人对数据库发展的支持。
本文转载自公众号蚂蚁金服科技(ID:Ant-Techfin)。
原文链接:
https://mp.weixin.qq.com/s/GB6P13YeR--t1wbcdcQh9Q
评论