转载链接:https://www.infoq.cn/article/2017/06/U-no-Google

在为问题寻找解决方案时要先充分了解问题本身,而不是一味地盲目崇拜那些巨头公司。Ozan Onay 以 Amazon、LinkedIn 和 Google 为例,为执迷不悟的人敲响警钟。以下内容已获得作者翻译授权,查看原文: You Are Not Google 。

软件工程师总是着迷于荒唐古怪的事。我们看起来似乎很理性,但在面对技术选型时,总是陷入抓狂——从 Hacker News 到各种博客,像一只飞蛾一样,来回折腾,最后精疲力尽,无助地飞向一团亮光,跪倒在它的前面——那就是我们一直在寻找的东西。

真正理性的人不是这样做决定的。不过工程师一贯如此,比如决定是否使用 MapReduce。

Joe Hellerstein 在他的大学数据库教程视频中说道:

世界上只有差不多 5 个公司需要运行这么大规模的作业。至于其他公司……他们使用了所有的 IO 来实现不必要的容错。在 2000 年代,人们狂热地追随着 Google:“我们要做 Google 做过的每一件事,因为我们也运行着世界上最大的互联网数据服务。”

超出实际需求的容错没有什么问题,但我们却为此付出了的惨重的代价:不仅增加了 IO,还有可能让原先成熟的系统——包含了事务、索引和查询优化器——变得破碎不堪。这是一个多么严重的历史倒退!有多少个 Hadoop 用户是有意识地做出这种决定的?有多少人知道他们的决定到底是不是一个明智之举?

MapReduce 已经成为一个众矢之的,那些盲目崇拜者也意识到事情不对劲。但这种情况却普遍存在:虽然你使用了大公司的技术,但你的情况却与他们大不一样,而且你的决定并没有经过深思熟虑,你只是习以为常地认为,模仿巨头公司就一定也能给你带来同样的财富。

是的,这又是一篇劝大家“不要盲目崇拜”的文章。不过这次我列出了一长串有用的清单,或许能够帮助你们做出更好的决定。

很酷的技术?UNPHAT

如果你还在使用 Google 搜索新技术来重建你的软件架构,那么我建议你不要再这么做了。相反,你可以考虑应用 UNPHAT 原则。

在彻底了解(Understand)你的问题之前,不要急着去寻找解决方案。你的目标应该是在问题领域内“解决”问题,而不是在方案领域内解决问题。
列出(eNumerate)多种方案,不要只把眼睛盯在你最喜欢的方案上。
选择一个候选方案,并阅读相关论文(Paper)。
了解候选方案的产生背景(Historical context)。
比较优点(Advantages)和缺点,扬长避短。
思考(Think)!冷静地思考候选方案是否适合用于解决你的问题。要出现怎样异常的情况才会让你改变注意?例如,数据要少到什么程度才会让你打消使用 Hadoop 的念头?
你不是 Amazon

UNPHAT 原则十分直截了当。最近我与一个公司有过一次对话,这个公司打算在一个读密集的系统里使用 Cassandra,他们的数据是在夜间加载到系统里的。

他们阅读了 Dynamo 的相关论文,并且知道 Cassandra 是最接近 Dynamo 的一个产品。我们知道,这些分布式数据库优先保证写可用性(Amazon 是不会让“添加到购物车”这种操作出现失败的)。为了达到这个目的,他们在一致性以及几乎所有在传统 RDBMS 中出现过的特性上做出了妥协。但这家公司其实没有必要优先考虑写可用性,因为他们每天只有一次写入操作,只是数据量比较大。

他们之所以考虑使用 Cassandra,是因为 PostgreSQL 查询需要耗费几分钟的时间。他们认为是硬件的问题,经过排查,我们发现数据表里有 5000 万条数据,每条数据最多 80 个字节。如果从 SSD 上整块地读取所有数据大概需要 5 秒钟,这个不算快,但比起实际的查询,它要快上两个数量级。

我真的很想多问他们几个问题(了解问题!),在问题变得愈加严重时,我为他们准备了 5 个方案(列出多个候选方案!),不过很显然,Cassandra 对于他们来说完全是一个错误的方案。他们只需要耐心地做一些调优,比如对部分数据重新建模,或许可以考虑使用(当然也有可能没有)其他技术……但一定不是这种写高可用的键值存储系统,Amazon 当初创建 Cassandra 是用来解决他们的购物车问题的!

你不是 LinkedIn

我发现一个学生创办的小公司居然在他们的系统里使用 Kafka,这让我感到很惊讶。因为据我所知,他们每天只有很少的事务需要处理——最好的情况下,一天最多只有几百个。这样的吞吐量几乎可以直接记在记事本上。

