接着说谷歌,上篇文章提到了 GFS 。那么谷歌为什么要硬着头皮去啃分布式系统这块硬骨头呢?首先,我们要知道谷歌刚开始成立时是一家搜索公司,方便用户查询互联网上的信息。因此谷歌必须要存储整个互联网上的信息,那这个数据量是庞大的。对于这个需求,传统的数据库或者更深入地说,单机是远远不够的,必须要使用分布式系统搭建集群;但是那个时候要搭建集群,可供选择的方案大多像 Oracle 的 RAC 一样,需要昂贵的机器。因此谷歌必须要自行去解决这个问题:
- 必须是集群,多台机器组合在一起,可以不断扩展
- 不能是高端机器,一般的商用计算机就可以
如果选择了海量的廉价计算机组成集群,那势必意味着集群内部会遇见不可知的错误导致其中一台或者多台机器宕机,而且这宕机还是经常性的、不可预知的。除此以外,谷歌需要存储的是互联网数据,这个数据主要是由爬虫进行爬取的,基于这个事实,谷歌认为 GFS 只要负责好 TB 或者 PB 级别的大文件,并且这个文件只能增加,无需进行更新操作。明白这些前提,再去看 GFS 这篇论文会轻松很多,比如对数据进行三副本存储,而元数据使用 Paxos 算法。
谷歌有了 GFS 这样牛逼的存储,那么还需要倒排索引。所谓的倒排索引,是“被用来存储在全文搜索下某个单词在一个文档或者一组文档中的存储位置的映射”。因此有了 MapReduce 去构建倒排索引(MapReduce入门程序也是一个 WordCount 程序,统计一段话里每个单词对应的数量是多少)。MapReduce 借用了函数式编程里的 map 和 reduce 思想,当然这不是重点,重点是 MapReduce 的可容错性,它创新性的使用文件系统作为中间计算结果的缓存层,当然这个文件系统不能因为单机的故障而宕机,另外需要一个调度层去分配资源和重试失败任务,这自然就是 Yarn 了(不过谷歌内部使用的是 Borg 作为资源管理系统,Hadoop 刚开始的时候还没有类似的资源关系系统,后面到 2.0 才开始引入 Yarn)。
MapReduce 的一切都建立在 GFS (开源实现是 HDFS )和 Borg (开源实现是 Docker )的前提上,其本身倒是没有可值得一提的。有了这两个东西,再结合传统数据库理论完全能做出更好的东西,比如 Spark 。大家有空的话可以参考下数据库领域的 Michael Stonebraker 和谷歌的 Jeff Dean 的论战,相关论文是MapReduce :a major step backwards,吃下瓜也是挺好的。
MapReduce 构建倒排索引时有个大问题,那就是每一次构建都需要重头开始跑整个系统的数据,代价太高了,且互联网上的实时热点数据更新非常快,那就需要一个只更新热点网站的工具,这个工具类似于 Key-Value 存储,每一次倒排索引更新主键即可,更新时最好有时间戳记录,但是呢,不需要像传统数据库一样支持全局事务,单行事务即可。这就是 BigTable ,开源实现是 Hbase 。
有了这个东西,谷歌只需要更新网站发生变化的网址就行了,用户也就可以实时地查询到热点新闻了。BigTable 还只是一个半成品,事务这东西如果上推到应用层去做会复杂的要命,因此后来谷歌做了一个 Spanner 的东西,引领了 NewSQL 的风潮。后面会简要翻译下 Spanner 的相关论文,做一个介绍。
好了,GFS 、MapReduce 和 BigTable 的介绍到此结束了,谷歌发表了这三篇论文,给大数据时代的到来奠定了基石,虽然 MapReduce 已成昨日黄花,Spark 和 Flink 正冉冉新起,BigTable 也有很多相关替代品出现,但是我们依然不能忘记谷歌做出的贡献。