All posts by dotte

An Unorthodox Approach to Database Design : The Coming of the Shard

Update 4: Why you don’t want to shard. by Morgon on the MySQL Performance Blog. Optimize everything else first, and then if performance still isn’t good enough, it’s time to take a very bitter medicine.
Update 3: Building Scalable Databases: Pros and Cons of Various Database Sharding Schemes by Dare Obasanjo. Excellent discussion of why and when you would choose a sharding architecture, how to shard, and problems with sharding.
Update 2: Mr. Moore gets to punt on sharding by Alan Rimm-Kaufman of 37signals. Insightful article on design tradeoffs and the evils of premature optimization. With more memory, more CPU, and new tech like SSD, problems can be avoided before more exotic architectures like sharding are needed. Add features not infrastructure. Jeremy Zawodny says he’s wrong wrong wrong. we’re running multi-core CPUs at slower clock speeds. Moore won’t save you.
Update: Dan Pritchett shares some excellent Sharding Lessons: Size Your Shards, Use Math on Shard Counts, Carefully Consider the Spread, Plan for Exceeding Your Shards

Once upon a time we scaled databases by buying ever bigger, faster, and more expensive machines. While this arrangement is great for big iron profit margins, it doesn’t work so well for the bank accounts of our heroic system builders who need to scale well past what they can afford to spend on giant database servers. In a extraordinary two article series, Dathan Pattishall, explains his motivation for a revolutionary new database architecture–sharding–that he began thinking about even before he worked at Friendster, and fully implemented at Flickr. Flickr now handles more than 1 billion transactions per day, responding in less then a few seconds and can scale linearly at a low cost.

What is sharding and how has it come to be the answer to large website scaling problems?

Information Sources

What is sharding?

While working at Auction Watch, Dathan got the idea to solve their scaling problems by creating a database server for a group of users and running those servers on cheap Linux boxes. In this scheme the data for User A is stored on one server and the data for User B is stored on another server. It’s a federated model. Groups of 500K users are stored together in what are called shards.

The advantages are:

  • High availability. If one box goes down the others still operate.
  • Faster queries. Smaller amounts of data in each user group mean faster querying.
  • More write bandwidth. With no master database serializing writes you can write in parallel which increases your write throughput. Writing is major bottleneck for many websites.
  • You can do more work. A parallel backend means you can do more work simultaneously. You can handle higher user loads, especially when writing data, because there are parallel paths through your system. You can load balance web servers, which access shards over different network paths, which are processed by separate CPUs, which use separate caches of RAM and separate disk IO paths to process work. Very few bottlenecks limit your work.

    How is sharding different than traditional architectures?

    Sharding is different than traditional database architecture in several important ways:

  • Data are denormalized. Traditionally we normalize data. Data are splayed out into anomaly-less tables and then joined back together again when they need to be used. In sharding the data are denormalized. You store together data that are used together.

    This doesn’t mean you don’t also segregate data by type. You can keep a user’s profile data separate from their comments, blogs, email, media, etc, but the user profile data would be stored and retrieved as a whole. This is a very fast approach. You just get a blob and store a blob. No joins are needed and it can be written with one disk write.

  • Data are parallelized across many physical instances. Historically database servers are scaled up. You buy bigger machines to get more power. With sharding the data are parallelized and you scale by scaling out. Using this approach you can get massively more work done because it can be done in parallel.
  • Data are kept small. The larger a set of data a server handles the harder it is to cash intelligently because you have such a wide diversity of data being accessed. You need huge gobs of RAM that may not even be enough to cache the data when you need it. By isolating data into smaller shards the data you are accessing is more likely to stay in cache.

    Smaller sets of data are also easier to backup, restore, and manage.

  • Data are more highly available. Since the shards are independent a failure in one doesn’t cause a failure in another. And if you make each shard operate at 50% capacity it’s much easier to upgrade a shard in place. Keeping multiple data copies within a shard also helps with redundancy and making the data more parallelized so more work can be done on the data. You can also setup a shard to have a master-slave or dual master relationship within the shard to avoid a single point of failure within the shard. If one server goes down the other can take over.
  • It doesn’t use replication. Replicating data from a master server to slave servers is a traditional approach to scaling. Data is written to a master server and then replicated to one or more slave servers. At that point read operations can be handled by the slaves, but all writes happen on the master.

    Obviously the master becomes the write bottleneck and a single point of failure. And as load increases the cost of replication increases. Replication costs in CPU, network bandwidth, and disk IO. The slaves fall behind and have stale data. The folks at YouTube had a big problem with replication overhead as they scaled.

    Sharding cleanly and elegantly solves the problems with replication.

    Some Problems With Sharding

    Sharding isn’t perfect. It does have a few problems.

  • Rebalancing data. What happens when a shard outgrows your storage and needs to be split? Let’s say some user has a particularly large friends list that blows your storage capacity for the shard. You need to move the user to a different shard.

    On some platforms I’ve worked on this is a killer problem. You had to build out the data center correctly from the start because moving data from shard to shard required a lot of downtime.

    Rebalancing has to be built in from the start. Google’s shards automatically rebalance. For this to work data references must go through some sort of naming service so they can be relocated. This is what Flickr does. And your references must be invalidateable so the underlying data can be moved while you are using it.

  • Joining data from multiple shards. To create a complex friends page, or a user profile page, or a thread discussion page, you usually must pull together lots of different data from many different sources. With sharding you can’t just issue a query and get back all the data. You have to make individual requests to your data sources, get all the responses, and the build the page. Thankfully, because of caching and fast networks this process is usually fast enough that your page load times can be excellent.
  • How do you partition your data in shards? What data do you put in which shard? Where do comments go? Should all user data really go together, or just their profile data? Should a user’s media, IMs, friends lists, etc go somewhere else? Unfortunately there are no easy answer to these questions.
  • Less leverage. People have experience with traditional RDBMS tools so there is a lot of help out there. You have books, experts, tool chains, and discussion forums when something goes wrong or you are wondering how to implement a new feature. Eclipse won’t have a shard view and you won’t find any automated backup and restore programs for your shard. With sharding you are on your own.
  • Implementing shards is not well supported. Sharding is currently mostly a roll your own approach. LiveJournal makes their tool chain available. Hibernate has a library under development. MySQL has added support for partioning. But in general it’s still something you must implement yourself.

    See Also

  • The Flickr Architecture for more interesting ideas on how to implement sharding.
  • The Google Arhitecture.
  • The LiveJournal Architecture. They talk quite a bit about their sharding approach and give a lot of helpful details.
  • The Shard category.

from:http://highscalability.com/unorthodox-approach-database-design-coming-shard

Facebook Architecture

大型Web 2.0企业技术架构集

YouTube网站架构

YouTube的成长速度惊人,目前每天视频访问量已达1亿,但站点维护人员很少。他们是如何管理,以实现如此强大供应能力的?被Google收购后,又在走什么样的发展道路呢?

平台

l Apache

l Python

l Linux (SuSe版本)

l MySQL

l psyco(python->C动态编译器)

l lighttpd(取代Apache作为视频服务器)

统计数据

l 每天高达1亿的视频访问量。

l 创建于2005年2月。

l 2006年3月,每日视频访问量达到3千万。

l 2006年7月,每日视频访问量达到1亿。

l 2个系统管理员,2个系统扩展架构师。

l 2个产品功能开发人员,2个网络工程师,1个DBA。

性能监控手段

网站维护人员每天多次重复的工作,类似于执行下面这段代码。

while (true)

{

identify_and_fix_bottlenecks();

drink();

sleep();

notice_new_bottleneck();

}

Web服务器

l NetScalar用于实现负载均衡和对静态内容的缓存。

l Apache运行于mod_fast_cgi模式。

l 一台Python应用服务器专门负责Web请求的路由。

l 应用服务器与各个数据库和其他类型信息源建立会话,取得所需数据并生成HTML页面。

l 通过增加服务器,一般就可以实现对Web层的扩展。

l Python代码的效率一般不是瓶颈所在,真正瓶颈在于RPC请求。

l Python应用的开发和发布快速灵活,这是他们能够应对激烈竞争的重要保证。

l 正常情况下,能将每个页面的响应时间控制在100ms以内。

l 利用psyco(python->C的动态编译器),通过JIT编译方法实现内部循环的优化。

l 在CPU高敏感的活动(如加密)中使用C扩展。

l 预生成某些HTML页面并缓存。

l 在数据库中实现行级缓存。

l 对Python结果对象缓存。

l 预先计算某些数据,并发送至对应应用,以形成本地缓存。这项策略目前还未大规模运用。不需要每个应用服务器都花很多时间将预先计算,并将结果数据发送到所有服务器。有一个代理机专门负责此项工作——监控数据的变化情况,预先计算并发送。

视频服务

l 成本,包括带宽、硬件购置和电力的消耗。

l 每段视频均通过刀片群集(mini-cluster)服务器管理,也就是说由多个机器联合提供视频内容服务。

l 刀片群集管理的优势:

n 多个磁盘提供内容服务,意味着更快的速度。

n 提供了动态余量。一台机器停止服务,其他可以接管。

n 实现了在线备份。

l 使用lighttpd作为视频的Web服务器:

n Apache的成本太高。

n 使用epoll同时操作多个fds(文件描述符)。

n 从单进程切换到多进程,以处理更多连接。

l 将频繁访问的内容转移到CDN(content delivery network):

n CDN将内容复制到多个源,因此对用户来说,获取数据时可以选择最优路径。

n CDN服务器主要依靠内存提供服务,否则因访问频繁,可能引起抖动。

l 低访问量的内容(每天1-20的访问量),YouTube服务器以colo模式管理。

n 长尾效应。单个视频的访问量不高,但大量视频合起来就不一样了。各磁盘块被访问到的概率是随机的。

n 在这种情况下,花费了大量投入的缓存,作用并不大。这个问题是当前研究的一个热点。如果你有一个长尾型的产品,请记住缓存不见得就是解决性能问题的救世主。

n 优化调整RAID控制器,在底层策略上下功夫。

n 调整每台服务器上的内存,不要太大也不要太小。

视频服务中的几个关键点

l 整体方案力求简洁、廉价。

l 网络路径保持最短,不要在内容和终端用户间部署太多设备。路由器、交换机等可能承受不了这么高的负载。

l 尽量采用普通硬件。高档硬件的支撑设备很昂贵,实际中往往发现它们的作用并不大。

l 使用简单、通用的工具。YouTube优先考虑Linux自带的大多数工具。

l 正确处理随机寻道问题(采用SATA、优化调整等)。

视频截图的处理

