发新话题
打印

[大型站点架构] Architecture相关架构的学习及讨论(ZT)

Architecture相关架构的学习及讨论(ZT)

YouTube架构学习                  
                  
YouTube发展迅速,每天超过1亿的视频点击量,但只有很少人在维护站点和确保伸缩性。
平台
Apache
Python
Linux(SuSe)
MySQL
psyco,一个动态的Python到C的编译器
lighttpd代替Apache做视频查看
状态
支持每天超过1亿的视频点击量
成立于2005年2月
于2006年3月达到每天3千万的视频点击量
于2006年7月达到每天1亿的视频点击量
2个系统管理员,2个伸缩性软件架构师
2个软件开发工程师,2个网络工程师,1个DBA
处理飞速增长的流量

代码

    * while (true)
    * {
    *   identify_and_fix_bottlenecks();
    *   drink();
    *   sleep();
    *   notice_new_bottleneck();
    * }

每天运行该循环多次Web服务器
1,NetScaler用于负载均衡和静态内容缓存
2,使用mod_fast_cgi运行Apache
3,使用一个Python应用服务器来处理请求的路由
4,应用服务器与多个数据库和其他信息源交互来获取数据和格式化html页面
5,一般可以通过添加更多的机器来在Web层提高伸缩性
6,Python的Web层代码通常不是性能瓶颈,大部分时间阻塞在RPC
7,Python允许快速而灵活的开发和部署
8,通常每个页面服务少于100毫秒的时间
9,使用psyco(一个类似于JIT编译器的动态的Python到C的编译器)来优化内部循环
10,对于像加密等密集型CPU活动,使用C扩展
11,对于一些开销昂贵的块使用预先生成并缓存的html
12,数据库里使用行级缓存
13,缓存完整的Python对象
14,有些数据被计算出来并发送给各个程序,所以这些值缓存在本地内存中。这是个使用不当的策略。应用服务器里最快的缓存将预先计算的值发送给所有服务器也花不了多少时间。只需弄一个代理来监听更改,预计算,然后发送。
视频服务
1,花费包括带宽,硬件和能源消耗
2,每个视频由一个迷你集群来host,每个视频被超过一台机器持有
3,使用一个集群意味着:
-更多的硬盘来持有内容意味着更快的速度
-failover。如果一台机器出故障了,另外的机器可以继续服务
-在线备份
4,使用lighttpd作为Web服务器来提供视频服务:
-Apache开销太大
-使用epoll来等待多个fds
-从单进程配置转变为多进程配置来处理更多的连接
5,大部分流行的内容移到CDN:
-CDN在多个地方备份内容,这样内容离用户更近的机会就会更高
-CDN机器经常内存不足,因为内容太流行以致很少有内容进出内存的颠簸
6,不太流行的内容(每天1-20浏览次数)在许多colo站点使用YouTube服务器
-长尾效应。一个视频可以有多个播放,但是许多视频正在播放。随机硬盘块被访问
-在这种情况下缓存不会很好,所以花钱在更多的缓存上可能没太大意义。
-调节RAID控制并注意其他低级问题
-调节每台机器上的内存,不要太多也不要太少
视频服务关键点
1,保持简单和廉价
2,保持简单网络路径,在内容和用户间不要有太多设备
3,使用常用硬件,昂贵的硬件很难找到帮助文档
4,使用简单而常见的工具,使用构建在Linux里或之上的大部分工具
5,很好的处理随机查找(SATA,tweaks)
缩略图服务
1,做到高效令人惊奇的难
2,每个视频大概4张缩略图,所以缩略图比视频多很多
3,缩略图仅仅host在几个机器上
4,持有一些小东西所遇到的问题:
-OS级别的大量的硬盘查找和inode和页面缓存问题
-单目录文件限制,特别是Ext3,后来移到多分层的结构。内核2.6的最近改进可能让Ext3允许大目录,但在一个文件系统里存储大量文件不是个好主意
-每秒大量的请求,因为Web页面可能在页面上显示60个缩略图
-在这种高负载下Apache表现的非常糟糕
-在Apache前端使用squid,这种方式工作了一段时间,但是由于负载继续增加而以失败告终。它让每秒300个请求变为20个
-尝试使用lighttpd但是由于使用单线程它陷于困境。遇到多进程的问题,因为它们各自保持自己单独的缓存
-如此多的图片以致一台新机器只能接管24小时
-重启机器需要6-10小时来缓存
5,为了解决所有这些问题YouTube开始使用Google的BigTable,一个分布式数据存储:
-避免小文件问题,因为它将文件收集到一起
-快,错误容忍
-更低的延迟,因为它使用分布式多级缓存,该缓存与多个不同collocation站点工作
-更多信息参考Google Architecture,GoogleTalk Architecture和BigTable
数据库
1,早期
-使用MySQL来存储元数据,如用户,tags和描述
-使用一整个10硬盘的RAID 10来存储数据
-依赖于信用卡所以YouTube租用硬件
-YouTube经过一个常见的革命:单服务器,然后单master和多read slaves,然后数据库分区,然后sharding方式
-痛苦与备份延迟。master数据库是多线程的并且运行在一个大机器上所以它可以处理许多工作,slaves是单线程的并且通常运行在小一些的服务器上并且备份是异步的,所以slaves会远远落后于master
-更新引起缓存失效,硬盘的慢I/O导致慢备份
-使用备份架构需要花费大量的money来获得增加的写性能
-YouTube的一个解决方案是通过把数据分成两个集群来将传输分出优先次序:一个视频查看池和一个一般的集群
2,后期
-数据库分区
-分成shards,不同的用户指定到不同的shards
-扩散读写
-更好的缓存位置意味着更少的IO
-导致硬件减少30%
-备份延迟降低到0
-现在可以任意提升数据库的伸缩性
数据中心策略
1,依赖于信用卡,所以最初只能使用受管主机提供商
2,受管主机提供商不能提供伸缩性,不能控制硬件或使用良好的网络协议
3,YouTube改为使用colocation arrangement。现在YouTube可以自定义所有东西并且协定自己的契约
4,使用5到6个数据中心加CDN
5,视频来自任意的数据中心,不是最近的匹配或其他什么。如果一个视频足够流行则移到CDN
6,依赖于视频带宽而不是真正的延迟。可以来自任何colo
7,图片延迟很严重,特别是当一个页面有60张图片时
8,使用BigTable将图片备份到不同的数据中心,代码查看谁是最近的
学到的东西
1,Stall for time。创造性和风险性的技巧让你在短期内解决问题而同时你会发现长期的解决方案
2,Proioritize。找出你的服务中核心的东西并对你的资源分出优先级别
3,Pick your battles。别怕将你的核心服务分出去。YouTube使用CDN来分布它们最流行的内容。创建自己的网络将花费太多时间和太多money
4,Keep it simple!简单允许你更快的重新架构来回应问题
5,Shard。Sharding帮助隔离存储,CPU,内存和IO,不仅仅是获得更多的写性能
6,Constant iteration on bottlenecks:
-软件:DB,缓存
-OS:硬盘I/O
-硬件:内存,RAID
7,You succeed as a team。拥有一个跨越条律的了解整个系统并知道系统内部是什么样的团队,如安装打印机,安装机器,安装网络等等的人。With a good team all things are possible。
作者: shine    时间: 2007-11-29 16:50     标题: Twitter架构学习

