只说性能指标而不提测试场景的大数据方案都是耍流氓

只说性能指标而不提测试场景的大数据方案都是耍流氓

大数据时代的用户都在追求更高的运算性能,于是,各方大神纷纷登场。我们经常能听到某些厂商发布自己产品的性能指标,号称可以秒级处理TB数据、或者比业内流行产品快出N倍等等。反正吹牛不上税,吹得越响用户听得心里就越痒痒。

真的是这样吗?里头会不会有什么坑?

产品的发布稿和文档中很少甚至没有提及宣称的性能指标在什么测试场景下获得的,我们只好自己来分析一下看。

一类宣传词是用绝对数值,比如能在数秒内处理TB级甚至PB级数据。

所有人应当都有复制硬盘文件的经验吧,一个10G的文件复制一遍要多久?记不清的可以现在自己试试看。

普通PC硬盘的读取速度一般是50-100M/秒,服务器的高级硬盘或者固态硬盘的性能会好些,不过单块硬盘的速度也就200-300M/秒的样子。即使按3秒读1G的速度算,1T数据光是读取一遍也需要3000秒,差不多要一个小时!

这就是硬盘的速度,而且还只是单任务读取的速度。

显然,软件没可能提高硬盘的性能了,那还怎么可能秒级处理上T的数据呢?

很简单,加硬盘呗,如果有1000块硬盘,不就可以在3秒内读完1T数据了嘛。

理论上讲,数秒内处理上T甚至上P数据并不是胡话,但是,您可要想清楚是不是真有这么多硬盘?还得是高档货哟。而且,在这种硬件环境下,别的产品是不是也能做到同样的性能指标呢?

用这个办法可以简单地估算出在确定硬件环境下确定数据量的处理性能极限。比如10个节点的集群,每节点装有10块硬盘的阵列,那么要处理1T数据至少需要30秒,2T就是60秒,...。这个数是理论极限,不可能再少了,除非硬件技术有重大冲破。

我们还是按理想情况在计算。实际情况下,可能没有采用这么高速的硬盘(毕竟有点贵),数据不大可能存放得那么连续整齐,这么多硬盘协调动作也不是那么简单的事情,用集群还有网络传输延迟的问题(万兆网卡比硬盘还快些,不过也很贵的),有些复杂的运算可能还有回写动作(内存装不下就要写出去缓存),这类期望的秒级运算常常用于报表和查询而有并发需求,...。这些因素综合起来,让这个数字在实际场景下再差一个数量级也是很正常的事了。

有人说,硬盘太慢了,我们改用内存。

好吧,内存是能比硬盘快出数量级,基本可以按CPU主频去估算速度,内存还适合高速处理随机访问和并发冲突问题。不过,估算方法并没有多大差别,内存也要花钱买,而且大内存并不是想装就能装上的,要花更多钱去用特定的服务器。内存使用率经常并不高(Java程序只有20%多的使用率),也要再打折扣。

对这些数字有了概念后,就不容易被厂商的宣传忽悠了。再听到有产品宣称几秒能搞定几T数据,不要着急兴奋,要记着问厂商需要多大规模的硬件环境,厂商在宣传时可不会主动说这个。要不,自己赶紧脑补一下,然后才知道要花多少银子能摆得平,反正有钱总能让运算快起来。

数秒甚至更短时间解决TB级数据的计算就必须用高成本的硬件吗?

当然不一定。不过这可能是一个更大的坑!

上面说的性能估算,假定了需要遍历所有数据,如果不遍历,当然就会很快了。

比如只做按键值查询,那只要事先做好索引,从TB级数据中找出某个键值还用不到1秒。可是,查询条件真地总是这样死板吗?而且这种情况下,所有传统数据库在建了索引后都有这个本事,对于那些key-value机制的开源NoSQL产品更是不在话下,还不要钱。

要么用列式存储。总数据量上T,但这个表有1000个列,只访问其中两三个列时只要遍历几个G数据,做到数秒很轻松。可是,实用的时候真地只要访问很少的列吗?提到列存,顺便说一句,列存远远没有传说中的那么美丽,这个回头再撰文细说。

还可以事先把汇总算好,很多OLAP产品的后台就是这样,原始数据量是有1T,花上几小时把汇总数据都算好存着,再取用时当然可以秒内返回了。可是,在查询汇总时就不会多提个条件吗(比如临时想看看交易额在500元以上的统计)?

在确定的硬件环境下,只能提供较弱的计算能力并没什么不合理的,有时也基本够用。但作为厂商,宣传性能指标时应当主动提供测出这个指标的特定运算场景,否则,嘿嘿,你懂的。

另一类宣传说法是和某些业界流行方案对比,常常会给出耸人听闻的数十甚至上百倍性能提升。

这又分两种情况,一种是和传统的商用数据库对比。

数据库需要考虑数据更新,在写入数据时会留有空隙,不会写得非常紧凑;多次写入后数据也不能保证连续存储;在读取时还要考虑可能同时发生的写动作,为保持一致性要采用较复杂的策略;这时候,如果采用压缩文件的方式紧凑地存储数据,牺牲数据更新的能力,确实都会比数据库获得更好的性能。