l 实现视频截图和缩略图的高效访问,有着惊人的难度。

l 如果每视频平均4个缩略图,那么总图量是非常庞大的。

l 缩略图存储在有限几台机器上。

l 大量小型对象服务中存在的难点问题:

n 磁盘寻道频繁,操作系统级inode(译者注:Linux/Unix系统中记录文件信息的对象)缓存和页缓存多。

n 每个目录受到最大文件数限制。Ext3文件系统可管理的目录层级非常多,即便依托2.6内核将大目录处理性能提高100倍左右,在文件系统中存储大量文件情况下,仍然不是一个值得称许的解决策略。

n 平均含60个缩略图的页面的访问量很大。

n 在如此高负载条件下,Apache的性能急剧下降。

n 使用squid(反向代理)作为Apache的前端,能起到一定作用。但随着负载的上升,性能最终会呈下降趋势——处理能力由原来的300个/s降为20个/s。

n 尝试使用lighttpd。这是一个单进程且单线程的应用,每个进程拥有独立缓存。为了提高性能,需要运行多个进程实例。如此一来,造成了资源浪费和性能限制等问题。

n 大量图片需要处理的情况下,向系统新增一台机器,需要24个小时。

n 重启机器后,系统需要花费6-10小时,来将内容从磁盘载入缓存。

l 为了解决这些问题,他们使用了Google的分布式数据存储策略——BigTable:

n 将文件拢在一起,避免了小文件问题。

n 速度快;即使运行在不可靠网络上,其错误率也是可以容忍的。

n 未知风险小,因为它使用了分布式的多级缓存。缓存工作于colo结构上。

数据库[DSJ2]

l 早期:

n 使用MySQL存储用户、标签和详细描述等原数据。

n 数据存储在挂10磁盘、10卷的单片RAID上。

n 租借硬件。负载上升,添加新设备时他们需要数天时间。

n 和其他很多系统一样,他们走过了这样一段历史:单服务器,主从服务器(单台主服务器,依靠多台从服务器实现读数据的负载均衡),数据库分割(逐渐稳定于分割模式)。

n 存在数据复制延迟的问题。主服务器是多线程的,硬件条件好,性能高;而从服务器运行于单线程模式,且硬件条件差一些。数据从主服务器到从服务器的复制是异步的,因此从服务器上的数据往往严重滞后于主服务器。

n 数据更新后,缓存将被清除,需从I/O更慢的磁盘读取,从而造成复制更为缓慢。

n 在这种以数据复制为中心的架构下,稍微提升写性能,都必须付出巨大成本。

n 他们的解决办法之一是将数据分割到两个不同群集,从而分解访问压力:一个视频池和一个普通群集。这个解决方案的出发点是:访问者最想看到的是视频,因此应该为这些功能分配最多资源;而YouTube社交功能是次重要的,因此做次优配置。

l 后来:

n 继续执行数据库分割策略。

n 按用户划分数据。

n 数据的读、写操作分离。

n 改进了缓存数据定位策略,减少I/O。

n 所需硬件减少了30%。

n 数据复制延迟降为0。

n 现在几乎能做到对数据库任意扩展。

数据中心策略

l 开始的时候使用托管机房。除非事先签订了协议,不能自行扩展硬件和网络系统。因此,他们后来选择了colo,可以完全按照自己的设计要求部署系统。

l 使用5/6个数据中心,外加CDN。视频的来源可以是任何一个数据中心,而非就近选择等模式。若访问频度很高,则移至CDN。

l 视频的访问性能依赖于带宽,而不是其他因素。对于图片,其他因素的影响就很大(例如页面平均图片数)。

l 利用BigTable将图片复制到各个数据中心。

经验教训

l 敢于坚持。 局部创新和一些有一定风险的策略,能够解决短期问题。如果一直坚持下去,就一定能找到长期解决方案。

l 确定事情的优先级。找出服务中的关键部分,优先为其配置资源、投入力量。

l 学会选择与合作。不要害怕将项目的关键部分外包。YouTube使用CDN向广大用户提供内容。如果完全依靠自己建设这样一个网络,需要花费的成本和时间都是惊人的。在你的系统中,应该可以存在这类同样的部件。

l 一切从简! 简单,将保证系统具有良好的可重构性以及对问题的快速响应。没有人真正知道怎么样才算是简单,如果在需要做出改变时,相关人员没有产生畏难情绪,就说明达到了简单的目标。

l 数据分割。数据分割策略将实现对磁盘、CPU、内存和IO实体和指标的优化配置,改善的不仅仅是写数据的性能。

l 对瓶颈资源做持续改善:

n 软件层:数据库、缓存

n 操作系统层:磁盘I/O

n 硬件层:内存、RAID

l 团队是成功的基础。在一个有良好纪律的团队中,所有成员都能够准确把握整个系统,了解深层问题。拥有一个好的团队,将无往而不胜。

Facebook 详解

Facebook是一个社会化网络站点。它于2004年2月4日上线。

Facebook 的创始人是Mark Zuckerberg,他是哈佛大学的学生,毕业于Asdsley高中。最初,网站的注册仅限于哈佛学院(译者注:哈佛大学的本科生部)的学生。在之后的两个月内,注册扩展到波士顿地区的其他高校(波士顿学院 Boston College、波士顿大学 Boston University、麻省理工学院 MIT、特福茨大学 Tufts)以及罗切斯特大学 Rochester、斯坦福大学Stanford、纽约大学 NYU、西北大学和所有的常春藤名校。第二年,很多其他学校也加入进来。最终,在全球范围内只要有一个大学后缀电子邮箱的人(如 .edu,.ac.uk等)都可以注册。之后,在Facebook中也可以建立起高中和公司的社会化网络。从2006年9月11日起,任何用户输入有效电子邮件地址和自己的年龄段,即可加入。用户可以选择加入一个或多个网络,比如中学的、公司的或地区的。

据2007 年7月数据,Facebook在所有以服务于大学生为主要业务的网站中,拥有最多的用户——三千四百万活跃用户(包括在非大学网络中的用户)。从2006 年9月到2007年9月间,该网站在全美网站中的排名由第60名上升至第7名。同时Facebook也是美国排名第一的照片分享站点,每天上载八百五十万张照片。这甚至超过其他专门的照片分享站点,如Flickr。

网站的名字Facebook来自传统的纸质“花名册”。通常美国的大学和预科学校把这种印有学校社区所有成员的“花名册”发放给新来的学生和教职员工,帮助大家认识学校的其他成员。
运营状况

网站对用户是免费的,其收入来自广告。广告包括横幅广告和由商家赞助的小组(2006年4月,有消息称Facebook每周的收入超过一百五十万美元)。用户建立自己的档案页,其中包括照片和个人兴趣;用户之间可以进行公开或私下留言;用户还可以加入其他朋友的小组。用户详细的个人信息只有同一个社交网络(如学校或公司)的用户或被认证了的朋友才可以查看。据TechCrunch(译者:硅谷最著名的IT新闻博客)报道,“在Facebook覆盖的所有学校中,85%的学生有Facebook档案;(所有这些加入Facebook的学生中)60%每天都登陆Facebook,85%至少每周登陆一次,93% 至少每个月一次。”据Facebooke 发言人Chris Hughes说,“用户平均每天在Facebook上花19分钟。”据新泽西州一家专门进行大学市场调研的公司“学生监听”在2006年进行的调查显示,Facebook在“本科生认为最in的事”中排名第二,仅次于苹果的iPod,和啤酒与性并列。

起步

Mark Zuckerberg在Andrew McCollum和Eduardo Saverin的支持下,于2004年2月创办了“The Facebook”。当时他是哈佛大学的学生。月底的时候,半数以上的哈佛本科生已经成了注册用户。

同时,Dustin Moskovitz和Chris Hughes也加入进来,帮助推广网站,将Facebook扩展到麻省理工学院、波士顿大学和波士顿学院。扩展一直持续到2004年4月,包括了所有长春藤院校和其他一些学校。之后的一个月,Zuckerberg,McCollum和Moskovitz搬到加利福尼亚州的Palo Alto市(译者:斯坦福大学所在地,硅谷的发源地),在Adam D’Angelo和Sean Parker(译者:著名的第一代P2P音乐分享网站Napster的创始人)的帮助下继续Facebook的发展。同年9月,另一个社会化网络站点 ConnectU的合伙人Divya Narendra,Cameron Winklevoss和Tyler Winlevoss把Facebook告上法庭。他们称Zuckerberg非法使用了他们在让他帮助建站时开发的源代码。与此同时,Facebook获得了PayPal创始人Peter Thiel提供的约五十万美金的天使投资。到12月时,Facebook的用户数超过100万。

2005

2005 年 5月,Facebook获得Accel Partners的一千两百七十万美元风险投资。2005年8月23日,Facebook从AboutFace公司手中以20万美元购得 facebook.com域名,从此从名字中把The去掉了。网站当时进行了重大改进。据Zuckerberg称,目的是提高用户档案页面的用户友好性。这个月,McCollum回哈佛大学继续进修,同时仍旧以顾问的身份为Facebook工作,并在暑假来公司工作。Hughes则继续在剑桥市(译者:哈佛大学所在地)履行他公司发言人的职责。2005年9月2日,Zuckerberg推出了Facebook高中版,并称这是最合乎逻辑的下一步。最初,Facebook高中版虽然被定位为需要邀请才能加入的社区,但是仅15天以后大部分高中的网络不需要密码也可以加入了(虽然Facebook账户还是需要的)。到10月份,Facebook已经扩展到大部分美国和加拿大的规模更小的大学和学院。除此之外,还扩展到英国的21所大学、墨西哥的 ITESM、波多黎各大学以及维京群岛大学。2005年12月11日,澳大利亚和新西兰的大学也加入了Facebook。至此,Facebook中共有超过2000所大学和高中。

2006

2006年 2月27日,应用户要求,Facebook允许大学生把高中生加为他们的朋友。约一个月后,2006年3月28日,《新闻周刊》报道Facebook可能被收购,谈判正在进行中。据报道,Facebook拒绝了一个七亿五千万美金的收购条件,甚至有传闻收购价格达到了20亿美金。同年四月,Peter Thiel、Greylock Partners和Meritech Capital Partners额外投资了两千五百万美元。5月,Facebook扩展到印度的印度理工学院和印度管理学院。6月,Facebook状告 Quizsender.com抄袭其设计风格,要求赔偿十万美元。7月25日,Facebook增加了更多提高收入机会的功能。在同苹果iTunes合作的推广活动中,加入“苹果学生小组”的用户可以在9月10日之前每周下载25首单曲。这个推广活动的目的是让学生们在秋季学期开学前对苹果和 Facebook的服务都更熟悉和喜爱。8月,Facebook又加入了德国的大学和以色列的高中。8月22日,Facebook推出Facebook记事本功能——一个可以添加标签、嵌入图片和评论的博客服务。同时用户可以从其他博客服务中导入。2006年9月11日,Facebook对所有互联网用户开放,这引起了很多现有用户的抗议。但两周后,Facebook注册仍旧对所有拥有有效电子邮件地址的人开放。

