自从 Hadoop 兴起之后,业界好象就有了这么一种共识:不再关注单机的运算性能,全靠集群堆。大家都在比谁的集群能更大,至于单机能力是否被充分发挥了,那没人关心。Hadoop 体系的诸多技术都有这个特征,单机性能奇低,但并不妨碍 Hadoop 推广得遍地都是。
发展到云计算阶段,这个认识就变成了“云上算力无穷”,算法有多笨都没有关系了,反正算力无穷多。所谓双拳难敌四手,到了云上,似乎啥都能搞定。
真有这么回事吗?
从云上能提供的硬件数量(CPU、内存)上看,算力确实是无穷的(相对于某个用户的需求),但这个“无穷”真能有多大意义呢?。
云计算的环境也是由普通硬件搭建的,一台物理机器能装上的 CPU 和内存数量都是有限的,再多的 CPU 和内存就需要用多机来组合了,而多机虚拟出来的 CPU 和内存和单机的性能是完全不同的。访问另一台物理机器的内存需要通过网络,而网络只适合批量访问,但内存的使用常常是小量随机式的,如果继续把网络模拟出来的内存当作单机内存去使用,而不调整算法以适应集群的话,那性能下降得会非常离谱。Java 程序员都知道当内存紧张时(还够但不充裕),JVM 要用外存缓存时导致的性能下降会有多严重,常常是一两个数量级的,在集群中发生本机内存不足需要访问其它节点的内存时,也会有类似的现象发生。这意味着,达到某个阈值的时候,你可能要动用 10 倍甚至 100 倍的硬件资源才能在期望的时间内完成运算了。算力虽然“无穷”,但并不能线性地扩展。
这就会引出另一个问题。
数天前与江湖上人称铎神的师弟(参考:https://mp.weixin.qq.com/s/0gFtvoYG-B_yBb1FoAlyHA)一起聊天,问起对“云上算力无限”这个观点的看法,铎神脱口而出:“云上算力无限,但用户口袋里的钱却有限”。
这道理简单得完全无需解释。
再退一步讲,就算用户财大气粗不在乎成本,仍然有不少运算没办法用上无限算力。
比如我们常见的关联运算(SQL 中的 JOIN),如果不在算法模型层面上进行改造,那它会有个集群节点的极限。分布式 JOIN 算法会有个 Suffle 动作,要在节点之间交换数据,当节点数较多时,Suffle 造成的网络延迟会抵消多机分摊计算带来的性能提升,这时候再增加更多的节点,运算性能并不会有明显提升了。而且这个节点限制数并不大,大概也就是几十到百的规模就会到顶了。
如果不对数据存储组织做刻意的优化,这种“关联”运算就会很常见。
从这三方面看,云上的“无穷”算力对于实际要做的运算来讲,常常没有多大实质意义。
需要一架飞机的时候,并不能用十万匹马来对付。
事还没讨论完,我们还要回答一个问题:既然真正意义的无穷算力并不普遍存在,为什么 Hadoop 等对单机资源利用率很低的技术还能大行其道?
这可能是因为 Hadoop 主要采用的是 PC 服务器,其价格远远低于之前的主流小型机,使用集群的总成本常常还比使用单个小型机的成本更低,这就给人造成了错觉,在原先可接受的成本下可以轻易地获得希望的算力。然而,小型机被逐步边缘化、硬件竞争都进入了 PC 服务器时代之后,耗用太多机器资源的技术就会越来越难过了。
那该咋办?
设计好算法,先把单机的运算效率提上去呗。
但是且显然,这事不能全指望数据库的优化,情况复杂时数据库引擎会晕掉(很容易造出这种并不太复杂的例子)。而且,很多运算本身都没法用 SQL 写出来,数据库想优化也无从谈起。
那又咋办?
嘿嘿,用 SPL 啊!
SPL 能够方便实现很多高性能的算法,把单机的运算效率提到极致,整体性能提上几倍甚至几个数量级,本来要用集群的运算也可以不用集群,大集群可以改用小集群。而且,关键的是,写出来的代码比 SQL 还短!
SPL 已开源且免费,欢迎下载试用,乾学院上还有高性能算法图书 【性能优化】。