通向高可扩展性之路(谷歌篇)

原文链接: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受限时,压缩是一个很好地选择。

时间: 2024-11-08 01:59:37

通向高可扩展性之路(谷歌篇)的相关文章

通向高可扩展性之路(推特篇) ---- 一个推特用来支撑1亿5千万活跃用户、30万QPS、22MB每秒Firehose、以及5秒内推送信息的架构

原文链接:http://highscalability.com/blog/2013/7/8/the-architecture-twitter-uses-to-deal-with-150m-active-users.html 写于2013年7月8日,译文如下: “可以解决推特所面临的挑战”的玩具般的方案是一个常用在扩展性上的比喻.每个人都觉得推特很容易实现.稍微具备一些系统架构的知识我们就可以构建一个推特,就这么简单.但是根据推特软件开发部门的VP Raffi Krikorian在 Timelin

ORACLE数据高可用之路

这篇是计算机中Oracle类的优质预售推荐>>>><ORACLE数据高可用之路> 编辑推荐 本书特别适合Oracle中高级系统管理人员.应用开发人员阅读,同时对关心服务器技术.关注数据高可用性与数据安全的企业技术人员.相关IT专业的高校教师和研究生也有重要的参考价值. 内容简介 现代数据服务面临的两大问题是数据保障和不间断服务,即数据服务的高可用性(High Availability).本书论述Oracle在此方面的两类解决方案:数据卫士(Data Guard)和数据集

JAVA必备——EJB,通向大型软件的路!

从接触java开始,就对java的标准,神交已久,今天先给大家简单介绍下,什么事ejb,然后咱们一起完成一个小例子,完成对ejb的熟悉过程,在这其间一起体会ejb带给我们的编码变化! 简介(来自百度): EJB是sun的服务器端组件模型,设计目标与核心应用是部署分布式应用程序.凭借java跨平台的优势,用EJB技术部署的分布式系统可以不限于特定的平台.EJB (Enterprise JavaBean)是J2EE的一部分,定义了一个用于开发基于组件的企业多重应用程序的标准.其特点包括网络服务支持和

基于SID的高可扩展性数据模型

前言 此文根据TMF SID规范撰写,欢迎大家提出建议和意见. TMF文档版权信息 Copyright © TeleManagement Forum 2013. All Rights Reserved. This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist i

(转)Android项目重构之路:实现篇

前两篇文章Android项目重构之路:架构篇和Android项目重构之路:界面篇已经讲了我的项目开始搭建时的架构设计和界面设计,这篇就讲讲具体怎么实现的,以实现最小化可用产品(MVP)的目标,用最简单的方式来搭建架构和实现代码. IDE采用Android Studio,Demo实现的功能为用户注册.登录和展示一个券列表,数据采用我们现有项目的测试数据,接口也是我们项目中的测试接口. 项目搭建 根据架构篇所讲的,将项目分为了四个层级:模型层.接口层.核心层.界面层.四个层级之间的关系如下图所示:

(转)Android项目重构之路:界面篇

在前一篇文章<Android项目重构之路:架构篇>中已经简单说明了项目的架构,将项目分为了四个层级:模型层.接口层.核心层.界面层.其中,最上层的界面,是变化最频繁的一个层面,也是最复杂最容易出问题的一个层面,如果规划不好,很容易做着做着,又乱成一团了. 要规划好界面层,至少应该遵循几条基本的原则: 保持规范性:定义好开发规范,包括书写规范.命名规范.注释规范等,并按照规范严格执行: 保持单一性:布局就只做布局,内容就只做内容,各自分离好:每个方法.每个类,也只做一件事情: 保持简洁性:保持代

Linux运维之路 基础篇:Linux基础命令(一)

Linux运维之路 基础篇:Linux基础命令(一) Linux哲学宗旨: 一切皆文件:把几乎所有的资源,包括硬件设备都组织为文件 有众多单一的小程序组成,一个程序制实现一个功能,组成小程序完成复杂操作 尽量避免和用户交互:实现脚本编程,以自动完成某些功能 使用纯文本文件保存配置信息 终端:用户和主机交互时用到的设备 物理终端:直接接入的设备也叫控制台/dev/console 虚拟终端:附加在物理终端上虚拟出的,默认启动六个,Ctrl+Alt(F1~F6),系统启动时,默认启动虚拟终端1,启动终

我的web前端自学之路-心得篇:我为什么要学习web前端?

时光如流水,转眼间,自己已经是大三的学长了,看着一个个学弟学妹,心中有种莫名的感觉,很怀念大学的前两年时光,但也很憧憬着自己的未来,自己将要去经历很多从未经历的事.我是我们学校信科院的一名学生,在编程方面,一开始只是接触到了C语言,但是c语言对于我来说并不友好,也并不是那么的好学,所以自己对程序不是很有兴趣,但一个偶然的机会,我接触到了web前端,看着我的一个大牛同学用前端 所涉及的语言写出了一些很棒的程序,于是就产生了一种很想学习前端的想法和很想把前端做的完美的渴望,于是,就开始了我的前端之路

高并发场景之RabbitMQ篇

上次我们介绍了在单机.集群下高并发场景可以选择的一些方案,传送门:高并发场景之一般解决方案 但是也发现了一些问题,比如集群下使用ConcurrentQueue或加锁都不能解决问题,后来采用Redis队列也不能完全解决问题, 因为使用Redis要自己实现分布式锁 这次我们来了解一下一个专门处理队列的组件:RabbitMQ,这个东西天生支持分布式队列. 下面我们来用RabbitMQ来实现上一篇的场景 一.新建RabbitMQ.Receive private static ConnectionFact