数据库

支付宝双11的功臣-分布式关系型数据库(oceanbase)

2016-12-09  本文已影响775人  馟苏

我们都知道阿里双11,除了创造了世界史上的交易奇迹之外,也创造了世界技术史上的奇迹。支付宝的峰值达到了每秒12万笔,这在技术界简直是一个奇迹。为什么说他是一个奇迹呢?简单的来解释一下:其实在日常开发中,打交道最多的就是数据库,好多开发都戏称只会增、删、改。但是千万不要小看增、删、改,因为假设你只有一个用户访问的你的数据库,你怎么写都可以,但是如果有几十万,上百万,上千万,乃至上亿用户呢?如果操作不当,那么你的数据库一定会down掉。所以看上去简单的东西其实一点都不简单,就好像风清扬一样,简单的剑招却蕴含着上千变化。

这里,我主要想揭秘下oceanbase,因为整个支付宝的交易的库都是依赖于它。oceanbase究竟是什么?用官方的话是这样的:OceanBase是一个支持海量数据的高性能分布式数据库系统,实现了数千亿条记录、数百TB数据上的跨行跨表事务,由淘宝核心系统研发部、运维、DBA、广告、应用研发等部门共同完成。那么以前在没有使用ob之前,支付宝都用的什么呢?mysql或者oracle。这两个一个是开源的数据库,一个是甲骨文公司的商业付费数据库。简单的来说都是人家老外搞得!其实这两个数据库已经很强大了,支付宝以前的框架都是基于这两种数据库的。但是随着业务的发展,这两种数据库也带来了弊端。

-------------------------------------------------------------华丽的分割线-------------------------------------------------------------

假设我们要撑起上千万的并发量,上百PB,乃至TB的数据量。如何设计?

方案一、单库(热备)

这个方案完全不行,原因不多说了。

方案二、数据拆分(分库分表)

按照业务特点将数据拆分:

垂直拆分以及水平拆分------比如说利用用户的user_id通过hash取模,然后路由到不同的分区。

这么做带来的问题有两个:1、当数据/负载增加时,需要人工介入,代价非常大。

2、select查询有时候需要便利所有的分区,速度非常慢。

3、每一台机器都要主从同步,管理起来太麻烦。

方案三、参考google的bigtable

主要是将一个bigtable拆分成几百万个子表(主键有序)。

好处:1、数据不会丢失(hdfs),故障迁移,可扩展。2、子表有序,查询快。

这样的话,方案就生成了,参考bigtable,在hbase的开源基础上自己开发一套。后来经过验证发现不行,因为,首先hbase的开源不彻底,每台单机支持的数据有限,然后是必须引入分布式事务2PC,一般时间在2~5s左右,因为对于hbase这种nosql只保证单行事务,如果要跨行跨表操作是支持不了的。并且分布式事务太耗时,所以这个方案只能抛弃!

在设计oceanbase的时候,目标是支持10w+tps,100w+qps,100TB+数据,难道没有方案了么?-------------------------------------------------------------华丽的分割线-------------------------------------------------------------

既要有非关系数据库的海量数据存储,还要有关系型数据库的事务,到底如何该解决呢?

经过数据分析,发现了隐藏在数据中的一个秘密:虽然业务线的数据量庞大,但是修改量实际很少。这个怎么理解。

我打个比喻:

1、人口基数实际上非常大,但是考虑到出生/死亡/失踪,这部分人口实际上在总人口中占比很小。

2、金融账务系统每天要记录很多的流水,但是考虑到一半在线上保存一年的流水,那么每天新增的几乎占比很小。

3、金融交易系统每天虽然要记录很多交易,但是考虑到一半都保存一年以上的交易记录,那么新增的占比很小的。

这就是隐藏在数据中的秘密!

其实大部分的数据,都是基数大,新增,删除,修改量占比不大。

那么可以这么解决。采用单台服务器记录最近一段时间的修改增量(内存中记录),而以前的数据不变(基线数据)。写事务只在单台服务器写,避免了2PC,高效的实现了跨行跨表事务。然后定期合并修改增量到基线数据服务器。

-------------------------------------------------------------华丽的分割线-------------------------------------------------------------

基于上面描述,OB整个系统架构:

整个ob集群包括:rootserver,updateserver,chunkserver,mergeserver这几个类服务器。

client:与mysql兼容,协议相同。

rootserver:管理集群,子表,数据分布,副本。分为主,副(主备数据同步)

updateserver:存储ob中的增量数据(内存)主备

chunkserver:存储基线数据

mergeserver:接受sql,解析,优化,转发给chunkserver或者updateserver,合并结果给客户端。

接下来我们来深入探讨一下:

首先ob部署在多个机房,每个机房一个ob集群。

客户端的请求过程:

1、请求rootserver获取ob集群中的mergeserver列表

2、按照一定策略选择mergeserver

3、请求失败后,重新选择一台mergeserver,如果某一台被请求失败超过一定次数,拉黑。

oceanbase集群会根据路由规则控制流量比,所以不用担心负载的问题。

ob中的基线数据按照主键排序(查询非常快)并划分为子表(每一个256M),并且都有副本。而在rootserver中记录了每个子表在chunkserver的位置。

mergeserver会缓存子表的分部信息,根据请求转发给该子表所在的chunkserver,如果写操作还会转发给updateserver。

在chunkserver中,一般存储子表,而一个子表由多个sstable过程,每个sstable的容量4k~64(主键有序)。

合并操作:

oceanbase定期触发合并/数据分发操作,chunkserver会从updateserver中获取一段时间更新的操作。(业务低谷时操作)

updateserver:

更新操作写入内存,当内存数据量超过一定值时,生成快照存储在SSD中。

定期合并/数据分发:把updateserver增量更新分发到chunkserver中。

1、updateserver冻结当前的活跃的内存表(Active Memory),生成冻结内存表,开启新的活跃内存表后,缓存更新操作写入新的活跃内存表。

2、updateserver通知rootserver数据版本变化,rootserver心跳通知chunkserver。

3、每台chunkserver启动定期合并或数据分发,从updateserver获取每个子表对应的增量更新数据。

为什么分为定期合并和数据分发?

定期合并:chunkserver讲本地sstable中的基线数据与冻结内存表中的增量更新数据归并,生成新的sstable。(因为合并操作对服务器性能影响非常大,需要在业务低估时进行)

数据分发:chunkserver将updateserver中的冻结内存表中的增量缓存到本地。(不受业务高峰限制)

以上就是我对ob的原理的总结,其中也看出一些问题,首先updateserver需要非常大的内存,第二为了避免单点,应该是主备切换,这里面用了zookeeper中的paxos算法,选举主机。整个ob还是非常复杂的,如果想深入探究还需要花费很大的功夫啊!

上一篇下一篇

猜你喜欢

热点阅读