2007

2007 年 5月10日,Facebook宣布了一个提供免费分类广告的计划,直接和其他分类广告站点,如Craigslist竞争。这个被称为“Facebook市场”的功能于2007年5月14日上线。2007年5月24日,Facebook推出应用编程接口(API)。通过这个API,第三方软件开发者可以开发在Facebook网站运行的应用程序。这被称为Facebook开放平台(Facebook Platform)。同年6月,和iTunes的合作继续为用户提供免费音乐单曲下载。7月,Facebook完成了第一次对其他公司的收购,从 Blake Ross和Joe Hewitt手中收购了Parakey(译者:Ross和Hewitt是火狐浏览器的作者,Parakey是一个被称为网络操作系统的平台)。7月24 日,Facebook聘用YouTube的前CFO Gideon Yu为CFO,替换了Michael Sheridan。8月,Facebook成为新闻周刊的封面故事。

2007年9月25日,微软宣布他们可能会收购Facebook的部分股份。据称Facebook被完全收购可能性不大,因为其创始人Mark Zuckerberg希望保持独立。

网站功能

墙(The Wall)

墙就是用户档案页上的留言板。有权浏览某一个用户完整档案页的其他用户,都可以看到该用户的墙。用户墙上的留言还会用Feed输出。很多用户通过他们朋友的墙,留短信儿。更私秘的交流则通过“消息(Messages)”进行。消息发送到用户的个人信箱,就象电子邮件,只有收信人和发信人可以看到。

2007年7月起,用户可以在墙上贴附件。之前,只允许文本内容。

礼物(Gift)(Facebook礼物)

2007 年 2月,Facebook新增了“礼物”功能。朋友们可以互送“礼物”--一些由前苹果设计师Susan Kare设计的有趣的小图标。礼物从Facebook的虚拟礼品店选择,赠送时附上一条消息。收到的礼物以及所附的消息会显示在收礼者的“墙”上,除非送礼者设定这个礼物是私秘的。另外,在墙的上方还有一个“礼盒”。用户收到的所有礼物都在礼盒中。公开的礼物显示送礼者的名字,私秘的礼物则显示“私人”。

另有一个“匿名”的选项。虽然所有人都可以看到礼物,但只有收礼者可以看到送礼者的名字和消息。这种礼物只在礼盒中,而不在墙上显示。

Facebook 用户注册时免费获得一个礼物,以后送出每个礼物需要花费一美元。最初推出的礼物是有关“情人节”的。同年2月由此产生收入的50%捐献给Susan G. Komen乳腺癌基金会。之后,Facebook每天推出一款新礼物,大多数都是限量版,或只是限期供应。用户个人主页会显示每日礼物的广告。随着 Facebook开放平台应用程序的出现,第三方开发的应用程序对1美元购买礼物的模式构成威胁。请注意,Zachary Allia(译者:一个第三方程序开发员)开发的“免费礼物”,与Facebook的官方礼物是不同的。

市场(Marketplace)

2007年5月,Facebook推出Facebook 市场。用户可以免费发布下列分类广告:卖二手货、租房、工作等。供求两方均可发布。所有Facebook用户都可以使用这个功能。目前是免费的。

捅(Pokes)

Facebook 提供一个“捅(Poke)”的用户功能,用户可以给别人发送一个“Poke”。Facebook常见问题中这样解释:“Poke是你和朋友互动的一种方式。当我们设计这个功能时,我们觉得提供这么一个什么意思也没有的功能其时挺酷。用户们给Poke不同的解释。我们鼓励你给它你自己的解释。”实际上这个功能的目的只是让用户能引起别的用户的注意。尽管很多用户确实用这个功能来引起别的用户注意,或只说声“嘿“,但有些用户仍把它理解为“性”的意味。这个解释造成了一个很热门的Facebook小组的产生--“Poke”够了,咱们干脆做爱吧。到2007年9月,这个小组共有二十五万用户。有时朋友之间会进行一种被称为“Poke仗”的游戏--两个用户间用“Poke”功能,互相Poke来Poke去。另有一些衍生出来的新功能,如“X 我”,和“超级Poke”,让用户可以把Poke替换成任何动作。

状态(Status)

状态,让用户向他们的朋友和Facebook社区显示他们现在在哪里、做什么。Facebook让用户填入状态的提示是“(某某用户)正在。。。”,用户填入剩下的部分。在用户好友列表的“新近更新”区,显示这些状态。

活动(Events)

Facebook活动的功能帮助用户通知朋友们将发生的活动,帮助用户组织线下的社交活动。

开放平台上的应用(Application)

2007年5月24日,Facebook推出Facebook 开放平台。利用这个框架,第三方软件开发者可以开发与Facebook核心功能集成的应用程序。

最流行的应用程序包括:

顶级朋友:用户可以选择和显示他们最好的朋友

涂鸦板:一个图形效果的“墙”

我喜欢:一个社会化音乐发现和分享服务,包括音乐会信息和有关音乐知识的小游戏

甚至有象棋、拼字游戏之类的游戏出现。而第三方网站如进行Facebook应用数据统计的Adonomics,相关博客如AppRate、Inside Facebook、Face Reviews等等或应运而生或对Facebook应用青眼有加。

2007 年 7月4日,Altura 风投宣布“Altura 1 Facebook投资基金”,成为第一个只投资Facebook相关项目的风险投资。2007年7月10日,Bay Partners宣布成立“应用工厂(AppFactory)”,一个只投资Facebook应用的种子基金。

2007年 8月29日,Facebook改变了他们对应用程序热度的衡量标准,更倾斜于那些有深度价值的应用。因为之前,衡量标准仅以用户数为标准,使得那些高度 “病毒传播”(译者:指极易于在用户间口口相传)但没什么用处的程序排名很高。著名IT博客Valleywag曾批评Facebook 应用是“一大堆垃圾”。

截止2007年9月26日,共有超过4500个Facebook应用出现。

Facebook标识语言(Facebook Markup Language)

Facebook 标识语言是HTML的子集。Facebook应用的开发者可以用这种语言定制他们的应用程序的外观。

Facebook视频

与 Facebook开放平台同时推出的,还有一个Facebook自己开发的应用程序--视频分享。用户可以上传视频、通过“Facebook移动”上传手机视频,以及用摄像头录像。同时用户可以给视频中的朋友加“标签”。这一功能被认为会与MySpace的相关功能竞争。但Facebook的视频只能在 Facebook网络内观看。然而,一段发表在Userscripts.org上的Greasemonkey代码让用户可以下载Facebook视频或将之转贴在其他网站。

Facebook的域模型

下图用UML类图的形式,显示了Facebook系统所管理的信息。它提炼出了Facebook数据库中的实体、关系、字段。如,图中显示了有关工作、学校、信用卡、显示用户名等的字段。(黄色方框代表类)

技术构架

Facebook使用LAMP(Linux、 Apache、 MySQL、 PHP)作为技术构架。Facebook的一个技术构架工程师Steven Grimm在博客中写到:几乎我们所有的服务器都运行开源软件。我们的Web服务器是Linux,Apache和PHP。我们数据库是MySQL。我们使用memchached来保证网站的快速反应。一些后台应用Python、Perl和Java,以及一些gcc和Boost。程序员用Subversion和git来进行代码管理。还有很多--象很多网站一样,从头到脚都是开源软件。

Google架构

Google是可伸缩性控制方面的王者。

Google一直的目标就是构建高性能高伸缩性的基础组织来支持它们的产品。

平台

l Linux

l 开发语言:Python,Java,C++
状态

l 在2006年大约有450,000台廉价服务器

l 在2005年Google索引了80亿Web页面,现在没有人知道数目

l 目前在Google有超过200个GFS集群。一个集群可以有1000或者甚至5000台机器。成千上万的机器从运行着5000000000000000字节存储的GFS集群获取数据,集群总的读写吞吐量可以达到每秒40兆字节

l 目前在Google有6000个MapReduce程序,而且每个月都写成百个新程序

l BigTable伸缩存储几十亿的URL,几百千千兆的卫星图片和几亿用户的参数选择架构

Google将它们的基础架构形象化为三层架构:

l 产品:搜索,广告,email,地图,视频,聊天,博客

l 分布式系统基础组织:GFS,MapReduce和BigTable

l 计算平台:一群不同的数据中心里的机器

l 确保公司里的人们的部署开销很小

l 在避免丢失日志数据的硬件上花费较多的钱,其他类型的数据则花费较少
可信赖的存储机制GFS(Google File System)

l 可信赖的伸缩性存储是任何程序的核心需求。GFS就是Google的核心存储平台。

l Google File System ——大型分布式结构化日志文件系统,Google在里面存储了大量的数据。

l 为什么构建GFS而不是利用已有的东西?因为可以自己控制一切,况且这个平台与别的不一样,

Google需要:

n 跨数据中心的高可靠性

n 成千上万的网络节点的伸缩性

n 大读写带宽的需求

n 支持大块的数据,可能为上千兆字节

n 高效的跨节点操作分发以减少瓶颈

l Master和Chunk服务器:

– Master服务器在不同的数据文件里保持元数据。数据以64MB为单位存储在文件系统中。客户端与Master服务器的交流则可以在文件上进行元数据操作并找到包含用户需要数据的那些Chunk服务器。

– Chunk服务器在硬盘上存储实际数据。每个Chunk服务器跨越3个不同的Chunk服务器备份以创建冗余来避免服务器崩溃。一旦经Master服务器指明,客户端程序就会直接从Chunk服务器读取文件。

l 一个上线的新程序可以使用已有的GFS集群或者可以制作自己的GFS集群。

l 关键点在于有足够的基础组织可以让人们对自己的程序有所选择,GFS可以调整来适应个别程序的需求。

使用MapReduce来处理数据

l 你现在已经有了一个很好的存储系统,那么该怎样处理如此多的数据呢?比如大量TB级的数据存储在1000台机器上。数据库不能伸缩或者伸缩到这种级别花费极大,这就是MapReduce出现的原因。

l MapReduce是一个处理和生成大量数据集的编程模型和相关实现。用户指定一个map方法来处理一个键/值来生成一个中间的键/值,还有一个 reduce方法以合并所有关联到同样的中间键的中间值。

