勿谈大,且看Bloomberg的中数据处理平台



勿谈大,且看Bloomberg的中数据处理平台

     
摘要:中数据意味着数据体积已经超越单服务器处理的上限,但也无需使用数千台节点组成的集群——通常是TB级,而不是PB级的。这里,我们不妨走进Bloomberg的用例,着眼时间序列数据处理上的数据和体积挑战。

中数据意味着数据体积已经超越单服务器处理的上限,但也无需使用数千台节点组成的集群——通常是TB级,而不是PB级的。这里,我们不妨走进Bloomberg的用例,着眼时间序列数据处理上的数据和体积挑战。

以下为译文

在Bloomberg,我们并不存在大数据挑战。取而代之,系统正在遭遇“中数据(Medium data)”的威胁,而当下许多行业的机构基本上都面临着这种威胁。对Bloomberg来说,在企业级低延时场景下,Hadoop和Spark这样的系统既没有效率,也难以维护。时至今日,高核心数、SSD以及海量内存已并不稀奇,但是当下的大数据平台(通过搭建商用服务器集群)却并不能完全利用这些硬件的优势,存在的挑战也不可谓不大。同时,当下很多分布式组件也深受Java的影响,很难达到预期的低延时性能。

一个实际用例

债券时间序列数据通常包括一个债券(比如IBM)、一个字段(比如price)、一个时间和一个值。

通常情况下,数据会被拆分成两个部分:当天数据和历史数据——处理当天数据的系统通常会捕获一天中的所有行为,而处理历史数据的系统需要负责前一段时间所积累的数据。在过去,统一这两种数据是不可能实现的,因为他们有着不同的性能需求:当天数据的处理系统必须可以承受大量的写入操作,而历史数据处理系统通常是每天一次的批量更新,但是数据体积更大,而且搜索次数也更多。

在债券时间序列数据上,在总量为一年的数据上,某个字段的响应时间需要控制在5毫秒。同时,这些数据每天会被访问数十亿次,峰值期间大约50万每秒。对于Bloomberg来说,这个系统非常重要,一旦发生故障,很可能就会扰乱到资本市场。

问题随之而来,类似Portfolio Analytics等应用往往会同时需求大量的数据。一个债券组合很可能包括数以万计的债券,而类似归因(attribution)这种计算往往需要每个源每天40个字段的数据。从而,在多年数据上计算一个债券组合的归因需要上千万的数据点(datapoint)。因此,即使在命中率为99.9%的高效缓存中,仍然存在大量缓存未命中的情况。这样一来,如果底层系统使用磁盘介质的话,这个操作往往会造成成千上万的磁盘寻道。同时,基于用户的数量,系统中存在着大量的请求。因此,不难想象,这会给现有价格历史系统造成什么样的挑战。

数年前,解决这个问题的途径是将一切都放到内存和固态硬盘上,同时将高度压缩的blobs分割到多个数据库中。这是一个巨大的飞跃,系统速度提升了2到3个数量级,然而这并不是我们想要的——跨多数据库压缩blobs分割是非常麻烦的。

时间序列数据通常会转化为非常极端的并行问题,往往会出现这样一个情况:当为一个组合取数以千万计的数据点时,工作可以根据需求被任意拆分到数以千万的主机上。这样看来,并行似乎是最好的解决方案。而在单主表的分布式处理上,理论中HBase应该是个非常契合的计算框架。

当然从理论上讲,理论和实践应该是一致的,然而在实践中往往并不是一直如此。数据集确实可以达到一定的效果,但是在性能、效率、期满及弹性上都存在一定的障碍。这样一来,问题就在于如何移除这些障碍。

当一个节点发生故障后,数据并不会丢失——因为数据已经通过HDFS备份到多个节点上。但是这里仍然存在一个非常大的缺点,在任何给定时间,到给定region的读写操作只被一个region服务器控制。如果这个region挂掉,故障将会被发现,故障转移会自动的进行。但是,直到这个故障被处理前,它负责的任何读写都不可能继续进行。

在故障转移上,HBase社区的发展可以说是日新月异,需求的时间也是愈来愈少,但是这里仍然存在一个巨大的漏洞。分布式系统中的故障往往通过设置期满判定,通过心跳或者其他机制来感知。这样一来,如果超时被设置的太短,很可能就会产生误报,但是如果时间被设置太长,则会造成更长时间的不可用。


