通向高可扩展性之路(谷歌篇)
原文链接:http://highscalability.com/google-architecture
原文写于2008年11月22日,以下是译文:
平台:
1. Linux
2. 很多种语言: Python, Java, C++
平台上有什么?
一些数据:
1. 2006年时大约有450,000 台廉价商用服务器
2. 2005年的时候谷歌已经索引了80亿网页。现在大概没人知道他们已经索引了多少网页了。
3. 现在谷歌有超过200个GFS集群。一个集群可以有1000甚至5000台机器。成千上万台的机器从这些可以装得下5PB存储的GFS集群中读取数据。一个集群的总的读写吞吐量可以高达每秒40GB。
4. 目前谷歌已有6000个MapReduce的程序,还正在已每个月数百的速度增加。
5. BigTable可以扩展到存储数以十亿计得URL,数以百TB计的卫星图片,以及数以亿计的用户偏好。
技术堆栈:
谷歌把他们的基础设施视为一个三层的堆栈:
1. 产品:搜索,广告,邮件,地图,视频,聊天,博客
2. 分布式系统基础设施: GFS,MapReduce, 和BigTable
3. 计算平台: 在各个不同数据中心运行着的那些机器
4. 确保公司员工可以以较低的成本方便地部署应用
5. 关注每一个应用的性价比。花更多的钱在硬件上来确保不丢失日志数据,但是在其他类型的数据上花更少的钱。虽然这么说,但是谷歌不丢失数据。
基于GFS(Google File System)的可靠存储机制:
1. 可靠地可扩展存储是任何应用的一个核心需求。GFS是谷歌的核心存储平台。
2. 谷歌文件系统 - 大规模分布式日志结构的文件系统,用来存储了很多很多数据
3. 为什么要自己开发这套系统而不是拿个已经存在的系统来用用?因为他们可以控制所有的细节,并且正是这套系统把谷歌和其他人区分了开来。他们需要:
- 多个数据中心之间的高可靠性
- 可扩展到数千个网络节点
- 巨大的读写带宽要求
- 支持大块的GB级的数据
- 有效地将多个操作分散到不同节点来减少瓶颈
4. 系统有主服务器和块服务器
- 主服务器用来存储各种数据文件的元数据。真正的数据在文件系统中存为多个64MB大小的块文件。客户从主服务器获取元数据并由此找到包含他们想要的文件的块服务器。
- 块服务器在硬盘上存着那些真正的数据。每一个块都被复制到三个不同的块服务器上来提供冗余,以防有的服务器会出故障。一旦客户从主服务器上获取了路径信息,客户的应用就会从块服务器上直接下载文件。
5. 一个新的应用上线既可以使用已有的GFS集群,也可以建立一个新的集群。理解谷歌在他们的数据中心中使用什么样的配置过程会是一件非常有趣的事情。
6. 关键是要有足够的基础设施来确保人们在上线他们的应用时有选择的余地。GFS可以被适当地调整来适应不同应用的需求。
用MapReduce来处理数据:
1. 现在你有了一个很好的存储系统,那么这么多数据能用来干嘛呢?我们假设你在1000台机器上有好几TB的数据。数据库通常不能支持这么大的数据,就算支持,这样的数据库也会非常昂贵。这时MapReduce就体现出了作用。
2. MapReduce是一个编程模型,也包含一个与之关联的处理和产生大数据集的具体实现。用户声明一个映射(map)函数来把一个键值对(key value pair)转化成多个作为中间变量的键值对,以及一个归纳(reduce)函数来合并所有中间变量中具有相同键(key)的值(value)。很多现实中的任务可以用这个模型来表达。用这种功能性风格写出来的代码可以自动在大集群的商用服务器上并行执行。有一个实时系统会来管理输入数据的分割,在多台机器上调度程序的运行,处理机器故障,以及机器间沟通的问题。这可以使没有在并行分布式系统下编程经验的程序员们方便的利用一个大型分布式系统的资源。
3. 为什么使用MapReduce?
- 这是一个很好的在多台机器间分摊任务的方法
- 处理机器故障
- 支持多种不同类型的应用,如搜索和广告。几乎每个应用都有MapReduce的操作。你可以预算有用的数据,找到单词计数,为TB级的数据排序等等。
- 计算可以自动的离IO源更近
4. MapReduce系统有三种不同的服务器。
- 主服务器将用户任务分配到映射服务器和归纳服务器上。它也跟踪任务状态。
- 映射服务器接受用户输入的数据,并对之执行映射操作。结果会被写到中间文件中去。
- 归纳服务器对中间文件执行归纳操作。
5. 例如你想数数所有网页中一共有多少个词。你可以把所有GFS上的网页输入MapReduce。这将会导致数以千计的机器同时开工,而这一切的协调,任务调度,处理失败,以及数据调送都会被自动执行。
- 具体步骤如下:GFS -> 映射 -> 洗牌 -> 归纳 -> 把结果存回GFS
- 在MapReduce中一个映射函数将数据从一种形式映射到另一种形式,并产生一个键值对。在我们的这个例子中,键就是单词,值就是计数。
- 洗牌过程汇总了键的类型。
- 归纳函数把所有键值对做了汇总并产生了最终结果。
6. 谷歌索引流水线有大约20种不同的MapReduce。一个MapReduce汇总数据中的各种记录的键,第二个mapReduce再利用这个结果做些别的事,然后又传递给下面的MapReduce,以此类推。
7. 程序可以很小,甚至20到50行的代码都有。
8. 不过拖后腿的任务会是一个问题。拖后腿的任务指的是那些比其他任务执行的慢的任务。它会影响整个任务的进度。它可能是由于比较慢的I/O(比如一个差的控制器)或是一个暂时的CPU利用率陡升。解决方案就是同时执行多个一样的任务,一旦有一个完成了就终止其它的。
9. 映射服务器和归纳服务器之间的数据传输是压缩过的。基本想法是因为服务器并不受限于CPU,所以花点CPU时间在压缩和解压数据上来节省带宽和I/O是值得的。
在BigTable中存储结构化数据:
1. BigTable是一个大规模容错的自管理系统,包括TB级的内存和PB级的存储。它可以支持每秒百万的读写。
2. BigTable有一个基于GFS的分布式哈希机制。它不是关系型数据库,不支持联合或者SQL式的查询。
3. 它支持基于关键字的查询来获得结构化的数据。GFS存储不透明数据,许多应用需求也含有结构化的数据。
4. 商业数据库通常不能扩展到如此规模,也不能运行在上千台机器上。
5. 通过控制他们自己的下层存储系统,谷歌可以获得更多的控制力和杠杆来优化他们的系统。比如说,如果他们想要使跨数据中心的操作更简单一些,他们可以把这个功能直接写入他们的系统中。
6. 机器可以随时加入或者离开这个系统,而这个系统还是可以工作。
7. 每一个数据项都被存在一个单元中,可以通过行健,列键或者时间标签来获取。
8.每一行都被存在一个或多个表单中。一个表单就是一系列64KB大小的,数据结构被称为SSTable的块。
9. BigTable有三种不同的服务器:
- 主服务器把表单分配到表单服务器上。它们跟踪表单们在哪里,并且在需要时会重新分配任务。
- 表单服务器处理表单的读写请求。当表单的大小超过限制(通常100-200MB)时,它们会把表单拆分。当一台表单服务器出故障时,它的表单会被分配到其他100台服务器上,这样系统就可以不受影响。
- 锁服务器提供分布式锁服务。一些类似向表单中写入数据, 主服务器仲裁,以及访问控制等操作需要互斥。
10. 一个地域性小组可以用来物理地集中存储相关数据,以提高地域性偏好。
11. 表单尽可能的被存在RAM中。
硬件:
1. 当你有很多机器的时候,你会怎样制造他们使得他们更加省钱省电?
2. 使用超级便宜的商用硬件,然后在其上设置软件来处理它们的故障。
3. 如果你使用一个侦察故障的基础设施,而不是确保每个部件都高度可靠,一千倍的用电量的增加可能可以只会增加33倍的支出。你必须在不可靠之上构建可靠来使这一套方法行之有效。
4. Linux,自己的服务器架设计,PC级的母板,低端存储
5. 用每瓦特的成本来衡量的性价比并没有提高,因为存在很大的电能和冷却的问题。
6. 混合使用自己独立的数据中心和与他人共享的数据中心。
其他:
1. 快速推出改动,而不是等待QA。
2. 代码库是创建程序的主要途径。
3. 一些应用被当成服务提供给别人,例如爬虫。
4. 有一个控制应用版本的基础设施,所以不用担心新发布一个版本会破坏什么东西。
谷歌的未来之路:
1. 支持含地理信息的分布式集群。
2. 给所有数据创建一个单一的全局命名域。现在数据被分散在各个集群中。
3. 更多更好的自动数据和计算迁徙。
4. 解决广域复制和网络分割引起的一致性问题(例如,即使一个集群因为做维护或者其他原因停运而下线,仍能保持服务可访问)
学到的经验教训:
1. 基础设施可以是一个竞争优势。 这对于谷歌来说是很明显的。他们可以更快更便宜的推出新的互联网服务,规模之大很少有人可以媲美。很多公司走上了一条完全不同的路。他们把基础设施认为是负担。每一个组使用完全不同的技术,也没有通用的计划来构建这些系统。谷歌认为自己是一家系统工程公司,这是一个非常新颖的看待软件开发的角度。
2. 拓展到多个数据中心仍然是一个未解决的难题。大多数网页存在于一个或最多两个数据中心之中。如何把一个网页分布到多个数据中心上去是一个可以说非常需要技巧的事情。
3. 看看Hadoop如果你自己没有时间从头重新构建这整个一套基础设施。Hadoop是一个开源的实现了很多跟这里说的类似的想法的系统。
4. 一个被低估了的平台化开发的优势就是年轻的开发员可以更快更有自信地在这个平台上创造靠谱的应用。如果每一个项目都需要创建一样的分布式基础架构的话,你就有麻烦了,因为知道怎么做这些事情的人相当少见。
5. 协同并不是总是一件坏事。让一个系统的所有部件协同工作的话,某一个部件改进就可以惠及其它所有的部件。优化文件系统,那每个人都可以立即不费任何功夫地受益。如果每一个项目都是用一个不同的文件系统,那就不可能对整个技术堆栈有一个持续的递增的优化。
6. 创建不需要关闭系统的自管理系统。这样可以使你更加容易地在服务器之间均衡资源,动态地增加容量,淘汰机器,以及自然地处理升级。
7. 创建一个达尔文式的基础设施。并行处理多个相同的耗时操作,并只等最快的那个结束。
8. 不要忽视学术界。学术界有很多好的想法没有被引入产业界。很多谷歌做的事情都有先例,只是没有大规模部署。
9. 考虑压缩。当你有很多CPU可以浪费,而I/O受限时,压缩是一个很好地选择。
作者:好大一片云
博客地址:http://www.cnblogs.com/zhutianshi/
转载声明:可以转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明,谢谢合作!
This work is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License.