许多真实世界的任务都可以使用这种模型来表现。以这种风格来写的程序会自动的在一个拥有大量机器的集群里并行运行。运行时系统处理输入数据的划分、程序在机器集之间执行的调度、机器失败处理和必需的内部机器交流等细节。这就允许程序员没有多少并行和分布式系统的经验就可以很容易使用一个大型分布式系统资源。

l 为什么使用MapReduce?

n 跨越大量机器分割任务的好方式。

n 处理机器失败。

n 可以与不同类型的程序工作,例如搜索和广告。几乎任何程序都有map和reduce类型的操作。可以预先计算有用的数据、查询字数统计、对TB的数据排序等等。

l MapReduce系统有三种不同类型的服务器:

n Master服务器分配用户任务到Map和Reduce服务器。它也跟踪任务的状态。

n Map服务器接收用户输入并在其基础上处理map操作。结果写入中间文件。

n Reduce服务器接收Map服务器产生的中间文件并在其基础上处理reduce操作。

l 例如,你想统计在所有Web页面里的字数。你应该将存储在GFS里的所有页面抛入MapReduce。所有的调整、工作调度、失败处理和数据传输将在成千上万台机器上同时进行并且自动完成。

n 步骤类似于:GFS -> Map -> Shuffle -> Reduction -> Store Results back into GFS。

n 在MapReduce里一个map操作将一些数据映射到另一个中,产生一个键值对,在我们的例子里就是字和字数。

n Shuffling操作聚集键类型。

n Reduction操作计算所有键值对的综合并产生最终的结果。

l Google索引操作管道有大约20个不同的map和reduction。

l 程序可以非常小,如20到50行代码。

l 一个问题可能是掉队者,就是是一个比其他程序慢的计算,阻塞了其他程序。掉队者可能因为缓慢的IO或者临时的CPU不能使用而发生。解决方案是运行多个同样的计算并且当一个完成后杀死所有其他的。

l 数据在Map和Reduce服务器之间传输时被压缩了。这可以节省带宽和I/O。

在BigTable里存储结构化数据

l BigTable是一个大伸缩性、容错的、自管理系统,包含千千兆的内存1000000000000000的存储。它可以每秒钟处理百万数量级的读写操作。

l BigTable是一个构建于GFS之上的分布式Hash机制,但不是关系型数据库,不支持join或者SQL类型查询。

l 提供查询机制通过键访问结构化数据。GFS存储存储不透明的数据,而许多程序需求有结构化数据。

l 商业数据库不能达到这种级别的伸缩性,并且不能在成千上万台机器上工作。

l 通过控制自己的低级存储系统,Google得到更多的控制权来改进它们的系统。例如,如果想让跨数据中心的操作更简单这个特性,就可以内建它。

l 可以自由的增删系统运行时机器,而整个系统可以保持正常工作。

l 每个数据条目存储在一个格子里,可以通过一个行key和列key或者时间戳来访问。

l 每一行存储在一个或多个tablet中。一个tablet是一个64KB块的数据序列并且格式为SSTable。

l BigTable有三种类型的服务器:

n Master服务器分配tablet服务器,它跟踪tablet在哪里并且如果需要则重新分配任务

n Tablet服务器为tablet处理读写请求。当tablet超过大小限制(通常是100MB-200MB)时它们拆开tablet。当一个Tablet服务器失败时,则100个Tablet服务器各自挑选一个新的tablet然后系统恢复。

n Lock服务器形成一个分布式锁服务。像打开一个tablet来写、Master调整和访问控制检查等都需要互斥。

l 一个locality组可以将物理上将相关的数据存储在一起以便得到更好的locality选择。

l tablet尽可能的缓存在RAM里。

硬件

l 当你有很多机器时,你怎样组织它们来达到成本的有效利用,并发挥最大效力?

l 使用非常廉价的硬件。

l 使用不可靠的(failure-prone)架构方式,而不是在高度可靠的组件上搭建基础架构,你可以获得1000倍计算能力的提升,而成本却降低了33倍。你必须在不可靠性之上来构建可靠性,以使得这个策略可以起作用。

l Linux系统,采取内部机架放置的设计方式,使用PC主板,低端存储。

l 基于性能来评估能源消耗不是好的方式,会遇到严重的电力和制冷方面的问题。

l 混合使用服务器,并使用他们自己的数据中心。

其他

l 迅速更改而不是等待QA。

l 库是构建程序的卓越方式。

l 一些程序作为服务提供。

l 通过一个基础组织处理程序的版本,这样可以自由发布而不用害怕会破坏什么东西。

Google将来的方向

l 支持地理位置分布的集群。

l 为所有数据创建一个单独的全局名字空间,将当前的数据从集群分离。

l 更多和更好的自动化数据迁移和计算。

l 解决使用网络划分做广阔区域的备份时的一致性问题(例如保持服务,即使有一个集群离线维护或存在一些损耗问题)。

经验教训

l 基础组织具有竞争性的优势,特别是对Google而言。Google可以很快很廉价的推出新服务,并且具有其他人很难达到伸缩性。许多公司采取完全不同的方式。他们认为基础组织开销太大。Google认为自己是一个系统工程公司,这是一个新的看待软件构建的方式。

l 跨越多个数据中心仍然是一个未解决的问题。大部分网站都是一个或者最多两个数据中心。我们不得不承认怎样在一些数据中心之间完整的分布网站是很需要技巧的。

l 如果你自己没有时间从零开始重新构建所有这些基础组织,你可以看看Hadoop。Hadoop是这里很多主意的一个开源实现。

l 平台的一个优点是初级开发人员可以在平台的基础上快速并且放心的创建健全的程序。如果每个项目都需要发明同样的分布式基础组织的轮子,那么你将陷入困境。因为知道怎样完成这项工作的人相对较少。

l 协同工作不一直是掷骰子。通过让系统中的所有部分一起工作,则一个部分的改进将帮助所有的部分。改进文件系统,则每个人从中受益并且是透明的。如果每个项目使用不同的文件系统,则在整个堆栈中享受不到持续增加的改进。

l 构建自管理系统让你没必要让系统关机。这允许你更容易在服务器之间平衡资源,动态添加更大的容量,让机器离线和优雅的处理升级。

l 创建可进化的基础组织,并行的执行消耗时间的操作并采取较好的方案。

l 不要忽略大学等研究教学机构。那里有许多没有转变为产品的好主意。绝大部分Google所实现的领先技术,其实并不是多么宏大且超前的设计。

l 考虑压缩——当你有许多CPU而IO有限时,压缩是一个好的选择。

Amazon的体系结构

Amazon从一个很小的网上书店发展成为现今世界上最大的网上书店中。他们开辟了让顾客来评估,审查和推荐商品的新方式。
平台

l Linux

l Oracle

l C++

l Perl

l Mason

l Java

l Jboss

l Servlets
状态

l 超过5500万活动顾客帐号

l 世界范围内超过100万活动零售合作商

l 构建一个页面所需访问的服务介于100至150个之间
体系结构

l 我们说的可伸缩性到底意味着什么?对于一个服务来说,当我们增加为其分配的系统资源之后,它的性能增长能够与投入的资源按比例提升,我们就说这个服务具有可伸缩性。通常意义上的性能提升,意味着能够提供更多的服务单元,也可以为更大的工作单元提供服务,比如增长的数据集等。

l Amazon的架构经历了巨大的变化,从一开始时的两层架构,转向了分布式的、去中心化的服务平台,提供许多种不同的应用。

l 最开始只有一个应用来和后端交互,是用C++来完成的。

l 架构会随着时间而演进。多年来,Amazon将增容的主要精力放在后端的数据库上,试图让其容纳更多的商品数据,更多的客户数据,更多的订单数据,并让其支持多个国际站点。到2001年,前端应用很明显不能再做任何增容方面的努力了。数据库被分为很多个小部分,围绕每个部分会创建一个服务接口,并且该接口是访问数据的唯一途径。

l 数据库逐渐演变成共享资源,这样就很难再在全部业务的基础之上进行增容操作了。前端与后端处理的演进受到很大限制,因为他们被太多不同的团队和流程所共享了。

l 他们的架构是松散耦合的的,并且围绕着服务进行构建。面向服务的架构提供给他们的隔离特性,让他们能够快速、独立地完成许多软件组件的开发。

l 逐渐地,Amazon拥有了数百个服务,并有若干应用服务器,从服务中聚合信息。生成Amazon.com站点页面的应用就位于这样的一台应用服务器之上。提供web服务接口、顾客服务应用以及卖家接口的应用也都是类似的情况。

l 许多第三方的技术难以适用Amazon这种网站的规模,特别是通讯基础架构技术。它们在一定范围内工作的很好,但是如果范围再扩大的话,它们就不适用了。因此,Amazon只好自己开发相应的基础技术。

l 不在一种技术上”吊死”。Amazon在有的地方使用jboss/java,不过只是使用servlets,并没有完全使用j2ee中所涉及到的技术。

l C++开发的程序被用来处理请求。Perl/Mason开发的程序用来生成页面中的内容。

l Amazon不喜欢采用中间件技术,因为它看起来更像一种框架而不是一个工具。如果采用了某种中间件,那么就会被那种中间件所采用的软件模式所困扰。你也就只能选用他们的软件。如果你想采用不同的软件几乎是不可能的。你被困住了!经常发生的情况就是消息中间件,数据持久层中间件,Ajax等等。它们都太复杂了。如果中间件能够以更小的组件的方式提供,更像一个工具而不是框架,或许对我们的吸引力会更大一些。

l SOAP 相关的web解决方案看起来想再次解决所有分布式系统的问题。

l Amazon提供SOAP和REST这两种Web 服务。大概有30%的用户采用SOAP这种Web Services。他们看起来似乎是Java和.NET的用户,而且使用WSDL来生成远程对象接口。大概有70%的用户使用REST。他们看起来似乎是 PHP和PERL的用户。

l 无论采用SOAP还是REST,开发人员都可以得到访问Amazon的对象接口。开发人员想要的是把工作完成,而不需要关心网线上传输的是什么东西。

l Amazon想要围绕他们的服务构建一个开放的社区。他们之所以选择Web Services是因为它的简单。事实上它是一个面向服务的体系架构。简单来说,你只有通过接口才能访问到需要的数据,这些接口是用WSDL描述的,不过它们采用自己的封装和传输机制。

l 架构开发团队都是小规模团队,而且都是围绕不同的服务进行组织。

n 在Amazon服务是独立的功能交付单元。这也是Amazon如何组织他的内部团队的。