在Bloomberg用例下,SLA是毫秒级的。但是,超时的设置却是秒级的,这样一来,即使故障被侦测后的处理时间无限接近于0,HBase故障转移所造成的延时完全不可行。

在与多个Hadoop提供商交流后,我们也得到了几个可行的解决方案,其中大部分是通过给数据库做多个备份来解决问题。鉴于Bloomberg系统可以应对整个数据中心丢失的大方针,使用这个途径无疑需要给每个数据库配置多个同时运行的副本,在我们看来这么做太复杂了。最终,我们对这个替代方案并不满意,并决定尝试修改。

如果故障转移检测和恢复过程不能被加速,那么某个region服务器发生故障后,这里必须存在可以立刻被查询的备用节点。根据这个思路,我们拟定了短期解决方案:数据必须在多个不同的地方进行存储,虽然在传输上可能会存在一定的延时,但是在这种存在大量批处理更新场景的类似价格历史日结系统中却完全可行——在备用region服务器上使用这个策略可以保证事件接收的顺序,提供了时间序列上的一致性,即使延时很高。

时间序列一致性备份region服务器被作为JIRA-10070的一部分添加到HBase中。

结论和下一步

除下故障转移,HBase还存在大量其他的问题。仔细地检查了瓶颈的来源,进行了大量的优化后(比如使用同步垃圾回收机制),系统性能得到了显著提升:

  • PORT写入性能提升1000倍
  • Read检索速度较之前提升3倍

通过HBase实验,我们将运行时响应时间缩短到原来的四分之一,并为将来提升留下了足够的发展空间。同时,更快的机器也有利于缩短响应时间。通过使用开源平台,我们认真思索来自多个提供商的意见,在中型数据处理上,我们可以看到很大的发展空间。

更重要的是,我们的收获不只是性能一个特性,我们更可以通过开源技术连接到一个更广泛的发展空间。

附录:HBase分配图解

性能1:分布和并行


性能2:同址计算

即使故障得以解决,在原始性能和一致性上仍然存在问题,这里我们将详述性能上的3个实验和结果。实验应用在一个合适的集群上,拥有11台搭载SSD的主机,每台主机配备了两个志强E5处理器以及128GB内存。在讲义的右上角显示了两个数字,第一个是实验初始时的平均响应时间,另一个则是进行改进后的响应时间,平均请求时间来自20万个记录上做随机的键值查询。

使用HBase,用户可以在大的Portfolio文件上做拆分,并且分配到集群中的多个主机上进行处理。这也是为什么要托管备用的region服务器以应对故障——如果请求发送到每个服务器,其中一个服务器在1分钟或者更多的时间内没有反应,很明显这个服务器已经出现问题,一个服务器产生故障将拖累集群中所有作业的处理时间。

因此,下一个需要着重对待的就是分配和并行。第一个工作就是如何平均的将作业拆分:在一个指定的大数据集上,集群中每台机器获得的chunk大小都是相同的?理想状态中,对1000行的数据进行拆分,每台服务器都应该获得100行。然而在一个简单的架构中,这点根本无法实现:如果原始键是债券名+XXX,那么所有IBM债券将放在同一个region中,同时,IBM将比其他债券更经常得到访问,这种现象也被称为hotspotting。

解决方案是使用HBase提供的特性来弥补。HBase中的数据总会通过原始键进行物理划分,如果原始键本身已经被哈希,同时这种哈希被作为一个前缀,随后行则会以不同的方式进行分配。想象一下,如果原始键是security+year+month+field,取它的MD5,并将之作为一个前缀,那么IBM这个债券分配到任何服务器上的可能性都会相同。

在一个完美的分配中,我们将获得一个完美的并行性:集群中11个节点都会做相同数量的作业。每个工作不只是负责相同的工作量,在每个请求上也会同样平均。毫无疑问,这里需要做的是尽可能地提升系统并行性。

解决这个问题的一个方法就是在每台主机上运行尽量多的region服务器,因此需要尽量提升主机的性能。这将提升总的region服务器数量,从而提升并行性的等级,随之显著的减少响应时间。