Twitter是目前为止最大的Ruby on Rails应用,几个月间页面点击由0增长到几百万,现在的Twitter比今年月快了10000%
平台
Ruby on Rails
Erlang
MySQL
Mongrel
Munin
Nagios
Google Analytics
AWStats
Memcached
状态
成千上万的用户,真实数量保密
每秒钟600请求
每秒钟平均200-300个连接,峰值为800个连接
MySQL每秒钟处理2,400个请求
180个Rails实例,使用Mongrel作为Web服务器
1个MySQL服务器(one big 8 core box)和1个slave用于只读的统计和报告
30+进程用于处理其余的工作
8台Sun X4100s
Rails在200毫秒内处理一个请求
花费在数据库里的平均时间是50-100毫秒
超过16GB的memcached
架构
1,遇到非常常见的伸缩性问题
2,最初Twitter没有监听,没有图,没有统计,这让解决问题非常困难。后来添加了Munin和Nagios。在Solaris上使用工具有点困难,虽然有Google Analytics但是页面没有loading所以它没什么用
3,大量使用memcached作缓存
-例如,如果获得一个count非常慢,你可以将count在1毫秒内扔入memcached
-获取朋友的状态是很复杂的,这有安全等其他问题,所以朋友的状态更新后扔在缓存里而不是做一个查询。不会接触到数据库
-ActiveRecord对象很大所以没有被缓存。Twitter将critical的属性存储在一个哈希里并且当访问时迟加载
-90%的请求为API请求。所以在前端不做任何page和fragment缓存。页面非常时间敏感所以效率不高,但Twitter缓存了API请求
4,消息
-大量使用消息。生产者生产消息并放入队列,然后分发给消费者。Twitter主要的功能是作为不同形式(SMS,Web,IM等等)之间的消息桥
-使用DRb,这意味着分布式Ruby。有一个库允许你通过TCP/IP从远程Ruby对象发送和接收消息,但是它有点脆弱
-移到Rinda,它是使用tuplespace模型的一个分享队列,但是队列是持久的,当失败时消息会丢失
-尝试了Erlang
-移到Starling,用Ruby写的一个分布式队列
-分布式队列通过将它们写入硬盘用来挽救系统崩溃。其他大型网站也使用这种简单的方式
5,SMS通过使用第三方网关的API来处理,它非常昂贵
6,部署
-Twitter做了一次review并推出新的mongrel服务器,还没有优雅的方式
-如果mongrel服务器替换了则一个内部错误抛给用户
-所以的服务器一次杀死。没有使用rolling blackout方式因为消息队列状态保持在mongrel里,这将导致剩余的mongrel被堵塞
7,误用
-系统经常宕机,因为人们疯狂的添加任何人为朋友,24小时内有9000个朋友,这将让站点崩溃
-构建工具来检测这些问题,这样你可以找到何时何地发生这些错误
-无情的删除这些用户
8,分区
-将来计划分区,目前还没有。当前所做的改变已经足够
-分区的计划基于时间,而不是用户,因为大部分请求都是本地的
-由于memoization分区会很难。Twitter不能保证只读的操作真的为只读,有可能写入一个只读的slave,这很糟糕
9,Twitter的API流量是Twitter站点的10倍
-Twitter所做的最重要的事情就是API
-保持服务简单允许开发人员在Twitter的基础组织上构建一些比Twitter自己所想到的更好的主意。例如,Twitterrific是一个使用Twitter优美的方式
学到的东西
1,和社区交流。不要隐藏并尝试自己解决所有问题。如果你提问,有许多聪明的人士愿意帮忙
2,将你的伸缩计划当成一个商业计划,聚集一帮顾问来帮助你
3,自己构建它。Twitter花费大量时间来尝试其他人的似乎可以工作的解决方案,但是失败了。自己构建一些东西会更好,这样你至少可以控制它并且构建你需要的特性
4,在用户的限度上构建。人们可能尝试弄垮你的系统。提高理由的限度和检测机制来保护你的系统不被杀死
5,不要让数据库成为首要瓶颈,并不是所有东西都需要一个很大的join,缓存数据,考虑其他创造性的方式来获得结果。一个好例子在里Twitter, Rails, Hammers, and 11,000 Nails per Second谈到
6,让你的应用一开始就很容易分区。这样你会一直有一种方式来伸缩你的系统
7,认知你的系统是很慢的,马上添加报告来跟踪问题
8,优化数据库
-索引所有东西,Rails不会为你做这件事
-解释你的查询是怎样运行的,索引可能不是按你想像的去做
-大量的非常规化。例如,Twitter一起存储用户ID和朋友ID,这预防了大量的开销昂贵的join
9,缓存所有东西,个别的ActiveRecord对象目前没有被缓存。目前查找已经足够快
10,测试一切
-你想知道当你部署时一起工作正常
-Twitter现在有一个完整的test suite。所以当缓存失效时Twitter可以在go live之前找到问题
11,使用异常提示和异常日志来获得立即的错误提示,这样你可以发现正确的方式
12,不要做傻事
-伸缩改变了傻东西
-尝试一次加载3000个朋友到内存中可能带来服务器崩溃,但是当只有4个朋友时它工作的很好
13,大部分性能不是来自语言,而是来自应用设计
14,通过创建一个API来让你的站点开放服务。Twitter的API是它成功的一个大原因。它允许用户创建一个扩展和生态系统。你可以从不做你的用户可以做的工作,这样你就不会有创造性。所以开发你的系统并且让其他人将他们的应用与你的应用集成变容易
作者: shine    时间: 2007-11-29 16:51     标题: Google架构学习