n 如果你有一个新的业务建议,或者想解决一个问题,你就可以组织一个团队。由于沟通上的成本,每个团队都限制到8~10个人。他们被称为two pizza teams。因为用两个比萨饼,就可以让团队成员每个人都吃饱了。

n 团队都是小规模的。他们被授权可以采取他们所中意的任何方式来解决一个问题或者增强一个服务。

n 例如,他们创建了这样一个团队,其功能是在一本书中查找特有的文字和短语。这个团队为那个功能创建了一个独立的服务接口,而且有权做任何他们认为需要做的事情。

l 部署

n 他们创建了一个特殊的基础设施,来完成对依赖性的管理和对完成服务的部署。

n 目标是让所有正确的服务可以在一个主机中部署。所有的应用代码、监控机制、许可证机制等都应该在一个“主机”中。

n 每个人都有一个自己的系统来解决这些问题。

n 部署进程的输出是一个虚拟机,你可以用EC2来运行他们。

l 为了验证新服务的效果,从客户的角度去看待服务,这样做是值得的。

n 从客户的角度去看待服务,聚焦于你想交付给用户的价值。

n 强迫开发人员将关注点放在交付给客户的价值上,而不是先考虑如何构建技术再考虑如何使用技术。

n 从用户将要看到的简要特性开始,再从客户考虑的角度检查你构建的服务是否有价值。

n 以最小化的设计来结束设计过程。如果想要构建一个很大的分布式系统,简单性是关键。

l 对于大型可伸缩系统来说状态管理是核心问题

n 内部而言,他们可以提供无限存储空间。

n 并不是所有的操作是有状态的。结账的步骤是有状态的。

n 通过分析最近点击过的页面的SessionID,这种服务可以为用户提供推荐商品建议。

n 他们追踪、保存着所有的数据,所以保持状态不是一个问题。有一些分离的状态需要为一个session来保持。提供的服务们会一直保留信息,所以你只要使用这些服务就可以了。

l Eric Brewers’ CAP理论——或称为系统的三个属性

n 系统的三个属性:一致性,可用性,网络分区容忍度。

n 对于任何一个共享数据的系统都至少具备这三个属性中的两个。

n 网络分区容忍度:把节点分割成一些小的分组,它们可以看到其他的分组但是无法看到其他全部节点。

n 一致性:写入一个值然后再读出来,你得到的返回值应该和写入的是同一个值。在一个分区系统中有些情况并非如此。

n 可用性:并非总是可读或者可写。系统可能会告诉你无法写入数据因为需要保持数据的一致性。

n 为了可伸缩性,你必须对系统进行分区,因此针对特定的系统,你要在高一致性或者高可用性之间做出选择。你必须找到可用性和一致性的恰当重叠部分。

n 基于服务的需要来选择特定的实现方法。

n 对于结账的过程,你总是想让更多的物品放入顾客的购物车,因为这样可以产生收入。在这种情况下你需要选择高可用性。错误对顾客是隐藏的,过后才会被拿出来分析。

n 当一个顾客提交订单过来时,我们要将关注点更多的放在保持高一致性上。因为几个不同的服务——信用卡处服务、配送服务、报表功能等——在同时访问那些数据。
汲取的教训

l 为了构建真正的可伸缩的系统,你必须改变你的想法或者心态。混沌方法在概率意义上可能工作的很好。在传统的系统中我们展示的是一个完美的世界,没有什么东西会出现问题、停止运转,之后我们在这个完美的世界上构造复杂的算法。实际上,事情总是会出问题的,这就是你必须要接受的事实。例如,试着多想想如何快速完成服务器重启和如何快速恢复数据。合适的分布数据和服务,你可能向100%无故障又迈进了一步。创建可自愈的(self-healing)、自组织的(self-organizing)系统架构。

l 创建一个没有分享的基础架构。对于开发和部署来说,基础架构也是共享资源,就像在逻辑层和数据层共享的资源一样,你也会遭遇到出问题的时候。可能会导致锁机制和屏蔽机制,并产生死锁。一个面向服务的架构,允许采取并行和分离的开发流程,这样可以使得功能特性的开发也具有“可伸缩性”,与系统的增长相匹配

l 将系统及其API同时开放,这样你会围绕着你的应用创建了一个生态系统。

l 管理巨大的分布式系统的唯一方法,就是让所有的事情尽可能的简单。保持事情简单的办法就是保证设计的时候没有隐藏的需求和隐藏的依赖关系。采用尽可能少的技术来解决你解决的问题。人为的创造一些不需要的复杂系统层次架构对公司并没有益处。

l 围绕服务进行组织可以提供敏捷性。你可以并行的做事情,因为输出结果是一个服务。这使得缩短了产品和服务投放到市场去的时间。需要创建一个基础架构来保证服务可以被很快的构建起来。

l 任何事情,在有真正的实现之前,就来了一堆炒作消息,这其中肯定存在着问题。

l 在内部使用服务品质协议(Service Level Agreement,简称SLA)来管理服务。

l 任何人都可以很快的为他们的产品添加Web Services。以服务的形式来实现你的一部分产品,并开始使用这些服务。

l 由于性能,可靠性和成本控制的原因,可能需要自己来构建基础设施架构。自己构建这些基础架构即便Amazon关门了也不必说是某某公司的错误导致的。自己构建的系统可能没有其他的易用,不过相对使用第三方的东西来说,你可以更快地对自己构建的基础架构进行修补、调试和部署。

l 采用“‘方法’和‘目的’”这样的思辨方式,来区分好与坏。我曾参加过几次前Amazon员工做的演讲,从中发现,这是Amazon和其他公司很不一样的独特而有趣之处。其深层道理是,通过将选择的权利交给真正的顾客,来看哪种做法最合适,并基于这些测试来发现顾客的真正需要。Avinash Kaushik把这个叫做避免HiPPO(the highest paid people in the room,屋子里拿薪水最高的人)的影响。通过A/B测试和Web Analytics等技术手段可以达成目的。如果你对应该做什么有疑问,先开发一些功能,让人们使用这些功能,再看哪一种变通使用方式能够带给你想要的结果。

l 创建一个节俭的环境。例如,Amazon就把门当桌子来用。

l 了解你需要什么。Amazon早期有一个很糟糕的经历,就是没有达成预期目标的推荐系统: “这不是我们所需要的图书推荐系统。Amazon需要的是一个可以基于少量分散的数据,例如一些顾客的评分和购买记录,就可以很好的工作的图书推荐系统。而且它的反应速度要足够快。这个系统也需要适应大量的数据和大量的图书类别。而且它还可以帮助读者发现一些他们真正需要却自己无法发现的图书需求。”

l 人性化的项目——人们跟随这个项目是因为他们对其感兴趣——可以激发更多的价值和创造力。不要低估因为兴趣而激发的力量。

l 在创建产品的过程中,让每个人都参与进来。在圣诞大采购来临之时,去仓库打包图书吧,这样才是团队精神。

l 创建一个可以用来测试的站点,测试通过之后才可以真正的向大众推出。

l 对于Web服务器使用的只读数据来说,一个健壮的、集群式的、冗余的、分布式文件系统是完美的。

l 如果更新没有成功的话,要有可以回滚到以前正常的状态的运作方式。必要的话开发一个工具。

l 转向更深入的基于服务的架构

l 面试的时候需要关注参加面试者的三个要点:热情,创造力和熟练程度。在Amazon,成功的最大特征就是对工作的热情。

l 要雇佣这样的员工,他们有着惊人的调试技术和系统知识,最重要的是,他们可以在高度压力的状况下,应对非常棘手的问题。

l 创新只能来自于底层。最了解问题的人才是最有可能解决问题的人。任何一个依赖于创新的组织必须可以容纳一定程度的混沌。忠诚和服从不是你的工具。

l 创新精神必须无处不在。

l 任何人都应该有机会去尝试,去学习,去实践。职位的变迁,服从,传统的习惯都不应该有多大的权利。创新的蓬勃发展,必须要有一套行之有效的考核办法。

l 拥抱创新。在整个公司员工的面前,Jeff Bezos会亲自颁发’Just do it’奖,一双旧的耐克鞋,给那些具有创新精神员工。

l 不要基于绩效给付薪酬。给予好的福利和高的薪酬,但是要让大部分人都能享受到。通过其他的方式来表达出对一些表现非常优异的员工的认可。’按劳分配’听起来不错,但是在一个大公司内是不可能做到公平的。采用一些非货币的奖励,例如一双旧的耐克鞋其实也是很好的。那也是一种用来表达感谢的方式,说明有人在关心他们。

l 迅速扩张。像Barnes& Nobel这样的大型对手紧跟在你的后面。Amazon曾经不是互联网上最大的书店,不是第二名,甚至也不是第三名。但是他们的远景规划和执行方式最终让他们笑到了最后。

l 在数据中心,员工花在解决基础设施问题上面的时间只有30%是和利润创造相关的。其他的70%的时间则是花在”繁重”的硬件采购、软件管理、负载均衡、维护、应对增容挑战等其他事情上。

l 严禁客户直接访问数据。这意味着你可以让你的服务具有可伸缩性,并在不影响客户的前提下,具有更好的可靠性。这有些类似于Google的能力,他们能够通过对服务器栈的独立、分布的改进,来提升所有的应用。

l 创建统一的服务访问机制。这使得服务易于集成,还可以完成请求路由去中心化、分布请求追踪、以及其他一些高级的基础架构技术。

l 让世界上任何开发人员都能够通过Web服务接口,免费访问Amazon.com。这也是成功的一个重要因素。因为它引发的诸多创新,仅靠Amazon自己的队伍是无法想象出来或者无法实现的。

l 开发人员自己知道哪些工具用起来最顺手,什么样的工具最适合目前的工作。

l 不要在工程师身上强加过多的限制。为某些功能的完成提供一些激励措施,比如与监控系统的集成,或者与其他基础架构工具的集成等功能。但是对于其他的功能,要保证团队的独立性。

l 开发人员与艺术家类似,如果有足够的自由,他们就可以把工作做到最好,但是他们也需要好的工具。提供尽量多的支持工具,围绕着服务的开发,提供环境的支持,使得环境不会成为开发工作的阻碍。

l 谁构建,谁运行。这让开发人员与他们所开发的软件的日常运营工作相联系。也带给他们与顾客之间的日常联系。这种顾客反馈循环对于提升服务质量来说是至关重要的。

l 每隔两年,开发人员就应该与客户服务部门在一起待一段时间。在那里,他们可以听到真实的客服电话,回答客服电子邮件,并深刻领会他们作为技术人员所开发的东西造成的影响。

