OceanBase的变化

jopen 12年前
     <p> <strong>OceanBase 面临的新挑战</strong></p>    <p> 随着 OceanBase(以下简称 OB)在淘宝的应用越来越广泛,前端对数据的需求也提出了越来越严苛的要求。在应用系统和开发团队的配合下,给用户提供了很多额外的功能,给用户带来方便的同时,也给 OB 带来了很多的挑战。</p>    <p> 以淘宝的收藏夹应用为例,从4月份上线到现在,我们增加了2倍的数据表,数据量(包括数据条目和每日更新条目)是上线初期的4倍,访问量是上线初期的8倍以上。尤其是每年一度的1111光棍节,这一天不只是中国的网购节日,对淘宝各个应用及底层系统都是一次技术大考,OB 也不例外,我们需要为应用系统准备3倍以上的流量空间。当然,我们不能在活动前一天非常豪迈的对 IT 部的同事说:上三倍服务器!尤其是 OB 的架构中存在一个公认的单点——UpdateServer(以下简称 UPS)的情况下。最近一段时间,我们想了很多的办法来提升系统的可扩展性和弱化瓶颈。</p>    <p> <strong>OB0.2.1的发布</strong></p>    <p> 这里请注意,我们摆了一个乌龙,假如你看到开源分支上出现了0.2.1和0.2.2两个版本的话,0.2.1其实是更新的,它包含了0.2.2版本的所有功能。这两个版本的规划和应用需求的急迫程度有偏差,造成的结果就是版本较小的更晚发布,你完全可以直接了解0.2.1版本!</p>    <p> 在0.2.1版本中,从功能和架构方面来看,我们主要做了以下这些更新。</p>    <p> <strong>UPS 支持转储</strong></p>    <p> 这是一个很重要的新特性,将 UPS 内存中的数据 DUMP 到 SSD 设备的 SStable 中。通过转储,释放更新数据内存占用,同时 SStable 在 SSD 设备上也能提供可以接受的读取性能,基本上解决了线上应用更新量的瓶颈。这个新特性已经应用在淘宝的多个应用中,更新量最大的一个应用每天每个 UPS 接受500GB 的更新数据。</p>    <p> <strong>支持按列存储</strong></p>    <p> 我们提供了类似 column family 的机制,支持少量数据独立存储在一起,减少整行存储访问过程中可能带来的 IO 读取量放大。实现的方法有点特别,欢迎大家在代码中发现。</p>    <p> <strong>查询功能增强</strong></p>    <p> OB 现阶段通过服务端数据过滤的方式实现了文本的 like,实现了一个比较高效的文本匹配算法。同时,在服务端使用多路归并的方法,实现了多个条件(条件之间是 AND 关系)的数据查询。</p>    <p> <strong>数据 DUMP</strong></p>    <p> OB 通过访问固定版本数据,实现了数据全量 DUMP,DUMP 出的数据可以根据配置吐出文本文件。通过解析 UPS 的 CommitLog,实现了数据增量 DUMP,增量 DUMP 的周期可以在秒级别。在已有的线上应用中,需要想淘宝数据仓库中提供的数据都已经通过 OB 进行了吐出,这些应用已经去除了对原有关系型数据库的依赖。</p>    <p> <strong>多机房</strong></p>    <p> OB 使用了一个单独的进程(我们称之为 lsync)解析 UPS 的 CommitLog,同时将其复制到另外一个机房的 OB 集群 UPS 上。而接受日志同步的 UPS 会进行数据回放,从而在两台乃至多台 UPS 之间保证数据更新的一致性。而 ChunkServer(以下称之为 CS)的数据是不变的,这样 OB 就保证了多个集群之间的数据一致性。由于数据同步采用异步进程,这些集群可以分布在同一个城市乃至异地。这种简单的机制保证了绝大部分情况下数据的容灾需求,主集群现在可以通过手工命令进行切换,同时为数据的分布读提供了基础(这点很重要,下面要讲的系统瓶颈优化有两个都依赖这个功能)。根据线上实际的应用情况,同城两个机房间的数据同步延时在毫秒级别。</p>    <p> <strong>系统瓶颈优化</strong></p>    <p> 0. 2.1 发布之后,根据运行情况和1111的要求,OB 又对这个版本进行了一些改造,主要针对线上出现的一些瓶颈。</p>    <p> <strong>双集群流量分布</strong></p>    <p> 我们改造了 OB 客户端,使之接受 OB 的 RootServer(以下简称为 RS)的调配,在两个集群之间灵活的按比例调配读取流量。我们先确定了一个固定长度的数组,例如100或者1000等等,并按照比例在这个数组中划出相应的比例对照不同的集群,读取请求将根据生成的一个随机数取模之后落到这个数组的哪一个位置决定到哪个集群访问,当然写流量和写之前有一致性要求的读还是集中在一个集群上的。原本规划的是多个集群流量分配,而不仅仅局限于两个。但由于时间比较紧,多个集群复杂的集群失效处理很难在短时间内稳定,而且经过评估单个集群的性能上限大大提高,远没有达到性能极限,所以就暂时采用了当前的简单方案。</p>    <p> <strong>单集群内读流量分布</strong></p>    <p> 我们改造了 OB 的 MergeServer(以下简称为 MS),使之接受 RS 的调配,在一个集群的多台 UPS 之间灵活的按比例调配读取流量,分配方法类似多集群之间流量分配,当然写流量以及写之前有一致性要求的读还是集中在一台 UPS 上的。同时为了降低基准数据和更新数据合并对 UPS 的负载,我们在 CS 端也实现了类似的机制,将合并的读取流量也按比例分配到了不同的 UPS 上。和上一个架构优化一起,这些流量调配都是可以在线调整的,这样提升了整个集群的读取扩展能力。由于 OB 的静态数据读取能力可以根据 CS 的扩展线性增长,而现在更新数据的读取能力也基本上能够根据集群数量和 UPS 数量做到线性扩展了,这样 OB 基本上就消除了读取数据的瓶颈,而这些对应用方都是透明的。</p>    <p> <strong>UPS 上行带宽优化</strong></p>    <p> 在前一段时间,线上应用出现了 UPS 上行带宽打满千兆的情况,将网卡使用方式变化为双 active 之后在短时间内再次接近预警值,不管我们有没有做上面的两个优化,这种情况都是应该改变的。通过分析,我们定位到了问题所在,采用了两个手段,首先减少了在内存的 memtable 中更新数据的版本数量,其次在每次 UPS 返回数据前都对进行了多次更新的字段进行了版本合并。通过这些优化,UPS 的上行带宽下降了40%以上,随着多集群和多 UPS 的上线,UPS 的网络出口瓶颈基本上也消除了。这个优化手段还带来了一些意外效果,UPS 的 CPU 使用率也下降了,可见原有的数据序列化方式 CPU 占用比较高,这是下一步优化的方向之一。</p>    <p> <strong>合并调度优化</strong></p>    <p> OB 的基准数据和动态数据合并是比较消耗性能的。通常来讲,我们总是能在一天中找到业务的低峰期进行合并,但在光棍节那天情况就会有所变化,为此我们对这个合并的调度机制进行了优化,从 CS 和 UPS 两端都进行了速度控制,在合并的同时保证不错的访问能力。同时,我们在多集群方案中加入了集群错峰合并的方法,保证在合并的时候有一个到多个集群拥有全部的服务能力,在线上我们实际验证了现有的合并调度机制,高峰期间集群仍表现良好。</p>    <p> <strong>UPS 转储文件的预热</strong></p>    <p> 前面已经提到 UPS 支持更新数据转储至持久化设备,当然我们通常使用 SSD,但 SSD 相对内存访问速度仍然有数量级的差距。为了进一步提升访问速度,我们设计了一套转储文件预热方案,利用数据转储为 SStable 之后尺寸大大减少的特点,我们可以用远小于 memtable 的内存将转储数据加载进来,也能提供接近内存的访问速度。当然,这个预热的内存大小是有限制的,实际上是利用 CS 原有的 BlockCache 机制,而且为了不至于一下子将访问扔到还很冷的 SSD 持久化数据,我们做了一个简单的流量逐步导入的机制,保证数据渐渐热起来。这套预热方案已经编码、测试完毕,但还没有在实际应用中使用,不过也快了,欢迎大家尝试。</p>    <p> <strong>下一步 OB 的方向</strong></p>    <p> 要做的东西还非常多,OB 只能根据应用的需求进行排序,同时兼顾架构的演进,下面是我们认为下个阶段比较重要的功能特性:</p>    <p> <strong>OB 的 restful web 接口</strong></p>    <p> OB 的接口现在还是比较难以使用的,同时有一个比较重的客户端,相信各位了解过开源 OB 的同学对此也深有体会吧,这个问题严重阻碍了 OB 的推广和发展。淘宝核心系统有国内很好的 Nginx 开发团队,我们会合作提供 OB 的 restful web 接口,第一步可能仅仅提供类似 get、put、delete、scan 等简单操作,时间大概是在2012年 Q1,后续将封装复杂操作,最终会把一些简单的 SQL 封装进来,时间大概是2012年 Q2。</p>    <p> <strong>OB 与其他开源产品的整合</strong></p>    <p> OB 作为分布式数据库,其读性能很大程度上依赖前端缓存,而缓存淘宝有自主开发的 TAIR,或者一些成熟的开源产品,例如 memcached、redis 等等。另外,数据库都提供有类似 blob 字段等较大数据的存储功能,而在 OB 中直接提供这种服务代价是比较昂贵的,淘宝有自主开发的分布式文件系统 TFS,比较适合提供这种存储服务。而对这两个功能加入,当然不会继续使用客户端的方式,这样会使应用开发成本越来越高,也越来越不灵活。</p>    <p> 在提供 OB 的 restful web 接口的同时,我们会将三种数据存储需求进行整合,用户将不再需要关注缓存数据同步、数据存储、数据备份等等麻烦的问题,数据将以服务化的方式提供,这个模型在2012年 Q2 的时候会有雏形,我们也会及时开源出来与大家分享。</p>    <p> <strong>OB 集成 MapReduce</strong></p>    <p> OB 当中现存在大量数据,这些数据都是要进入离线数据分析集群的,但有些分析工作数据同步的代价和所需的计算资源相比有些得不偿失,另外公用分析集群有自己通用的调度方式,有时候对应用的反应不够及时,而 OB 自身的存储方式也能支持小数据量(百G或T级别)的离线分析,这就催生了我们将经典的 MapReduce 模型引入的想法。</p>    <p> 拜 Hadoop 实现的灵活机制,我们可以方便地将 Hadoop MapReduce 架设到 OB 上,开发代价是实现几个数据输入输出函数,现在已经开展了一些工作,做了一些实验,后续会持续投入在这方面,2011年 Q4 会有一个简单的雏形出来,请大家提出宝贵意见。</p>    <p> <strong>在线的大数据量请求</strong></p>    <p> 有些在线应用需要大数据量的分析,例如百万级别的数据聚合、消重、公式计算等等,要求的时间效率在秒级别。这种需求不适用于M/R模型,简单的数据库运算又会有大表 join 的问题。OB 探索部分满足这个需求,也和相应的业务部门进行了合作,牵涉到的修改主要是数据并发访问、支持更丰富的 where 条件、运算函数、算法优化等等,原型已经有了,相对成熟的时候会放出来给大家,收集大家的意见和建议。</p>    <p> <strong>索引</strong></p>    <p> 在现在的 OB 架构中,索引部分功能由 Rowkey 替代,但总有一些需求是 Rowkey 无法满足的,现在我们的替代方案是建立冗余表并利用 OB 更新具有部分事务性的特点保证数据表和索引表的数据一致。这种方式对应用方非常不友好,尤其是应用方索引维护较多的情况下。OB 会在下一个阶段支持在线索引,时间点大概是在2012年 Q2。</p>    <p> <strong>更新能力扩展</strong></p>    <p> 如果数据更新可以放宽事务要求,OB 现在已经有了线上方案,有些应用已经接入多台 UPS 并行写入。后续将按照应用需求(包括大家的需求哦)决定是否支持分布式事务。</p>    <p> <strong>OB0.2.1将在11月更新到开源站点上,还有很多技术细节这里没有谈到,欢迎大家踊跃发掘,多提宝贵意见,谢谢!<br /> <br /> </strong>来自: <a id="link_source2" href="/misc/goto?guid=4958198934583070143" target="_blank">rdc.taobao.com</a><br /> </p>