Google是伸缩性的王者。Google一直的目标就是构建高性能高伸缩性的基础组织来支持它们的产品。
平台
Linux
大量语言:Python,Java,C++
状态
在2006年大约有450,000台廉价服务器
在2005年Google索引了80亿Web页面,现在没有人知道数目
目前在Google有超过200个GFS集群。一个集群可以有1000或者甚至5000台机器。成千上万的机器从运行着5000000000000000字节存储的GFS集群获取数据,集群总的读写吞吐量可以达到每秒40兆字节
目前在Google有6000个MapReduce程序,而且每个月都写成百个新程序
BigTable伸缩存储几十亿的URL,几百千千兆的卫星图片和几亿用户的参数选择
堆栈
Google形象化它们的基础组织为三层架构:
1,产品:搜索,广告,email,地图,视频,聊天,博客
2,分布式系统基础组织:GFS,MapReduce和BigTable
3,计算平台:一群不同的数据中心里的机器
4,确保公司里的人们部署起来开销很小
5,花费更多的钱在避免丢失日志数据的硬件上,其他类型的数据则花费较少
可信赖的存储机制GFS(Google File System)
1,可信赖的伸缩性存储是任何程序的核心需求。GFS就是Google的核心存储平台
2,Google File System - 大型分布式结构化日志文件系统,Google在里面扔了大量的数据
3,为什么构建GFS而不是利用已有的东西?因为可以自己控制一切并且这个平台与别的不一样,Google需要:
-跨数据中心的高可靠性
-成千上万的网络节点的伸缩性
-大读写带宽的需求
-支持大块的数据,可能为上千兆字节
-高效的跨节点操作分发来减少瓶颈
4,系统有Master和Chunk服务器
-Master服务器在不同的数据文件里保持元数据。数据以64MB为单位存储在文件系统中。客户端与Master服务器交流来在文件上做元数据操作并且找到包含用户需要数据的那些Chunk服务器
-Chunk服务器在硬盘上存储实际数据。每个Chunk服务器跨越3个不同的Chunk服务器备份以创建冗余来避免服务器崩溃。一旦被Master服务器指明,客户端程序就会直接从Chunk服务器读取文件
6,一个上线的新程序可以使用已有的GFS集群或者可以制作自己的GFS集群
7,关键点在于有足够的基础组织来让人们对自己的程序有所选择,GFS可以调整来适应个别程序的需求
使用MapReduce来处理数据
1,现在你已经有了一个很好的存储系统,你该怎样处理如此多的数据呢?比如你有许多TB的数据存储在1000台机器上。数据库不能伸缩或者伸缩到这种级别花费极大,这就是MapReduce出现的原因
2,MapReduce是一个处理和生成大量数据集的编程模型和相关实现。用户指定一个map方法来处理一个键/值对来生成一个中间的键/值对,还有一个 reduce方法来合并所有关联到同样的中间键的中间值。许多真实世界的任务都可以使用这种模型来表现。以这种风格来写的程序会自动并行的在一个大量机器的集群里运行。运行时系统照顾输入数据划分、程序在机器集之间执行的调度、机器失败处理和必需的内部机器交流等细节。这允许程序员没有多少并行和分布式系统的经验就可以很容易使用一个大型分布式系统资源
3,为什么使用MapReduce?
-跨越大量机器分割任务的好方式
-处理机器失败
-可以与不同类型的程序工作,例如搜索和广告。几乎任何程序都有map和reduce类型的操作。你可以预先计算有用的数据、查询字数统计、对TB的数据排序等等
4,MapReduce系统有三种不同类型的服务器
-Master服务器分配用户任务到Map和Reduce服务器。它也跟踪任务的状态
-Map服务器接收用户输入并在其基础上处理map操作。结果写入中间文件
-Reduce服务器接收Map服务器产生的中间文件并在其基础上处理reduce操作
5,例如,你想在所有Web页面里的字数。你将存储在GFS里的所有页面抛入MapReduce。这将在成千上万台机器上同时进行并且所有的调整、工作调度、失败处理和数据传输将自动完成
-步骤类似于:GFS -> Map -> Shuffle -> Reduction -> Store Results back into GFS
-在MapReduce里一个map操作将一些数据映射到另一个中,产生一个键值对,在我们的例子里就是字和字数
-Shuffling操作聚集键类型
-Reduction操作计算所有键值对的综合并产生最终的结果
6,Google索引操作管道有大约20个不同的map和reduction。
7,程序可以非常小,如20到50行代码
8,一个问题是掉队者。掉队者是一个比其他程序慢的计算,它阻塞了其他程序。掉队者可能因为缓慢的IO或者临时的CPU不能使用而发生。解决方案是运行多个同样的计算并且当一个完成后杀死所有其他的
9,数据在Map和Reduce服务器之间传输时被压缩了。这可以节省带宽和I/O。
在BigTable里存储结构化数据
1,BigTable是一个大伸缩性、错误容忍、自管理的系统,它包含千千兆的内存和1000000000000000的存储。它可以每秒钟处理百万的读写
2,BigTable是一个构建于GFS之上的分布式哈希机制。它不是关系型数据库。它不支持join或者SQL类型查询
3,它提供查询机制来通过键访问结构化数据。GFS存储存储不透明的数据而许多程序需求有结构化数据
4,商业数据库不能达到这种级别的伸缩性并且不能在成千上万台机器上工作
5,通过控制它们自己的低级存储系统Google得到更多的控制权来改进它们的系统。例如,如果它们想让跨数据中心的操作更简单这个特性,它们可以内建它
6,系统运行时机器可以自由的增删而整个系统保持工作
7,每个数据条目存储在一个格子里,它可以通过一个行key和列key或者时间戳来访问
8,每一行存储在一个或多个tablet中。一个tablet是一个64KB块的数据序列并且格式为SSTable
9,BigTable有三种类型的服务器:
-Master服务器分配tablet服务器,它跟踪tablet在哪里并且如果需要则重新分配任务
-Tablet服务器为tablet处理读写请求。当tablet超过大小限制(通常是100MB-200MB)时它们拆开tablet。当一个Tablet服务器失败时,则100个Tablet服务器各自挑选一个新的tablet然后系统恢复。
-Lock服务器形成一个分布式锁服务。像打开一个tablet来写、Master调整和访问控制检查等都需要互斥
10,一个locality组可以用来在物理上将相关的数据存储在一起来得到更好的locality选择
11,tablet尽可能的缓存在RAM里
硬件
1,当你有很多机器时你怎样组织它们来使得使用和花费有效?
2,使用非常廉价的硬件
3,A 1,000-fold computer power increase can be had for a 33 timeslower cost if you you use a failure-prone infrastructure rather than aninfrastructure built on highly reliable components. You must buildreliability on top of unreliability for this strategy to work.
4,Linux,in-house rack design,PC主板,低端存储
5,Price per wattage on performance basis isn’t getting better. Have huge power and cooling issues
6,使用一些collocation和Google自己的数据中心
其他
1,迅速更改而不是等待QA
2,库是构建程序的卓越方式
3,一些程序作为服务提供
4,一个基础组织处理程序的版本,这样它们可以发布而不用害怕会破坏什么东西
Google将来的方向
1,支持地理位置分布的集群
2,为所有数据创建一个单独的全局名字空间。当前的数据由集群分离
3,更多和更好的自动化数据迁移和计算
4,解决当使用网络划分来做广阔区域的备份时的一致性问题(例如保持服务即使一个集群离线维护或由于一些损耗问题)
学到的东西
1,基础组织是有竞争性的优势。特别是对Google而言。Google可以很快很廉价的推出新服务,并且伸缩性其他人很难达到。许多公司采取完全不同的方式。许多公司认为基础组织开销太大。Google认为自己是一个系统工程公司,这是一个新的看待软件构建的方式
2,跨越多个数据中心仍然是一个未解决的问题。大部分网站都是一个或者最多两个数据中心。我们不得不承认怎样在一些数据中心之间完整的分布网站是很需要技巧的
3,如果你自己没有时间从零开始重新构建所有这些基础组织你可以看看Hadoop。Hadoop是这里很多同样的主意的一个开源实现
4,平台的一个优点是初级开发人员可以在平台的基础上快速并且放心的创建健全的程序。如果每个项目都需要发明同样的分布式基础组织的轮子,那么你将陷入困境因为知道怎样完成这项工作的人相对较少
5,协同工作不一直是掷骰子。通过让系统中的所有部分一起工作则一个部分的改进将帮助所有的部分。改进文件系统则每个人从中受益而且是透明的。如果每个项目使用不同的文件系统则在整个堆栈中享受不到持续增加的改进
6,构建自管理系统让你没必要让系统关机。这允许你更容易在服务器之间平衡资源、动态添加更大的容量、让机器离线和优雅的处理升级
7,创建可进化的基础组织,并行的执行消耗时间的操作并采取较好的方案
8,不要忽略学院。学院有许多没有转变为产品的好主意。Most of what Google has done has prior art, just not prior large scale deployment.
9,考虑压缩。当你有许多CPU而IO有限时压缩是一个好的选择。
作者: shine    时间: 2007-11-29 16:53     标题: Load Balancing