l 让大家聆听“来自顾客的声音”,内容是一个顾客讲述自己使用网站所产生的用户体验的真实故事。这可以让管理层和工程师们体会到,我们是在为实实在在的人们开发这些技术。通过客服统计数据,我们可以提早发现做错了哪些事情,或是发现哪些是客户的真实痛点。

l 就像Google一样,Amazon的基础架构是他们的巨大核心竞争力。通过一些相对简单的底层服务,他们可以构建出非常复杂的应用。他们可以彼此独立地完成各个服务的增容,维护非并行系统的可用性,并在不需要修改大量系统配置的情况下,快速发布新的服务。

eBay的架构

有谁不想知道eBay是如何开展业务的呢?成为世界上最大的高负荷量的网站之一,这个过程可不容易。创建这样一个庞然大物,需要真正的工程学:在网站的稳定性、运转速度、性能和成本之间达到一个平衡。

你可能无法模仿eBay增容系统的方法,但是其中的问题和可能的解决方案是值得我们学习借鉴的。

平台

Ÿ Java

Ÿ Oracle

Ÿ WebSphere

Ÿ Horizontal Scaling

Ÿ Sharding

Ÿ Mix of Windows and Unix

统计数据

Ÿ 每天一般处理260亿个SQL请求,对1亿件供出售的商品进行跟踪记录

Ÿ 2.12亿名注册用户,10亿张照片

Ÿ 每天10亿次页面访问量,产生1.05亿张列表,2PB的数据。每月30亿应用程序接口呼叫。1999年6月到2006年第三季度间,页面浏览量、邮件的发送量、带宽增长了35倍。

Ÿ 99.94%的可用性,通过“每个人都可以使用网站的所有部分”与“在某个地方有些用户无法使用网站的至少一个部分”对比计算得出。

Ÿ 数据库虚拟化,涵盖分布在100多个服务器集群中的600种产品实例。

Ÿ 15,000个J2EE应用服务器。大概100组的功能(又叫做apps)。“池”的概念:处理所有销售业务的机器。[DSJ1]

架构

Ÿ 一切设计都依照“如果负荷增长十几倍会怎么样”来考虑。采取平行性增容而非垂直性增容,即拥有很多平行的盒子。

Ÿ 架构被严格分成:数据层、应用层、搜索、运行

Ÿ 表示层使用MSXML框架(即使在Java中)

Ÿ Oracle数据库,Websphere Java(1.3.1版本)

Ÿ 依照主访问路径、以及对一个主键的模数为界限,划分数据库

Ÿ 每个数据库至少有三个在线数据库,分布在8个数据中心。

Ÿ 一些数据库备份在15分钟、4个小时之后运行

Ÿ 数据库依照功能分割为70余项,包括:用户、项目账户、反馈、交易等。

Ÿ 不使用存储过程,有一些非常简单的触发机制。

Ÿ 密集使用CPU的任务从数据库层移到应用层。因为应用服务器便宜而数据库则是制约瓶颈,所以参照完整性、连接和分类在应用层完成。

Ÿ 没有客户端事务处理和分布式事务处理。

Ÿ J2EE:使用servlets、JDBC、连接池(具有重新写入功能),其它很少使用。

Ÿ 应用层中没有状态信息。状态信息存在于cookie或者scratch数据库中。

Ÿ 应用服务器之间没有对话——采用严格的架构分层。

Ÿ 网站上的一般商品在卖出之前其搜索数据(比如价格)改变5次,因此实时的搜索结果非常重要。

Ÿ Voyager——eBay建立的实时反馈架构。使用基本数据库提供的的可靠的多点映射机制

(multicast),来完成节点搜索、内存中的搜索索引、水平分割、N切片、在M个实例中平衡负载、存储请求等功能。
经验总结:

Ÿ 减容,而不是扩容

——在每一层上平行增容

——功能分解

Ÿ 推荐异步整合

——最小化可用性耦合

——增加增容的选择

Ÿ 虚拟组件

——降低物理依存

——提高配置弹性

Ÿ 应对故障的设计

——自动的故障检测和通知

——在商务特性中采用“失效保护模式”

Ÿ 因为数据库是制约瓶颈,所以将任务从数据库移到应用层。Ebay在这方面做的非常极端。我们看到其它的架构使用缓存和文件系统来解决数据库的瓶颈问题,而Ebay甚至用应用层处理很多传统的数据库操作(如表连接)。

Ÿ 按自己的意愿使用和舍弃,不必采用全套框架,只使用对你有用的。eBay没有使用完整的J2EE stack,只是采用servlets、JDBC、连接池等。

Ÿ 不要害怕构建满足你的需求并按需求发展的解决方案。每一个现成的解决方案都不可能完全让你高枕无忧,你必须自己走完剩下的路。

Ÿ 随着业务的成长,运行控制成为增容的越来越大的一部分。如果运行一个即时使用的系统,你必须考虑如何升级、配置和监视数以千计的机器。

Ÿ 架构进化——任何一个成长中的网站面临的主要挑战。在保持现有网站运行的同时,需要有改变、改善和开发新系统的能力。

Ÿ 一开始就过于担心可增容性是错误的。因为分析和担心可能永远也不会发生的流量而陷入恐慌是不必要的。

Ÿ 完全不考虑可增容性是不对的。事情永远不会做完,系统总是在进化和改变,你需要建立一个有能力应付架构进化的组织。并且一开始就把这些期望和能力融入你的业务中去,不要让人和组织成为你网站瘫痪的原因。不要认为系统一开始就应该是完美的,一个好的系统是在解决真正的问题和担忧中成长起来的,期待改变,适应改变才是正确的态度。

myspace架构及大型网站架构经验