讲义中的图表显示了这个实验的结果。如果11台服务器上每个只搭建一个region,总计11个,平均响应时间是260毫秒。当region数量提升到每台主机3个时,也就是总计33台主机,平均响应时间将下降到185毫秒。每台主机上5个region服务器将提升到160毫秒。但是如果每台主机上的region服务器提升到10个时,响应时间反而会提高,为什么?

出现这种问题后,首先想到的可能就是负载是否超过了服务器的性能;每台服务器同时运行10个region服务器进程,每个都拥有多个线程,显然核心数量会不足。但是,根据研究,这个并还不足以作为影响系统的原因,真实的答案非常有意思,但是在揭开它之前,我们先看一下同址计算。


大数据的原理之一就是让计算尽可能的靠近数据,这么做的理由非常简单。举个例子,如果你想知道一个大数据集表格中究竟有多少行,你可能需要将每一行都取到本地客户端,然后循环访问并进行计算,如果使用的是传统数据库环境,你还可以使用“select count(*) from…”,后者显然是更加有效的。

说永远比做容易。许多问题使用这个途径是无法解决的,即使在许多已知的情况下,许多框架都会出现问题。在海量数据分析上,2013年National Research Council(国家研究委员会)提出了7个大型并行计算问题,希望对分布式计算系统进行良好的分类,比较有意思的是,根据测算结果,Hadoop并不适合所有类型。

幸运的是,我们有一个简单的可用的用例,它可以再次减半响应时间。

现在的情况是,这里有数据的多个源,Barclays、Merrill Lynch和多个公司都提供了债券计价数据。相同债券同一天的数据也可能出现在其他源中,但是价格可能不一致。每个客户有不同的优先顺序,每个请求都包含了某个源应该用在某个订单的顺序。尝试从第一个数据源中获取所有数据,如果发现丢失,则会尝试下一个源。通常情况下,发现所有数据需要访问5个这样的数据源。

在分离数据库世界中,不同的源都处于不同的地理位置中,这就意味着尝试第一个数据库,取得所有的数据,查询丢失了什么,构成一个新的请求,并发布下一个任务。

对于HBase,我们仍然可以获得物理分类的优势,支持上千万列,并通过协同处理器进行同址计算。

通过将源和字段列与security和date整合,它们将被混搭在相同的region服务器上 。协同处理器的逻辑将变为“为指定行发现第一个源,并进行security和date匹配”。

在一个只包含一些行的小协同处理器上,平均响应时间将降到85毫秒。

性能3:同步中断


继续上文的话题,增加region服务器数量降低性能给我们留下的谜题:为什么响应时间在开始时有改善,而随后则会变得更糟糕?问题的答案涉及到两个方面——Java和所有高fan out分布式系统一些常见的问题。

一个涉及到不止1个fan out的请求中,服务器访问越高,fan out的程度就越高。那么,在一个有fan out的请求中,响应时间该如何计算?

答案就是,响应的时间由最慢的反应者决定,当给11台主机每个都配备10个region服务器时,每个请求需要fan out 110个进程。如果其中109个是1毫秒完成,1个请求是170毫秒,那么响应时间将高达170毫秒。

这里的罪魁祸首毫无疑问就是Java的垃圾回收机制,它会冻结一个机器直到回收结束。Fan-out的程度越高,其中一个region服务器在做垃圾回收的可能性就越大。当region数量达到110个时,可能性已经开始接近1。

这里的解决方案非常的简单。既然在垃圾回收过程中所有的服务器都会被冻结,那么为什么不让这些region服务器同时做垃圾回收?这种情况下,请求将需要更多的时间,但是毫无疑问的是,在处理的过程中,没有region服务器会做垃圾回收。为此,我们编写了不能再简单的代码进行测试——system.gc()以及30秒会调用一次这个方法的定时器。

通过这个操作,我们首次将相应时间从85毫秒降低到60毫秒。

Java垃圾回收机制这个诟病已经被广泛认知,这也是Jeff Dean归纳为Synchronized Disruption中的一个问题。任何并行系统中的请求都需要遭受最慢者的摧残,因此影响个体机器的问题将同时影响到整个系统。想获得更多详情,推荐阅读“Achieving Rapid Response Times in Large Online Services”,你将获得更多关于高fan out计算系统的使用经验。

这就意味着,Java当下已经成为很多高fan out计算系统的基础,其中包括Hadoop、HBase、Spark、SOLR等,同步进行垃圾回收将解决非常大的问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值