Kafka 被设计用于处理 LinkedIn 内部的吞吐量,那可是一个天文数字。即使是在几年前,这个数字已经达到了每天数万亿,在高峰时段每秒钟需要处理 1000 万个消息。不过 Kafka 也可以用于处理低吞吐量的负载,或许再低 10 个数量级?

或许工程师们在做决定时确实是基于他们的预期需求,并且也很了解 Kafka 的适用场景。但我猜测他们是抵挡不住社区对 Kafka 的追捧,并没有仔细想过 Kafka 是否适合他们。要知道,那可是 10 个数量级的差距!

再一次,你不是 Amazon

比 Amazon 的分布式数据库更为著名的是它的可伸缩架构模式,也就是面向服务架构。Werner Vogels 在 2006 年的一次访谈中指出,Amazon 在 2001 年时就意识到他们的前端需要横向伸缩,而面向服务架构有助于他们实现前端伸缩。工程师们面面相觑,最后只有少数几个工程师着手去做这件事情,而几乎没有人愿意将他们的静态网页拆分成小型的服务。

不过 Amazon 还是决定向 SOA 转型,他们当时有 7800 个员工和 30 亿美元的销售规模。

当然,并不是说你也要等到有 7800 个员工的时候才能转向 SOA……只是你要多想想,它真的能解决你的问题吗?你的问题的根源是什么?可以通过其他的方式解决它们吗?

如果你告诉我说,你那 50 个人的公司打算转向 SOA,那么我不禁感到疑惑:为什么很多大型的公司仍然在乐此不彼地使用具有模块化的大型单体应用?

甚至 Google 也不是 Google

使用 Hadoop 和 Spark 这样的大规模数据流引擎会非常有趣,但在很多情况下,传统的 DBMS 更适合当前的负载,有时候数据量小到可以直接放进内存。你是否愿意花 10,000 美金去购买 1TB 的内存?如果你有十亿个用户,每个用户仅能使用 1KB 的内存,所以你的投入远远不够。

或许你的负载大到需要把数据写回磁盘。那么你需要多少磁盘?你到底有多少数据量?Google 之所以要创建 GFS 和 MapReduce,是要解决整个 Web 的计算问题,比如重建整个 Web 的搜索索引。

或许你已经阅读过 GFS 和 MapReduce 的论文,Google 的部分问题在于吞吐量,而不是容量,他们之所以需要分布式的存储,是因为从磁盘读取字节流要花费太多的时间。那么你在 2017 年需要使用多少设备吞吐量?你一定不需要像 Google 那么大的吞吐量,所以你可能会考虑使用更好的设备。如果都用上 SSD 会给你增加多少成本?

或许你还想要伸缩性。但你有仔细算过吗,你的数据增长速度会快过 SSD 降价的速度吗?在你的数据撑爆所有的机器之前,你的业务会有多少增长?截止 2016 年,Stack Exchange 每天要处理 2 亿个请求,但是他们只用了 4 个 SQL Server,一个用于 Stack Overflow,一个用于其他用途,另外两个作为备份复本。

或许你在应用 UNPHAT 原则之后,仍然决定要使用 Hadoop 或 Spark。或许你的决定是对的,但关键的是你要用对工具。Google 非常明白这个道理,当他们意识到 MapReduce 不再适合用于构建索引之后,他们就不再使用它。

先了解你的问题

我所说的也不是什么新观点,不过或许 UNPHAT 对于你们来说已经足够了。如果你觉得还不够,可以听听 Rich Hickey 的演讲“吊床驱动开发”,或者看看Polya 的书《 How to Solve It 》, 或者学习一下 Hamming 的课程“ The Art of Doing Science and Engineering ”。我恳请你们一定要多思考!在尝试解决问题之前先对它们有充分的了解。最后送上 Polya 的一个金句名言:

回答一个你不了解的问题是愚蠢的,到达一个你不期望的终点是悲哀的。