着中国大型IT企业信息化速度的加快,大部分应用的数据量和访问量都急剧增加,大型企业网站正面临性能和高数据访问量的压力,而且对存储、安全以及信息检索等等方面都提出了更高的要求……
本文中,我想通过几个国外大型IT企业及网站的成功案例,从Web技术人员角度探讨如何积极地应对国内大型网站即将面临的扩展(主要是技术方面,而较少涉及管理及营销等方面)矛盾。
一、 国外大型IT网站的成功之道 (一) MySpace      今天,MySpace已经成为全球众口皆碑的社区网站之王。尽管一流和营销和管理经验自然是每个IT企业取得成功的首要因素,但是本节中我们却抛弃这一点,而主要着眼于探讨在数次面临系统扩张的紧急关头MySpace是如何从技术方面采取应对策略的。 第一代架构—添置更多的Web服务器      MySpace最初的系统很小,只有两台Web服务器(分担处理用户请求的工作量)和一个数据库服务器(所有数据都存储在这一个地方)。那时使用的是Dell双CPU、4G内存的系统。在早期阶段,MySpace基本是通过添置更多Web服务器来对付用户暴增问题的。但到在2004年早期,在MySpace用户数增长到五十万后,其数据库服务器已经开始疲于奔命了。
第二代架构—增加数据库服务器      与增加Web服务器不同,增加数据库并没那么简单。如果一个站点由多个数据库支持,设计者必须考虑的是,如何在保证数据一致性的前提下让多个数据库分担压力。
MySpace运行在三个SQL Server数据库服务器上—一个为主,所有的新数据都向它提交,然后由它复制到其它两个;另两个数据库服务器全力向用户供给数据,用以在博客和个人资料栏显示。这种方式在一段时间内效果很好——只要增加数据库服务器,加大硬盘,就可以应对用户数和访问量的增加。
这一次的数据库架构按照垂直分割模式设计,不同的数据库服务于站点的不同功能,如登录、用户资料和博客。垂直分割策略利于多个数据库分担访问压力,当用户要求增加新功能时,MySpace只需要投入新的数据库加以支持。在账户到达二百万后,MySpace还从存储设备与数据库服务器直接交互的方式切换到SAN(存储区域网络)—用高带宽、专门设计的网络将大量磁盘存储设备连接在一起,而数据库连接到SAN。这项措施极大提升了系统性能、正常运行时间和可靠性。然而,当用户继续增加到三百万后,垂直分割策略也变得难以维持下去。
第三代架构—转到分布式计算架构      几经折腾,最终,MySpace将目光移到分布式计算架构——它在物理上分布的众多服务器,整体必须逻辑上等同于单台机器。拿数据库来说,就不能再像过去那样将应用拆分,再以不同数据库分别支持,而必须将整个站点看作一个应用。现在,数据库模型里只有一个用户表,支持博客、个人资料和其他核心功能的数据都存储在相同数据库。
既然所有的核心数据逻辑上都组织到一个数据库,那么MySpace必须找到新的办法以分担负荷——显然,运行在普通硬件上的单个数据库服务器是无能为力的。这次,不再按站点功能和应用分割数据库,MySpace开始将它的用户按每百万一组分割,然后将各组的全部数据分别存入独立的SQL Server实例。目前,MySpace的每台数据库服务器实际运行两个SQL Server实例,也就是说每台服务器服务大约二百万用户。据MySpace的技术人员说,以后还可以按照这种模式以更小粒度划分架构,从而优化负荷分担。
第四代架构—求助于微软方案      2005年早期,账户达到九百万,MySpace开始用微软的C#编写ASP.NET程序。在收到一定成效后,MySpace开始大规模迁移到ASP.NET。      账户达到一千万时,MySpace再次遭遇存储瓶颈问题。SAN的引入解决了早期一些性能问题,但站点目前的要求已经开始周期性超越SAN的I/O容量——即它从磁盘存储系统读写数据的极限速度。
第五代架构—增加数据缓存层并转到支持64位处理器的SQL Server 2005      2005年春天,MySpace账户达到一千七百万,MySpace又启用了新的策略以减轻存储系统压力,即增加数据缓存层——位于Web服务器和数据库服务器之间,其唯一职能是在内存中建立被频繁请求数据对象的副本,如此一来,不访问数据库也可以向Web应用供给数据。
2005年中期,服务账户数达到两千六百万时,MySpace因为我们对内存的渴求而切换到了还处于beta测试的支持64位处理器的SQL Server 2005。升级到SQL Server 2005和64位Windows Server 2003后,MySpace每台服务器配备了32G内存,后于2006年再次将配置标准提升到64G。
事实上,MySpace的Web服务器和数据库仍然经常发生超负荷,其用户频繁遭遇“意外错误”和“站点离线维护”等告示,他们不得不在论坛抱怨不停……
MySpace正是在这样不断重构站点软件、数据库和存储系统中,才一步步走到今天。事实上,MySpace已经成功解决了很多系统扩展性问题,其中存在相当的经验值得我们借鉴。MySpace系统架构到目前为止保持了相对稳定,但其技术人员仍然在为SQL Server支持的同时连接数等方面继续攻坚,尽可能把事情做到最好。
(二) Amazon      亚马逊书店无疑是电子商务发展的里程碑。2000年到现在,世界网络业腥风血雨。Amazon曾经成为网络泡沫的头号代表。如今,当这个“最大的泡沫”用几经易改的数字把自己变成了坚实的IT巨人。
历览Amazon发展过程,其成功经验在于,它创造性地进行了电子商务中每一环节的探索,包括系统平台的建设,程序编写、网站设立、配送系统等等方面。用Amazon当家人贝索斯的话说就是,“在现实世界的商店最有力的武器就是地段,地段,地段,而对于我们来说最重要的三件事就是技术,技术,技术。”
(三) eBay      eBay是世界闻名的拍卖网站,eBay公司通信部主管凯文•帕斯格拉夫认为,“eBay成功的最重要原因在于公司管理和服务。”      其成功的奥秘可以列举为以下几点:      ①敢为天下先—在网络尚不普及的时代,eBay率先进入网络拍卖领域;      ②依托虚拟商场所产生的特有的“零库存”是eBay公司取得成功的另一个重要原因。该公司的核心业务没有任何库存风险,所有的商品都是由客户提供,它只需要负责提供虚拟的拍卖平台—网络和软件。所以,eBay公司的财务报表上不会出现“库存费用”和“保管费用”等。 ③自eBay公司成立开始,它就一直遵循两条“黄金原则”:建设虚拟社区,给网民以家的感觉;保证网站稳定安全地运行。
二、 国内大型网站开发时的几点建议      从本节开始,我们将结合国内外大型IT网站在技术扩展方面的沉痛教训和成功经验,探讨在如今刚刚开始的Web 2.0时代如何应对国内网站即将面临的数据访问量增加(甚至是急剧膨胀)的问题,并提出一些供参考的策略和建议。
(四) 搭建科学的系统架构      构建大型的商业网站绝对不可能像构建普通的小型网站一样一蹴而就,需要从严格的软件工程管理的角度进行认真规划,有步骤有逻辑地进行开发。对于大型网站来说,所采用的技术涉及面极其广泛,从硬件到软件、编程语言、数据库、Web服务器、防火墙等各个领域都有了很高的要求,已经不是原来简单的html静态网站所能比拟的。以著名的Yahoo!为例,他们的每一个大型网站工程都需要大量相应专业人员的参与。
(五) 页面静态化      可不要小看纯静态化的HTML页面!其实在很多情况下,HTML往往意味着“效率最高、消耗最小”,所以我们尽可能使我们的网站上的页面采用静态页面来实现。但是,对于大量内容并且频繁更新的网站,我们无法全部手动实现,因此可以开发相应的自动化更新工具,例如我们常见的信息发布系统CMS。像我们经常访问的各个门户站点的新闻频道,甚至他们的其他频道,都是通过信息发布系统来管理和实现的。信息发布系统可以实现最简单的信息录入自动生成静态页面,还能具备频道管理、权限管理、自动抓取等功能,对于一个大型网站来说,拥有一套高效、可管理的CMS是必不可少的。
(六) 存储问题      存储也是一个大问题,一种是小文件的存储,比如图片这类;另一种是大文件的存储,比如搜索引擎的索引。 大家知道,对于Web服务器来说,不管是Apache、IIS还是其他容器,图片是最消耗资源的,于是我们有必要将图片与页面进行分离,这是基本上大型网站都会采用的策略,他们都有独立的图片服务器,甚至很多台图片服务器。这样的架构可以降低提供页面访问请求的服务器系统压力,并且可以保证系统不会因为图片问题而崩溃,在应用服务器和图片服务器上,可以进行不同的配置优化以保证更高的系统消耗和执行效率。
(七) 数据库技术—集群和库表散列      对于大型网站而言,使用大型的数据库服务器是必须的事情。但是,在面对大量访问的时候,数据库的瓶颈仍然会显现出来,这时一台数据库将很快无法满足应用,于是我们需要借助于数据库集群或者库表散列技术。
在数据库集群方面,很多数据库厂商都有自己的解决方案,Oracle、Sybase、SQL Server等都有很好的方案,常用的MySQL提供的Master/Slave也是类似的方案。因此,你使用了什么样的数据库,就参考相应的解决方案来实施即可。
上面提到的数据库集群由于在架构、成本、扩张性方面都会受到所采用数据库类型的限制,于是我们需要从应用程序的角度来考虑改善系统架构,其中,库表散列是常用并且最有效的解决方案。我们在应用程序中安装业务和应用或者功能模块将数据库进行分离,不同的模块对应不同的数据库或者表,再按照一定的策略对某个页面或者功能进行更小的数据库散列,比如用户表,按照用户ID进行表散列,这样就能够低成本的提升系统的性能并且有很好的扩展性。在这一方面一个现成的例子就是搜狐。它的论坛就是采用了这样的架构,将论坛的用户、设置、帖子等信息进行数据库分离,然后对帖子、用户按照板块和ID进行散列数据库和表,最终可以在配置文件中进行简单的配置便能让系统随时增加一台低成本的数据库进来补充系统性能。
(八) 缓存策略      这绝对不单指低级的缓存技术相关的编程,应从整个架构角度着眼,深入研究Web服务器、数据库服务器的各层级的缓冲策略,最后才是低级的缓冲技术的编程。不同的Web服务器、数据库服务器及Web编程语言都有自己不同的缓冲策略。例如数据库存储方面,SQL Serve 2005中的主动式缓存机制,Oracle数据的cache group技术,Hibernate的缓存包括Session的缓存和SessionFactory的缓存;Web服务器方面,Apache提供了自己的缓存模块,也可以使用外加的Squid模块进行缓存,这两种方式均可以有效的提高Apache的访问响应能力,IIS缓冲器技术;至于web开发语言,所用缓存技术更存在很大不同,例如ASP.NET 2.0中提出了两种缓存应用程序数据和缓存服务页输出的策略,这两种缓存技术相互独立但不相互排斥,PHP有Pear的Cache模块,等等。
(九) 镜像      镜像是大型网站常采用的提高性能和数据安全性的方式,镜像的技术可以解决不同网络接入商和地域带来的用户访问速度差异。在镜像的细节技术方面,这里不阐述太深,有很多专业的现成的解决架构和产品可选。也有廉价的通过软件实现的思路,比如Linux上的rsync等工具。
(十) 负载均衡      负载均衡将是大型网站解决高负荷访问和大量并发请求采用的终极解决办法。 负载均衡技术发展了多年,有很多专业的服务提供商和产品可以选择,基于LAMP解决方案的Lighttped+Squid是相当不错的解决负载均衡和加速系统的有效方式。
(十一) 硬件四层交换      第四层交换使用第三层和第四层信息包的报头信息,根据应用区间识别业务流,将整个区间段的业务流分配到合适的应用服务器进行处理。第四层交换功能就象是虚IP,指向物理服务器。它传输的业务服从的协议多种多样,有HTTP、FTP、NFS、Telnet或其他协议。这些业务在物理服务器基础上,需要复杂的载量平衡算法。在IP世界,业务类型由终端TCP或UDP端口地址来决定,在第四层交换中的应用区间则由源端和终端IP地址、TCP和UDP端口共同决定。
在硬件四层交换产品领域,有一些知名的产品可以选择,比如Alteon、F5等,这些产品很昂贵,但是物有所值,能够提供非常优秀的性能和很灵活的管理能力。Yahoo中国当初接近2000台服务器使用了三四台Alteon就搞定了。
(十二) 软件四层交换      大家知道了硬件四层交换机的原理后,基于OSI模型来实现的软件四层交换也就应运而生,这样的解决方案实现的原理一致,不过性能稍差。但是满足一定量的压力还是游刃有余的。
一个典型的使用负载均衡的策略就是,在软件或者硬件四层交换的基础上搭建squid集群,这种思路在很多大型网站包括搜索引擎上被采用,这样的架构低成本、高性能还有很强的扩张性,随时往架构里面增减节点都非常容易。
(十三) 软件投资问题      据报导,目前国内除了一些上市企业和特别大知名大公司以外,很少有企业在成本中考虑正版软件的购置费用。这种思维极有可能给中国互联网带来噩梦。如果一些公司真正面临软件资金方面的困难,完全可以考虑使用开源世界的LAMP解决方案(Linux+Apache+MySQL+Perl、PHP或者Python Web编程语言);否则,随着我国加入WTO范围的不断扩大,盗版打击必然越来越严。因此,“苟且偷生”必将自食其果。
另外,随着网络带宽日渐提升,WEB 2.0技术必将影响到网络世界的几乎每一个角落。因此,如何积聚技术人员进行技术攻关并进一步加强安全防范也成为一个日益严峻的问题,宜尽早纳入到公司的议事日程。   四、 总结      中国电子商务真正理性发展的一个标志,是大量的传统企业实实在在地开始用互联网来处理商务、做生意,而现在这样的浪潮已经开始。北京发行集团,联合SINA、6688.com等单位共同推出的网上虚拟书店—新新书店就是这样的一个标志。
随着网络带宽日渐提升,随着网络理念和WEB 2.0技术的断深入人心,各种B2B、B2C、C2C等电子商务模式很可能以立体交叉方式整合到各种大型商务网站中来。因此,作为公司的技术人员,作为临危救驾的“白衣骑士”,如何应对海量存储、海量访问问题,海量信息检索的问题,日益严峻的安全问题,等等,已经刻不容缓。

QQ空间技术架构之深刻揭密

QQ空间作为腾讯海量互联网服务产品,经过近七年的发展,实现了从十万级到亿级同时在线的飞跃。在这个过程中,QQ空间团队遇到了哪些技术挑战?其站点前后台架构随着业务规模的变化又进行了怎样的演进与变迁?成长背后有过怎样的心酸和快乐……

4.26日晚间,腾讯大讲堂·深圳首站《QQ空间技术架构之峥嵘岁月》活动在腾讯总部腾讯大厦多功能厅举办,腾讯Web前端研发领域专家、腾讯最早的专职Web开发团队核心成员、Qzone核心架构研发总监徐晓在两小时的演讲中揭开了QQ空间技术架构背后的秘密。

正式分享之前,徐晓介绍了QQ空间目前的海量服务数据规模(图1):

  1. 拥有5.5亿的活跃用户
  2. 过万台的设备
  3. 数千万级别的同时在线
  4. 数十亿级别的全站PV
  5. P级的UGC存储量
  6. 每天千亿级别的服务请求

