Stack Overflow是我最喜欢的问答网站,没有之一,原因是它能解决我学习程序过程中遇到的大多数问题,而 Quora 和 知乎更多的是拓展我的视野。(不要和我提百度知道,百度知道是小学生用来做暑假作业的!)
目前Stack Overflow每月不重复的访问用户超过1600万;每月网页浏览量(PV)增长了近6倍,达到9500万。已经发展壮大成了 Stack Exchange Network,而这个网络包括Stack Overflow、Server Fault和Super User等,旗下总共拥有43个网站,而且发展势头良好。
Stack Overflow的变化翻天覆地,而不变的是他们开放的心态,所以才有了这篇架构分享的文章。最近,他们写了一系列文章分享他们如何应对这样的快速增长。
Stack Exchange’s Architecture in Bullet Points
Stack Overflow’s New York Data Center
Designing For Scalability of Management and Fault Tolerance
Stack Overflow Search ― Now 81% Less
Stack Overflow Network Configuration
Does StackOverflow use caching and if so, how?
Which tools and technologies build the Stack Exchange Network?
(期待后面有时间把上面提到的文章都翻译一遍)
在过去的一段时间里,Stack Exchange到底发生了哪些明显的变化呢?
更多:更多的用户,更多的PV,更多的数据中心,更多的站点,更多的开发者,更多的操作系统,更多的数据库,更多的服务器…更多…
Linux:Stack Overflow因使用Windows系统而著称,现在他们使用越来越多的Linux服务器,比如HAProxy(负载均衡), Redis(NoSQL数据库),Bacula(数据备份系统),Nagios(远程监控软件),日志,路由器都运行于Linux系统,几乎所有需要并行处理的功能都是由Linux处理。
容错:Stack Overflow目前为两条不同的线路使用了两个不同的交换机,增加了更多的冗余服务器,将一些网站服务运行于第二个数据中心。
NoSQL:Redis作为整个网站的缓存层。这是一个巨大的改变,以前并没有将缓存作为一个独立的层分离出来。Redis是一个运行于Linux的NoSQL数据库。
遗憾的是,一些我关注的问题并没有从中找到答案,比如面对这么多不同的系统,如何解决多租户的问题(Multi-tenancy 是一种软件体系结构,在这种体系结构中软件运行在 software as a service 服务商的服务器上,服务于多个客户组织即 tenant)。但是,从中我们依然可以学到很多。下面是收集的一些数据列表:
统计信息
每月9500万次浏览量
每秒800个HTTP请求
每秒180个DNS请求
每秒55M流量
1600万个用户(Stack Overflow的流量在2010年增长了131%,全球每月不重复访客增至1660万人)。
数据中心
1个机架放在俄勒冈州的Peak Internet(用于放置chat和Data Explorer)
2个机架放在纽约州的Peer 1(用于放置Stack Exchange Network的其余部分)
硬件设备
10台戴尔R610 IIS Web服务器(3台专门用于Stack Overflow):1个英特尔至强处理器E5640,2.66 GHz四核,8线程;16 GB内存;Windows Server 2008 R2
2台戴尔R710数据库服务器:2个英特尔至强处理器X5680,3.33 GHz;64 GB内存;8个硬盘;SQL Server 2008 R2
2台戴尔R610 HAProxy服务器:1个英特尔至强处理器E5640,2.66 GHz;4 GB内存;Ubuntu Server
2台戴尔R610 Redis服务器:2个英特尔至强处理器E5640,2.66 GHz;16 GB内存;CentOS
1台戴尔R610 Linux备份服务器,运行Bacula:1个英特尔至强处理器E5640,2.66 GHz;32 GB内存
1台戴尔R610 Linux管理服务器,用于Nagios和日志:1个英特尔至强处理器E5640,2.66 GHz;32 GB内存
2个戴尔R610 VMWare ESXi域控制器:1个英特尔至强处理器E5640,2.66 GHz;16 GB内存;2只Linux路由器;5台戴尔Power Connect交换机
开发工具
编程语言:C#(ASP.NET)
集成开发环境(IDE):Visual Studio 2010 Team Suite
开发框架:Microsoft ASP.NET Framework 4.0
Web框架:ASP.NET MVC 3
视图引擎:Razor
浏览器框架:jQuery 1.4.2
数据访问层:LINQ to SQL,一些原始SQL
源码控制:Mercurial和Kiln
比较工具:Beyond Compare 3
软件与技术
堆栈技术:BizSpark 的WISC
操作系统:Windows Server 2008 R2 x64,Ubuntu Server,CentOS
数据库:运行于Microsoft Windows Server 2008 Enterprise Edition x64 的SQL Server 2008 R2
WEB服务器:IIS7.0
负载均衡:HAProxy
缓存技术: Redis(分布式缓存)
代码部署:CruiseControl.NET
搜索系统:Lucene.NET
备份系统:Bacula
监控系统:Nagios (使用 n2rrd 和 drraw 插件)
日志分析:Splunk
SQL Server监控:SQL Monitor from Red Gate
DNS解析:Bind
远程控制:Rovio
外部监控:Pingdom
外部组件(一些没有包含在开发工具中的代码)
reCAPTCHA
DotNetOpenId
WMD - Now developed as open source. See github network graph
Prettify
Google Analytics
Cruise Control .NET
HAProxy
Cacti
MarkdownSharp
Flot
Nginx
Kiln
CDN: 没有使用,所有静态内容从sstatic.net来提供,这个快速的、无cookie的域用于将静态内容分发到Stack Exchange系列网站。
开发人员和系统管理员
14名开发人员
2名系统管理员
内容
License: Creative Commons Attribution-Share Alike 2.5 Generic
Standards: OpenSearch, Atom
Host: PEAK Internet
更多可以学习的架构知识
使用HAProxy替代Windows NLB 的原因是:HAProxy成本低廉、易于使用,还是免费的;而且通过Hyper-V,很适合作为网络上的一个512M虚拟机“设备”。它还在服务器的前端工作,所以对服务器来说完全透明;而且作为不同的网络层,更容易排除故障,而不是与你的所有窗口配置混杂在一起。
没有使用CDN,因为与捆绑在现有主机方案中的带宽相比,连亚马逊CDN这样“便宜的”CDN其费用都非常昂贵。按照亚马逊的CDN费率和Stack Overflow的带宽使用量,每月至少要付1000美元。
备份到磁盘上,便于快速恢复;备份到磁道(tape)上,便于历史归档。
SQL Server的全文搜索机制集成度差,问题多,功能弱,所以改用了Lucene。
最感兴趣的是HTTP请求峰值,因为他们需要确保可以处理的过来。
所有站点都运行在Stack Exchange平台上。Stack Overflow、Super User、Server Fault、Meta、WebApps和Meta Web Apps都运行相同的软件。
给StackExchange的用户进行区分是因为拥有不同专业技能的人不适合不同主题的站点。你也许是世界上最出色的大厨,但并不是说你就有能力修复服务器。
尽量把一切都放到缓存中。
所有匿名用户可以访问的页面都使用缓存输出缓存输出给用户。
每个站点有三种不同的缓存:本地缓存、站点缓存和全局缓存。
缓存中的大部分项目在超时(通常是几分钟)后过期,但从来不被明确删除。当宣布某个特定的缓存项目无效时,他们使用Redis messaging消息传递机制,向“一级”缓存发布删除通知。
Joel Spolsky不是微软的忠实粉丝,他并不为Stack Overflow做出技术决策,他认为微软的协议是存在问题。需要你自己去考虑Hacker News commentor。
Stack Overflow为自己的输入/输出系统选择了英特尔X25固态硬盘组成的RAID 10阵列。这个RAID阵列消除了可靠性方面的任何问题;与FusionIO相比,固态硬盘的性能确实很好,而价格又便宜得多。
微软许可证的总标价约为24.2万美元。由于Stack Overflow使用Bizspark,所以没在支付总标价,但他们能付的最多也就这么多。
英特尔网卡取代了博通网卡。这解决了他们之前面临的问题:连接中断、数据包丢失和地址解析协议(ARP)表损坏。
缓存信息
上面提到了Stack Exchange每个站点有三种不同的缓存:本地缓存、站点缓存和全局缓存。线面就来看看每个缓存的作用。
本地缓存:只能通过1对服务器/站点来访问。
为了限制网络延迟时间,Stack Overflow使用了本地“一级”缓存(基本上是HttpRuntime.Cache),缓存服务器上最近设定/读取的值。这样就可以把网络上的缓存查找开销减小至0字节。
缓存里面含有用户会话和等待的视图数更新等内容。
缓存完全驻留在内存中,没有网络或数据库访问。
站点缓存:可以由一个站点(任何服务器上)的任何实例来访问。
大部分缓存的值进入到这里,热点问题ID列表和用户验收率就是两个典例。
缓存驻留在Redis(位于不同的数据库,纯粹为了易于调试)。
Redis的速度很快,缓存查找中速度最慢的部分就是读取字节并写到网络上。
值被发送到Redis之前先进行压缩。Stack Overflow有许多处理器,大部分数据是字符串,所以得到的压缩比很高。
Redis机器上的处理器使用率为0%。
全局缓存:全局缓存被所有站点和服务器共享。
缓存内容包括收件箱、API使用限额和另外几项真正全局的内容。
缓存驻留在Redis中(位于数据库0,同样为了易于调试)。
建议继续学习:
- Facebook 的系统架构 (阅读:4985)
- 一淘网的系统架构 (阅读:2868)
- Digg.com 的系统架构 (阅读:2329)
QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习