一语点醒技术人:你不是 Google(转载)的更多相关文章

  1. CSDN:你认为一名优秀的技术人应该具备怎样的素质?

    CSDN:你认为一名优秀的技术人应该具备怎样的素质? 王晶昱:我个人认为,符合这个世界要求的就是优秀的.在目前这个时代,我认为一个优秀的技术人员的特质可能是: 兴趣驱动,兴趣是最好的老师,写程序本身就 ...

  2. 如何量化考核技术人的KPI?

    对技术人来说,技术是成长的“核心”.然而,在实际工作协作中,技术的重要性常常被业务所掩盖,造成先业务后技术的现象. 针对这个痛点,阿里高级技术专家张建飞提出了自己的解决思路,希望能与大家一起探讨交流. ...

  3. [转帖]Oracle 裁员史:技术人死于重组,卒于云计算

    Oracle 裁员史:技术人死于重组,卒于云计算 https://www.infoq.cn/article/tm-mcdHCPCI4eEwr6dbY 大厂裁员 我妈妈也总担心我没工作了 怎么还房贷 田 ...

  4. 如何量化考核技术人的 KPI?

    如何量化考核技术人的 KPI? 原创: 张建飞 阿里技术今天 阿里妹导读:对技术人来说,技术是成长的"核心".然而,在实际工作协作中,技术的重要性常常被业务所掩盖,造成先业务后技术 ...

  5. 一个技术人,最重要的是:极客精神(好奇心 + 探索欲)(新de代码)

    一个技术人,最重要的是:极客精神(好奇心 + 探索欲) 初到社会,面对众多的IT企业,我们是陌生与好奇的,认为所有企业都是管理一流并且高大上等的.然而工作多年以后你会发现,国内的IT企业环境良莠不齐, ...

  6. [转帖]技术人眼中的Facebook Libra

    技术人眼中的Facebook Libra https://www.jianshu.com/p/ddc733077749 比特币 以太坊 EOS Libra 0.8352019.07.01 14:15: ...

  7. 我花了2个月时间,整理了100篇Linux技术精华,技术人必看

    一个以技术为立身根基的教育机构做出来的微信号,干货程度会有多高? 马哥Linux运维公众号运营五年,从一开始的定位就是给技术人分享加薪干货的地方.这五年里,公众号运营最重的任务就是做内容.内容并不好做 ...

  8. IT技术人,“三十而已”

    最近电视剧<三十而已>热播,我家的电视机自然也是被霸屏,我还是跟着妹纸看了看,开头和结局完整看完,中间看了一点,大部分都是在微信公众号上通过别人的文章看完的.我个人也已经30+了,今天也和 ...

  9. <阿里工程师的自我素养>读后感-技术人应该具备的一些基本素质

    一.技术人具备"结构化思维"意味着什么? 1.什么是结构化思维? 结构化思维:逻辑+套路. 表达要有逻辑,所谓逻辑是指我们的结构之间必须是有逻辑关系的. 四种组织思想的逻辑关系 : ...

随机推荐

  1. SSM框架之Mybatis(5)数据库连接池及事务

    Mybatis(5)数据库连接池及事务 1.Mybatis连接池 ​ Mybatis 中也有连接池技术,但是它采用的是自己的连接池技术.在 Mybatis 的 SqlMapConfig.xml 配置文 ...

  2. Python 條件式 Condition

    除了重複使用Function,有時我們須檢查結果,依此判斷下個步驟該怎麼進行,如此就需要條件式 condition statement. if ... elif ... ese ( 或 if ... ...

  3. [转]Sumifs函数多条件求和的9个实例

    本文转自:http://m.officezhushou.com/sumif/5187.html 第一部分:sumifs函数用法介绍 excel中sumifs函数是Excel2007以后版本新增的多条件 ...

  4. Linux加密known_hosts文件中的IP

    如何加密known_hosts中的IP地址 很多挖矿会去自动匹配known_hosts文件中的IP地址,然后尝试免密登录,进一步感染更多的主机,所以对该文件进行加密可以阻止这一点. 修改 /etc/s ...

  5. Linux-3.14.12内存管理笔记【构建内存管理框架(2)】

    前面构建内存管理框架,已经将内存管理node节点设置完毕,接下来将是管理区和页面管理的构建.此处代码实现主要在于setup_arch()下的一处钩子:x86_init.paging.pagetable ...

  6. ENDGAME

    "So if I were to wrap this up tight with a bow or whatever,I guess I'd say my career of OI was ...

  7. #undef常用法

    Copy from C语言中#undef的语法是: #undef 标识符 用来将前面定义的宏标识符取消定义. 整理了如下几种常见用法,如果以后发现其他的再添加进来. 1.在一个程序块中用完宏定义后,为 ...

  8. <DFS & BFS> 286 339 (BFS)364

    286. Walls and Gates DFS: 思路是,搜索0的位置,每找到一个0,以其周围四个相邻点为起点,开始 DFS 遍历,并带入深度值1,如果遇到的值大于当前深度值,将位置值赋为当前深度值 ...

  9. shell 下

    一句话来概括shell    shell是一个基于Linux内核和应用程序之间的一个解释器 Shell解释器    /bin/sh    /bin/bash  目前多用的是bash    /sbin/ ...

  10. Java内存中的常量池

    1,java内存模型简介 <深入理解java虚拟机>里将java内存分为如下五个模块: 堆-堆是所有线程共享的,主要用来存储对象. 其中,堆可分为:新生代和老年代两块区域.使用NewRat ...