图1——QQ空间海量服务数据规模

接下来,徐晓把QQ空间成长和发展的历程分成三个阶段:石器时代、冷兵器时代和现代战争时代,分享了QQ空间从开始甚至难以生存,到逐步发展成国内最大的SNS社区产品背后的酸甜苦辣。

石器时代–从十万在线到百万在线

石器时代是QQ空间1.0到3.0稳健上线的过程。

徐晓说:“QQ空间在石器时代遇到的最大难题就是如何生存?如何让这个襁褓中的产品活下来?如何积累第一批宝贵的用户资源?”, 2005年QQ空间首发,最初是采用传统的发放邀请码的方式征集第一批用户。第一款QQ空间是嵌在独立的客户端软件中,看似是个客户端,其实是一个浏览器内核,里面都是HTML页面,以网站的方式存在。 当初的架构非常简单,采用了Apache搭建Web Server,Mysql保存最终数据。用户通过{uin}.qzone.qq.com(uin就是用户的QQ号码)这样的方式访问自己的空间。最开始上线时,仅邀请了电信用户。但上线之后才发现很多北方网通用户也非常希望来体验。但如果让北方网通用户跨网来访问电信的服务,那将是一个非常糟糕的体验。因为当时的跨网之间的带宽是非常有限的。

为了满足网通用户的需求,QQ空间团队在网通搭建了一套与电信一模一样的服务,电信的用户数据只存在电信的服务器上,网通用户数据只存在网通服务器上。看似异地分布,其实两部分数据是互相独立、不能冗余的。在用户注册开通空间时,就确定了他的数据存在于哪个服务器上。

用户访问空间的逻辑抽象来说是这样的(如图2):用户通过浏览器发起请求访问我们的第一个CGI,这个CGI再串行的获取用户数据,比如:装扮数据,日志数据等。等获取到全部数据之后,这个CGI再将所有的数据拼装成一个完整的HTML页面输出给用户。

图2——Qzone2.0典型载入逻辑

但同时,空间第一版的独立客户端也带来了各种问题和烦恼:

第一:非常不利于定位问题。

一旦页面元素填写失败,定位问题将是一件麻烦的事情。因为它不是Web页面,所以只能用其他抓包软件,比如Ethereal(Wireshark的前身)来抓取网络包做分析。但那个时候网络抓包工具的能力还比较弱,没有高亮和HTML语法检测等功能,所以整体环境比较受限。

第二:服务接入层压力大。

由于不仅要接受用户的请求,还要向后访问不同的数据。当后端某一个接口超时严重的情况下,很多用户的请求都会被挂起。这样就会消耗更多的连接资源,对Web服务器CPU的消耗很大。

第三:服务集群没有发挥出应有的服务能力

当时共用30-40台服务器,也只能支持50万左右的用户。无奈之下,团队想了一个没办法的办法:有意限制超过五十万用户,提出了一个排队等待机制,学习海底捞模式,当在线人数达到50w的时候,QQ空间会给用户展示一个Flash小游戏,让用户在等待的时候玩小游戏。

针对当时存在的种种问题,团队做了以下改进来解决:

第一:采用Web RIA。

当时大量使用了Ajax技术来减轻服务器的负载。其中一个极端的例子是:整个空间首页都是采用JS绘制,这样能够将用户访问的CGI足够轻量化。尽量简化了CGI逻辑,让CGI程序运行更加强壮、效率更高。同时,当服务异常时,还可以通过JS脚本绘制一个错误信息给予用户提示。而且,采用JS开发效率更高,调试更方便。 Web RIA化后,降低了服务器CPU消耗的40%,节约了DC的输出带宽约30%(部分JS脚本都可以被浏览器Cache住)。

第二:采用动静分离策略。

静态资源都放在自研的Web服务器qhttpd上,它具备当时ApacheSelect模型的两个数量级以上的接入能力。

第三:采用自研的Web Server:Qzhttp,主要用于动态分离的动态服务的需要。

由于Qzhttp是腾讯自研的、轻量的、更适合业务自己逻辑的Web Server,从而保证了它的高性能,它的接入能力比Apache (非FastCGI模式)提高了3倍。

石器时代做的最大的优化:

当用户申请QQ空间多个服务时,每个服务都有独立的存储和处理逻辑。只有当所有的服务处理完成,才会由QQ空间框架服务器返回给用户。这样对于同时依赖日志、相册、音乐、留言的服务就会产生两大问题:

  1. 短板效应一损俱损;
  2. 具体业务容量无法差异化。

针对这两个问题,做了首页载入性能优化及首页内容静态化系统两方面的优化:

研究用户访问模型。拉取展现与UGC内容的变更比例是7:1。用户之间互访频繁,看他人与看自己的比例是5:1.。通过以上数据,可以看出用户的UGC更新很少,但是用户之间互相访问很频繁。根据用户的这种访问模型,空间团队研发了一套静态化系统(图3)。这套系统会将用户首页的内容全部Cache,然后根据用户的访问,以及用户自己UGC内容的更改,采用一定策略更新静态化系统的Cache数据。 通过增加首页内容静态化系统,首页展现速度从5s提升到3s,用户也不用再玩小游戏进行等待。同时在设备没有扩容的前提下,同时在线用户访问数突破100w。

图3—首页内容静态化系统

通过不断的改进和优化,QQ空间3.0于2006年中稳健上线。

冷兵器时代——功能的磨砺

冷兵器时代是在线人数从百万阵营向千万阵营过渡的过程。这个阶段做的更多的是功能的磨砺,提高可用性的过程。

但与此同时,QQ空间团队又面临了新的问题:

  1. 网通,教育网用户体验很差;
  2. 版本迭代快速,导致外网bug不断;版本发布之后,所有开发必须留守2个小时;
  3. 后端服务质量不稳定,导致服务经常宕机。

之前有谈到,空间的用户数据是分布在电信与网通两套体系中的。但由于公司在网通的服务设备有限,随着用户量的不断增加,很快就达到了网通设备服务的上限。网通不能扩容设备,但用户量还在不断增加。面对这种情况,只好将网通和电信的数据合并为一套。当网通用户访问服务的时候,会通过一个代理将用户的请求转发到内网电信服务上。采用这种方式,提供了一套通用的解决方案,可以解决海外,网通,教育网,铁通等运营商的问题。

但这种跨网访问的静态资源下载量非常大,静态资源请求次数 : CGI请求数接近10:1,所以采用CDN提供静态资源下载,来提高用户访问速度。具体逻辑是:根据用户客户端IP判断用户属于哪一个ISP服务商,通过URL方式将用户的静态资源访问定向到该ISP的服务设备上。

这样,跳出CDN系统的拘束、优化思路,解决了大部分教育网用户问题,同时多级支持的思路成为公共方案。 但同时还是有很多的故障:

  1. 低ARPU、低成本、低价机器、大集群
  2. 版本迭代快每周发布版本
  3. 用户对故障和低效的容忍度非常低 通过调研,我们发现用户对Web的容忍度是很低的(如图4):

图4——用户容忍度曲线

一般页面在1s内打开,用户会感觉体验非常流畅。所以我们通过以下策略来保证服务质量:

  1. 区分关键路径,对关键路径的服务质量我们要求4个9以上,非关键路径的服务失败之后做有损体验;
  2. 采用动态超时时间控制算法,保证整个程序在可控的时间内做出响应;
  3. 多级容错机制,从后端服务到CGI,到前台JS脚本都对错误做了容错处理;
  4. 采用柔性可用策略,失败接口采用默认数据。

为了保证版本的服务质量,空间采用了灰度发布策略。新特性可能按照用户尾号发布,每次新特性只对一小部分人可见。一段时间内的用户反馈后,不断修复和改进问题,再逐步扩大用户群对新特性的可见性,最后新特性才对全量用户可见。同时,也通过控制JS版本号来达到了灰度发布的目的。

通过这些优化,QQ空间成功踏入千万级在线的阵营,QQ空间5.0正式上线。其中主要变化:后端服务进行了重构,前端页面也进行了优化。

现代战争时代–数千万在线向亿级在线

经过反复的改进和优化,QQ空间服务质量大幅提高,但是,新的问题还是随之而来:

不满足于发日志、传照片的用户,想要玩游戏、使用某些web工具。同时,公司其它团队要在QQ空间上开发应用,但QQ空间的应用配置都写死在QQ空间平台逻辑里面。为配合其他团队上线,发版本需要一周,工作不可并行,非常耗时,受到了很大挑战。针对这种情况,我们采取了两大措施:平台和应用架构分离(如图5)、简单配置后上线(如图6)。

图5——平台和应用架构分离

图6——简单配置后上线

如果某天深圳的IDC不可用了怎么办?

为了解决这个问题,空间团队做了全国IDC的异地部署,采用“一点写,多点读”模式的架构模型,将服务部署到深圳、上海、天津和西安。深圳是一个写入点,通过QQ空间自己的一套同步系统同步到全国各个IDC(如图7)。同时QQ空间提供了全方位的立体监控,7*24小时对服务做监控。

图7——IDC分布

如何快速发现和解决用户的问题?

定位用户问题需要花很大的时间成本,这就要求团队做很多的监控工作:服务器流量监控、接口调用监控、前端测速监控、前端调用错误监控。

同时,在千万级到亿级在线的过程中,团队要有全国甚至全球的分布和匹配分布的运营能力;出问题可以快速切割,全方位的立体化监控能力;各个逻辑层持续优化能力。只有持续优化,用户才能感知到性能的增加,用户才会增加。

经过无数次的推敲和不断优化,QQ空间的服务能力已经能够支持千万级别的用户在线请求,并且能够给用户提供7*24小时的不间断服务。向亿级在线阵营冲刺也将指日可待!

总结

百万在线:

当时如何撑住服务,让用户进来,从而积累QQ空间第一批用户,根据用户模型进行优化,让QQ空间架构有更好的接入能力,做到高性能。

千万在线:

通过各层的柔性服务和灰度发布的策略,让服务更加稳定,让用户数量级再上一个新台阶。

亿级在线:

服务要有更灵活、更敏捷的变更手段。同时有更好的监控和可运营的能力。

接下来是半个小时的Q&A环节,同学们踊跃提问,徐晓做出了详细专业的解答。最后,徐晓和大家分享了“腾讯《海量服务之道》系列的优质课程和秉承的原则”:

Qzone是全球第二大SNS社区,仅次于Facebook。徐晓说:“海量服务的价值观和用户对我们的厚爱造就了现在的QQ空间。我们会持续的发展,攻克各种难题,不断前进。”

from:http://www.infoq.com/cn/articles/qzone-architecture