基于Shared Nothing Architecture做Load Balancing,遵循REST的无状态模型,不用考虑Sticky Sessions
一、DNS Load Balancing
DNS Load Balancing是最简单的方式,它将相同域名解析到不同IP
由于TTL和缓存时间,DNS不能实时更新clusters的更改
DNS方式很难自定义配置balance策略
DNS方式对traffic的balance不准确,对特定地域而言DNS会将特定域名一直路由到一个IP上
DNS方式很难搞redundancy和failover
二、用硬件做Load Balancing
Alteon AS range(application switches)
Citrix Netscalers
Cisco CSS range(content-switching servers)
Foundry Networks ServerIron
商用产品的缺点就是贵
相比DNS方式,用硬件产品做Load Balancing很好的支持failover
三、用软件做Load Balancing
Perlbal
Pound
Nginx
LVS
幸好有免费开源软件
四、Layer 4 Load Balancing
即在OSI7层模型的第4层搞Load Balancing,也就是在Transport这层
最简单的方式是使用Round robin算法来做Load Balancing,Load Balancer捕获请求并分发到backendserver列表中的第一个server,并标记该Server为last used server,下次请求时则分发到下一个backendserver
五、Layer 7 Load Balancing
在Application这层搞Load Balancing,将HTTP请求headers纳入balancing策略考虑
HTTP请求URL本身就是Layer 7 Load Balancing的例子
可以在real server cluster之上搞一个Hash table作为Layer 7 LoadBalancing,访问某一特定的URL时分发到一个特定的realserver,这样对该特定server可以每次都命中特定的缓存而不用在每个real server都建立同样的缓存
Layer 7 Load Balancing对HTTP请求的解析开销很大,所以它的scalability相对Layer 4 Load Balancing而言有限
六,Huge-Scale Balancing
超级大型的应用我们需要GSLB(global server load balancing)来将负载balance到不同的Data Center,将客户端路由到最近的DC以保持最少的latency
Akamai EdgePlatform提供整合的服务
七、Balancing非HTTP的Traffic
例如email,由于SMTP与HTTP很类似,我们可以使用HTTP Load Balancer来balance email traffic,只需创建一个新的service来监听25端口并连接到real backend servers
积极!努力!低调!百折不挠!http://www.linuxtone.org 免费提供Linux系统集群部署相关咨询服务! Gmai:cnseek@gmail.com
分享才能进步!帮助他人就是在帮助自己! 共同学习探讨Linux!
  Linux= howto+man ! ^_^

TOP

这篇文章不错,受教了!

实践是硬道理!
开源,人人为我,我为人人!

TOP

呼吸的是如此的自然,即使是狼也感觉不到

TOP

发新话题