但是,这种快,在同等硬件环境下,一般也就百分之几十,想快出数倍都很难,需要配合一些传统数据库不大擅长的并行技术才有可能,快出数量级几乎没有可能性。

前面说过,软件不可能提升硬件性能,只能通过算法减少运算次数。但如果运算本身已很简单,那也就不大可能有什么优化方法了。

经常用来做基本性能测试的运算就是简单的查找和汇总运算(WHERE+GROUP),其实已经没有优化余地。想想也很明白,商用数据库做了这么多年,这些厂商显然也不傻,有好算法怎么可能不早就用了?大多数优化算法本来就是商用数据库厂商提出的。

如果运算复杂一些,比如带有JOIN或子查询,受限于SQL的数学模型,确实有许多可以被显著优化的环节(这个问题可以再展开详述)。但是,实现这种提升的前提是不再使用SQL(至少内核不是),而目前的绝大多数大数据方案都仍然在努力实现SQL(或子集),在这个体系下,也罕有什么人能比Oracle这种老牌数据库厂商有更丰富的优化经验。

所以,如果宣传词不是说假话,那这个性能提升基本上是因为硬件结构和存储机制不同造成的。比如用集群和单机去比,用内存和外存去比,用列式存储和行式存储去比。这种情况,要是不能快出数量级反而是件奇怪的事情了。这种胜之不武的对比,没什么值得夸耀的。

当然,采用集群提速仍然有意义,毕竟传统数据库的集群方案昂贵也不好用,能在同等成本下跑得更快也很重要。但是,这时候还要关注测出性能指标时使用的运算形式。如果是上面说的WHERE+GROUP,那很容易并行,机器多了那肯定会快很多,快出数量级并不很难。然而,许多大数据方案在SQL复杂度方面远远弱于传统商用数据库,有大表JOIN和子查询的复杂SQL可能性能会奇差,即使集群也可能跑不过传统数据库,有的甚至根本跑不出来。不服?别只算GROUP+WHERE,咱拿TPC-H那22个题跑一遍试试?

第二种常用的对比标杆是Hadoop上的Hive。

比Hive快出数倍并不是很难。Hive用的MapReduce是个省事的办法,但和高性能技术没多大关系,纯粹是靠机器多的蛮力把性能提上去。这也有意义,当数据量大到别的办法都不奏效时,蛮力就是唯一可行的选择了。MapReduce为什么快不了,先放在这里不谈,另外撰文解释。

不过,绝大多数场景用不着使蛮力。稍稍用点巧劲,就能很大幅度地超过基于MapReduce实现的Hive了。比如传统的商用数据库,同样的硬件环境,4-5个节点的Hive大概只能和一个Oracle相当,而且还是较简单的运算,运算再复杂些Hive就会更慢。

但是,想比Hive快出数量级也没多大可能性,道理和前面一样,这些运算就需要那么多次硬盘读写和CPU动作,这个量不可能再减少了,而MapReduce虽然做了许多冗余工作,但也没有多到数量级的地步。特别是数据量较大的情况下,这时运算的瓶颈主要在硬盘上,Impala、Spark以及Hive的速度差别并不明显。只有特定场合,比如大内存而相对小数据量时,Spark会有较大优势(Spark比Hive更擅长利用内存计算);算术计算很复杂时,Impala的优势也很明显(Impala有本地编译技术)。

也就是说,不能简单听厂商说个N倍就N倍,这个N倍是有附加条件的!N越大条件就越强,有时会强到不可能的地步,只说N倍而不说清附加条件的,那就只能再呵呵了。

还有个坑在于:Hive实在太慢了,就算比它快数倍也就和普通数据库相当,而且一般和Hive对比的都是Hadoop方案,这类方案可支撑的运算复杂度都较低,综合评估下来,经常并不比传统数据库有优势。这些性能对比,除了用来证明技术比Hive有特色外,在数据量没大到必须靠蛮力的地步(TB级还用不着)时,并没有多大实际意义。

顺便说一句,Hadoop体系下的方案都很慢,我们很少见到Hadoop方案和传统数据库对比性能的测试报告(google上也搜不出几个来),只见到Hadoop方案之间的对比。比如Impala和Hive比,Spark和Impala比,大家都不和Oracle比,就是自己玩。

最后澄清一个说法。有时候我们会听到有产品宣称上亿条记录的运算秒级完成,听起来也很牛,但算算数据量就会知道是正常的。如果字段不是很多的话,一条记录就算500字节,1亿行也就50G,有10块高速硬盘的单台服务器,10几秒内做个简单的单任务分组汇总或遍历查找运算是完全可能的。而且,高档服务器甚至可以把数据都装入内存,秒级返回并不是很困难。

  • 发表于:
  • 原文链接:http://kuaibao.qq.com/s/20180103A0VLYF00?refer=cp_1026

扫码关注云+社区