Optimize - 网站架构方案全解析

28 views
Skip to first unread message

Henry H

unread,
Sep 15, 2011, 7:04:51 PM9/15/11
to dev...@googlegroups.com

1、HTML静态化其实大家都知道,效率最高、消耗最小的就是纯静态化的html页面,所以我们尽可能使我们的网站上的页面采用静态页面来实现,这个最简单的方法其实也是最有效的方法。但是对于大量内容并且频繁更新的网站,我们无法全部手动去挨个实现,于是出现了我们常见的信息发布系统CMS,像我们常访问的各个门户站点的新闻频道,甚至他们的其他频道,都是通过信息发布系统来管理和实现的,信息发布系统可以实现最简单的信息录入自动生成静态页面,还能具备频道管理、权限管理、自动抓取等功能,对于一个大型网站来说,拥有一套高效、可管理的CMS是必不可少的。除了门户和信息发布类型的网站,对于交互性要求很高的社区类型网站来说,尽可能的静态化也是提高性能的必要手段,将社区内的帖子、文章进行实时的静态化,有更新的时候再重新静态化也是大量使用的策略,像Mop的大杂烩就是使用了这样的策略,网易社区等也是如此。同时,html静态化也是某些缓存策略使用的手段,对于系统中频繁使用数据库查询但是内容更新很小的应用,可以考虑使用html静态化来实现,比如论坛中论坛的公用设置信息,这些信息目前的主流论坛都可以进行后台管理并且存储再数据库中,这些信息其实大量被前台程序调用,但是更新频率很小,可以考虑将这部分内容进行后台更新的时候进行静态化,这样避免了大量的数据库访问请求。

2、图片服务器分离大家知道,对于Web服务器来说,不管是Apache、IIS还是其他容器,图片是最消耗资源的,于是我们有必要将图片与页面进行分离,这是基本上大型网站都会采用的策略,他们都有独立的图片服务器,甚至很多台图片服务器。这样的架构可以降低提供页面访问请求的服务器系统压力,并且可以保证系统不会因为图片问题而崩溃,在应用服务器和图片服务器上,可以进行不同的配置优化,比如apache在配置ContentType的时候可以尽量少支持,尽可能少的LoadModule,保证更高的系统消耗和执行效率。

3、数据库集群和库表散列大型网站都有复杂的应用,这些应用必须使用数据库,那么在面对大量访问的时候,数据库的瓶颈很快就能显现出来,这时一台数据库将很快无法满足应用,于是我们需要使用数据库集群或者库表散列。在数据库集群方面,很多数据库都有自己的解决方案,Oracle、Sybase等都有很好的方案,常用的MySQL提供的Master/Slave也是类似的方案,您使用了什么样的DB,就参考相应的解决方案来实施即可。上面提到的数据库集群由于在架构、成本、扩张性方面都会受到所采用DB类型的限制,于是我们需要从应用程序的角度来考虑改善系统架构,库表散列是常用并且最有效的解决方案。我们在应用程序中安装业务和应用或者功能模块将数据库进行分离,不同的模块对应不同的数据库或者表,再按照一定的策略对某个页面或者功能进行更小的数据库散列,比如用户表,按照用户ID进行表散列,这样就能够低成本的提升系统的性能并且有很好的扩展性。sohu的论坛就是采用了这样的架构,将论坛的用户、设置、帖子等信息进行数据库分离,然后对帖子、用户按照板块和ID进行散列数据库和表,最终可以在配置文件中进行简单的配置便能让系统随时增加一台低成本的数据库进来补充系统性能。

4、缓存一词搞技术的都接触过,很多地方用到缓存。网站架构和网站开发中的缓存也是非常重要。这里先讲述最基本的两种缓存。高级和分布式的缓存在后面讲述。架构方面的缓存,对Apache比较熟悉的人都能知道Apache提供了自己的缓存模块,也可以使用外加的Squid模块进行缓存,这两种方式均可以有效的提高Apache的访问响应能力。网站程序开发方面的缓存,Linux上提供的Memory Cache是常用的缓存接口,可以在web开发中使用,比如用Java开发的时候就可以调用MemoryCache对一些数据进行缓存和通讯共享,一些大型社区使用了这样的架构。另外,在使用web语言开发的时候,各种语言基本都有自己的缓存模块和方法,PHP有Pear的Cache模块,Java就更多了,.net不是很熟悉,相信也肯定有。

5、镜像是大型网站常采用的提高性能和数据安全性的方式,镜像的技术可以解决不同网络接入商和地域带来的用户访问速度差异,比如 ChinaNet和EduNet之间的差异就促使了很多网站在教育网内搭建镜像站点,数据进行定时更新或者实时更新。在镜像的细节技术方面,这里不阐述太深,有很多专业的现成的解决架构和产品可选。也有廉价的通过软件实现的思路,比如Linux上的rsync等工具。

6、负载均衡将是大型网站解决高负荷访问和大量并发请求采用的终极解决办法。负载均衡技术发展了多年,有很多专业的服务提供商和产品可以选择,我个人接触过一些解决方法,其中有两个架构可以给大家做参考。

7、硬件四层交换第四层交换使用第三层和第四层信息包的报头信息,根据应用区间识别业务流,将整个区间段的业务流分配到合适的应用服务器进行处理。第四层交换功能就象是虚 IP,指向物理服务器。它传输的业务服从的协议多种多样,有HTTP、FTP、NFS、Telnet或其他协议。这些业务在物理服务器基础上,需要复杂的载量平衡算法。在IP世界,业务类型由终端TCP或UDP端口地址来决定,在第四层交换中的应用区间则由源端和终端IP地址、TCP和UDP端口共同决定。在硬件四层交换产品领域,有一些知名的产品可以选择,比如Alteon、F5等,这些产品很昂贵,但是物有所值,能够提供非常优秀的性能和很灵活的管理能力。Yahoo中国当初接近2000台服务器使用了三四台Alteon就搞定了。

8、软件四层交换大家知道了硬件四层交换机的原理后,基于OSI模型来实现的软件四层交换也就应运而生,这样的解决方案实现的原理一致,不过性能稍差。但是满足一定量的压力还是游刃有余的,有人说软件实现方式其实更灵活,处理能力完全看你配置的熟悉能力。软件四层交换我们可以使用Linux上常用的LVS来解决,LVS就是Linux Virtual Server,他提供了基于心跳线heartbeat的实时灾难应对解决方案,提高系统的鲁棒性,同时可供了灵活的虚拟VIP配置和管理功能,可以同时满足多种应用需求,这对于分布式的系统来说必不可少。一个典型的使用负载均衡的策略就是,在软件或者硬件四层交换的基础上搭建squid集群,这种思路在很多大型网站包括搜索引擎上被采用,这样的架构低成本、高性能还有很强的扩张性,随时往架构里面增减节点都非常容易。这样的架构我准备空了专门详细整理一下和大家探讨。对于大型网站来说,前面提到的每个方法可能都会被同时使用到,我这里介绍得比较浅显,具体实现过程中很多细节还需要大家慢慢熟悉和体会,有时一个很小的squid参数或者apache参数设置,对于系统性能的影响就会很大,希望大家一起讨论,达到抛砖引玉之效。

用squid做web cache server,而apache在squid的后面提供真正的web服务。当然使用这样的架构必须要保证主页上大部分都是静态页面。这就需要程序员的配合将页面在反馈给客户端之前将页面全部转换成静态页面。

基本看出sina和sohu对于频道等栏目都用了相同的技术,即squid来监听这些IP的80端口,而真正的web server来监听另外一个端口。从用户的感觉上来说不会有任何的区别,而相对于将web server直接和客户端连在一起的方式,这样的方式明显的节省的带宽和服务器。用户访问的速度感觉也会更快。

实例Yupoo! 的网站技术架构

带宽:4000M/S 

服务器数量:60 台左右

Web服务器:Lighttpd, Apache, nginx

应用服务器:Tomcat

其他:Python, Java, MogileFS 、ImageMagick 等

首先看一下网站的架构图:

Yupoo_Arch.jpg

该架构图给出了很好的概览(点击可以查看在 Yupoo! 上的大图和原图,请注意该图版权信息)。

关于 Squid 与 Tomcat

Squid 与 Tomcat 似乎在 Web 2.0 站点的架构中较少看到。我首先是对 Squid 有点疑问,对此阿华的解释是"目前暂时还没找到效率比 Squid 高的缓存系统,原来命中率的确很差,后来在 Squid 前又装了层 Lighttpd, 基于 url 做 hash, 同一个图片始终会到同一台 squid 去,所以命中率彻底提高了"

对于应用服务器层的 Tomcat,现在 Yupoo! 技术人员也在逐渐用其他轻量级的东西替代,而 YPWS/YPFS 现在已经用 Python 进行开发了。

名次解释:

  • YPWS--Yupoo Web Server YPWS 是用 Python开发的一个小型 Web 服务器,提供基本的 Web 服务外,可以增加针对用户、图片、外链网站显示的逻辑判断,可以安装于任何有空闲资源的服务器中,遇到性能瓶颈时方便横向扩展。
  • YPFS--Yupoo File System 与 YPWS 类似,YPFS 也是基于这个 Web 服务器上开发的图片上传服务器。

【Updated: 有网友留言质疑 Python 的效率,Yupoo 老大刘平阳在 del.icio.us 上写到 "YPWS用Python自己写的,每台机器每秒可以处理294个请求, 现在压力几乎都在10%以下"】

图片处理层

接下来的 Image Process Server 负责处理用户上传的图片。使用的软件包也是 ImageMagick,在上次存储升级的同时,对于锐化的比率也调整过了(我个人感觉,效果的确好了很多)。”Magickd“ 是图像处理的一个远程接口服务,可以安装在任何有空闲 CPU资源的机器上,类似 Memcached的服务方式。

我们知道 Flickr 的缩略图功能原来是用 ImageMagick 软件包的,后来被雅虎收购后出于版权原因而不用了(?);EXIF 与 IPTC Flicke 是用 Perl 抽取的,我是非常建议 Yupoo! 针对 EXIF 做些文章,这也是潜在产生受益的一个重点。

图片存储层

原来 Yupoo! 的存储采用了磁盘阵列柜,基于 NFS 方式的,随着数据量的增大,”Yupoo! 开发部从07年6月份就开始着手研究一套大容量的、能满足 Yupoo! 今后发展需要的、安全可靠的存储系统“,看来 Yupoo! 系统比较有信心,也是满怀期待的,毕竟这要支撑以 TB 计算的海量图片的存储和管理。我们知道,一张图片除了原图外,还有不同尺寸的,这些图片统一存储在 MogileFS 中。

对于其他部分,常见的 Web 2.0 网站必须软件都能看到,如 MySQL、Memcached 、Lighttpd 等。Yupoo! 一方面采用不少相对比较成熟的开源软件,一方面也在自行开发定制适合自己的架构组件。这也是一个 Web 2.0 公司所必需要走的一个途径。

非常感谢一下 Yupoo! 阿华对于技术信息的分享,技术是共通的。下一个能爆料是哪家?

--EOF--

lighttpd+squid这套缓存是放在另外一个机房作为cdn的一个节点使用的,图中没描绘清楚,给大家带来不便了。

squid前端用lighttpd没用nginx,主要是用了这么久,没出啥大问题,所以就没想其他的了。

URL Hash的扩展性的确不好,能做的就是不轻易去增减服务器,我们目前是5台服务器做一组hash.

我们现在用Python写的Web Server,在效率方面,我可以给个测试数据,根据目前的访问日志模拟访问测试的结果是1台ypws,平均每秒处理294个请求(加载所有的逻辑判断)。

在可靠性上,还不没具体的数据,目前运行1个多月还没有任何异常。

lvs每个节点上都装nginx,主要是为了反向代理及处理静态内容,不过apache已显得不是那么必需,准备逐渐去掉。

我们处理图片都是即时的,我们目前半数以上的服务器都装了magickd服务,用来分担图片处理请求。

实例:Tailrank 网站架构

每天数以千万计的 Blog 内容中,实时的热点是什么? Tailrank 这个 Web 2.0 Startup 致力于回答这个问题。

专门爆料网站架构的 Todd Hoff 对 Kevin Burton 进行了采访。于是我们能了解一下 Tailrank 架构的一些信息。每小时索引 2400 万的 Blog 与 Feed,内容处理能力为 160-200Mbps,IO 写入大约在10-15MBps。每个月要处理 52T 之多的原始数据。Tailrank 所用的爬虫现在已经成为一个独立产品:spinn3r。

服务器硬件

目前大约 15 台服务器,CPU 是 64 位的 Opteron。每台主机上挂两个 SATA 盘,做 RAID 0。据我所知,国内很多 Web 2.0 公司也用的是类似的方式,SATA 盘容量达,低廉价格,堪称不二之选。操作系统用的是 Debian Linux 。Web 服务器用 Apache 2.0,Squid 做反向代理服务器。

数据库

Tailrank 用 MySQL 数据库,联邦数据库形式。存储引擎用 InnoDB, 数据量 500GB。Kevin Burton 也指出了 MySQL 5 在修了一些 多核模式下互斥锁的问题(This Bug?)。到数据库的JDBC 驱动连接池用 lbpool 做负载均衡。MySQL Slave 或者 Master的复制用 MySQLSlaveSync 来轻松完成。不过即使这样,还要花费 20%的时间来折腾 DB。

其他开放的软件

任何一套系统都离不开合适的 Profiling 工具,Tailrank 也不利外,针对 Java 程序的 Benchmark 用 Benchmark4j。Log 工具用 Log5j(不是 Log4j)。Tailrank 所用的大部分工具都是开放的。

Tailrank 的一个比较大的竞争对手是 Techmeme,虽然二者暂时看面向内容的侧重点有所不同。其实,最大的对手还是自己,当需要挖掘的信息量越来越大,如果精准并及时的呈现给用户内容的成本会越来越高。从现在来看,Tailrank 离预期目标还差的很远。期待罗马早日建成

YouTube架构学习

原文: YouTube Architecture

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
  • 处理飞速增长的流量

Java代码

1. while (true)
2. {
3. identify_and_fix_bottlenecks();
4. drink();
5. sleep();
6. notice_new_bottleneck();
7. }
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。

实例: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 times lower cost if you you use a failure-prone infrastructure rather than an infrastructure built on highly reliable components. You must build reliability 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有限时压缩是一个好的选择。

实例:Lighttpd+Squid+Apache搭建高效率Web服务器

架构原理

Apache通常是开源界的首选Web服务器,因为它的强大和可靠,已经具有了品牌效应,可以适用于绝大部分的应用场合。但是它的强大有时候却显得笨重,配置文件得让人望而生畏,高并发情况下效率不太高。而轻量级的Web服务器Lighttpd却是后起之秀,其静态文件的响应能力远高于 Apache,据说是Apache的2-3倍。Lighttpd的高性能和易用性,足以打动我们,在它能够胜任的领域,尽量用它。Lighttpd对 PHP的支持也很好,还可以通过Fastcgi方式支持其他的语言,比如Python。

毕竟Lighttpd是轻量级的服务器,功能上不能跟Apache比,某些应用无法胜任。比如Lighttpd还不支持缓存,而现在的绝大部分站点都是用程序生成动态内容,没有缓存的话即使程序的效率再高也很难满足大访问量的需求,而且让程序不停的去做同一件事情也实在没有意义。首先,Web程序是需要做缓存处理的,即把反复使用的数据做缓存。即使这样也还不够,单单是启动Web处理程序的代价就不少,缓存最后生成的静态页面是必不可少的。而做这个是 Squid的强项,它本是做代理的,支持高效的缓存,可以用来给站点做反向代理加速。把Squid放在Apache或者Lighttpd的前端来缓存 Web服务器生成的动态内容,而Web应用程序只需要适当地设置页面实效时间即可。

即使是大部分内容动态生成的网站,仍免不了会有一些静态元素,比如图片、JS脚本、CSS等等,将Squid放在Apache或者Lighttp 前端后,反而会使性能下降,毕竟处理HTTP请求是Web服务器的强项。而且已经存在于文件系统中的静态内容再在Squid中缓存一下,浪费内存和硬盘空间。因此可以考虑将Lighttpd再放在Squid的前面,构成 Lighttpd+Squid+Apache的一条处理链,Lighttpd在最前面,专门用来处理静态内容的请求,把动态内容请求通过proxy模块转发给Squid,如果Squid中有该请求的内容且没有过期,则直接返回给Lighttpd。新请求或者过期的页面请求交由Apache中Web程序来处理。经过Lighttpd和Squid的两级过滤,Apache需要处理的请求将大大减少,减少了Web应用程序的压力。同时这样的构架,便于把不同的处理分散到多台计算机上进行,由Lighttpd在前面统一把关。

在这种架构下,每一级都是可以进行单独优化的,比如Lighttpd可以采用异步IO方式,Squid可以启用内存来缓存,Apache可以启用MPM 等,并且每一级都可以使用多台机器来均衡负载,伸缩性很好。

原文:http://jythoner.iteye.com/blog/562567

Henry H

unread,
Sep 15, 2011, 7:24:15 PM9/15/11
to dev...@googlegroups.com

细分四层网站架构 解说网站的压力究竟在哪里


目前网站架构一般分成负载均衡层、WEB层和数据库层,我其实一般还会多加一层,即文件服务器层,这样我们在后面的讨论过程中,我们可以依次对这四层进行讨论;这里为了更具有说服力,我将用三个并发较大的生产环境来说明下,一个是我现在维护的电子商务网站(并发最大值 2000,日PV500万左右,此并发并不是总这么高的,只是最高峰是有2000,下面的网站类似)、我的一拍网网站(并发最大值1500,日PV500万左右)、以前维护的大型CDN广告网站(并发最大值5000,日PV 5000万左右)。

网站的压力究竟在哪里?

负载均衡层

首先说下负载均衡层,我们熟悉的硬件/软件技术有F5/LVS、HAProxy,还有Nginx,它们的性能都是非常优异的,且不说F5的抗并发能力,LVS现在在全世界范围内的应用,而且淘宝现在升级架构,也将LVS取代了F5,HAProxy可能大家不是特别熟悉,但它确实在生产环境下表现优异,强大的吞吐能力,稳定性比之硬件过尤不及。

再说下Nginx,我是将Nginx+Keepalived架构用于了各种生产环境中的,经过长时间的线上观察,发现Nginx作为负载均衡器/反向代理也很稳定,就算并发压力过大,我们前面可以用F5/LVS来顶,而将Nginx作为中层代理,这样的效果其实也 不差,所以负载均衡层的压力不能算是特别大。

WEB层

WEB层这块压力比较大的网站现在都换成了Nginx作为WEB应用服务器,事实上,它的抗并发能力确实超过了预期;我朋友维护的一家门户网站,高峰期时某台Nginx应用服务器的并发达到了一万以上,但Nginx也很负责和稳定的提供服务,在实际的生产环境中,如果我们考虑到后端的数据库服务时,一万并发应该也算是一个比较大的数值了。

另外,Linux集群有一个优势,就是它的高扩展性,就算我们的网站的并发有一万以上,我们后端的WEB服务是Apache,我们多加几台Apache服务器即可,在实际的线上维护时,我们发现,高峰期间,实际上每台WEB的并发并不算是特别大,所以网站的压力在这一层我们也能通过技术手段加以克服。

文件服务器层

文件服务器层,由于网站的后期宣传策话,名气也越来越大,PV值也越来越高,原先的DRBD+Heartbeat+NFS(这个其实也只是单NFS,只不过我们利用DRBD来保证NFS的高可用而已)已经越来越顶不住压力了,这个时候我们想到了分布式文件系统,我测试的的是MooseFS,在内网测试了很长时间还是没敢用到生产环境下面,googel的分布式文件系统还是很成熟的,推荐大家学习;最后还是用采用以前的CDN传统的方法解决这个问题,即用了squid反向代理加速器来解决小文件过多的问题,Nginx强大的正则处理分发能力,也让后端的NFS压力变得很小;另外,我还用采用域名的分散策略例如使用pics.xxx.com/pdf.xxx.com...来区分标记为a或b的一系列文件,这些文件存储的时候,依然按照标记,存到pics或pdf的服务器上。这个策略将区分机器的任务交由dns服务器来执行,扩容时会相应轻松。

这需要web项目初期就规划好这些东东,后期才转用域名策略的成本比较高甚至不可以实现,大家可以注意下,其实这一层如果网站是专业的图片服务器网站时压力还是很大的,我们需要在这个上面投入足够多的硬件资源。

数据库层

数据库层的压力,我觉得网站的PV和并发上去以后,数据库这块的压力是最大的,CDN大型广告网站我们用的是oracle RAC方案,它保证了数据的高可用性,当然了价格也是非常昂贵的(如果使用高配置的PC服务器,Oracle一般按照CPU个数收费);那么免费的MySQL数据库,面对这种并发压力大的情况,又用哪些方法呢?首先,我们说下传统的MySQL主从方案,配置简单,单机MySQL优化做好事性能也不弱,如果这种架构解决不了数据库的压力情况,我们可以考虑以下几种方案:

◆常规复制架构--Master-slaves,是由一个Master复制到一个或多个Salve的架构模式,主要用于读压力大的应用数据库端廉价扩展解决方案,读写分离,Master主要负责写方面的压力。

◆级联复制架构,即Master-Slaves-Slaves,这个也是为了防止Slaves的读压力过大,而配置一层二级 Slaves,很容易解决Master端因为附属slave太多而成为瓶劲的风险。

◆Dual Master与级联复制结合架构,即Master-Master-Slaves,最大的好处是既可以避免主Master的写操作受到Slave集群的复制带来的影响,而且保证了主Master的单点故障。

◆MySQL的数据库切分,我们可以通过数据切恰好技术将一个大的MySQL Server切分成多个小的MySQL Server,既解了写入性能瓶颈问题,同时也一次提升了整个数据库集群的扩展性,从而解决了数据库压力过大的问题,这个现在也是我在生产环境中比较推荐的做法之一。

以上的观点仅仅只代表个人的一些想法

Henry H

unread,
Sep 15, 2011, 7:28:00 PM9/15/11
to dev...@googlegroups.com

大型网站架构不得不考虑的10个问题

这里的大型网站架构只包括高互动性高交互性的数据型大型网站,基于大家众所周知的原因,我们就不谈新闻类和一些依靠HTML静态化就可以实现的架构 了,我们以高负载高数据交换高数据流动性的网站为例,比如海内,开心网等类似的web2.0系列架构。我们这里不讨论是PHP还是JSP或者.NET环 境,我们从架构的方面去看问题,实现语言方面并不是问题,语言的优势在于实现而不是好坏,不论你选择任何语言,架构都是必须要面对的。

这里讨论一下大型网站需要注意和考虑的问题

1、海量数据的处理

众所周知,对于一些相对小的站点来说,数据量并不是很大,select和update就可以解决我们面对的问题,本身负载量不是很大,最多再加几个 索引就可以搞定。对于大型网站,每天的数据量可能就上百万,如果一个设计不好的多对多关系,在前期是没有任何问题的,但是随着用户的增长,数据量会是几何 级的增长的。在这个时候我们对于一个表的select和update的时候(还不说多表联合查询)的成本的非常高的。

2、数据并发的处理

在一些时候,2.0的CTO都有个尚方宝剑,就是缓存。对于缓存,在高并发高处理的时候也是个大问题。在整个应用程序下,缓存是全局共享的,然而在 我们进行修改的时候就,如果两个或者多个请求同时对缓存有更新的要求的情况下,应用程序会直接的死掉。这个时候,就需要一个好的数据并发处理策略以及缓存 策略。

另外,就是数据库的死锁问题,也许平时我们感觉不到,死锁在高并发的情况下的出现的概率是非常高的,磁盘缓存就是一个大问题。

3、文件存贮的问题

对于一些支持文件上传的2.0的站点,在庆幸硬盘容量越来越大的时候我们更多的应该考虑的是文件应该如何被存储并且被有效的索引。常见的方案是对文 件按照日期和类型进行存贮。但是当文件量是海量的数据的情况下,如果一块硬盘存贮了500个G的琐碎文件,那么维护的时候和使用的时候磁盘的Io就是一个 巨大的问题,哪怕你的带宽足够,但是你的磁盘也未必响应过来。如果这个时候还涉及上传,磁盘很容易就over了。

也许用raid和专用存贮服务器能解决眼下的问题,但是还有个问题就是各地的访问问题,也许我们的服务器在北京,可能在云南或者新疆的访问速度如何解决?如果做分布式,那么我们的文件索引以及架构该如何规划。

所以我们不得不承认,文件存贮是个很不容易的问题

4、数据关系的处理

我们可以很容易的规划出一个符合第三范式的数据库,里面布满了多对多关系,还能用GUID来替换INDENTIFY COLUMN 但是,多对多关系充斥的2.0时代,第三范式是第一个应该被抛弃的。必须有效的把多表联合查询降到最低。

5、数据索引的问题

众所周知,索引是提高数据库效率查询的最方面最廉价最容易实现的方案。但是,在高UPDATE的情况下,update和delete付出的成本会高的无法想想,笔者遇到过一个情况,在更新一个聚焦索引的时候需要10分钟来完成,那么对于站点来说,这些基本上是不可忍受的。

索引和更新是一对天生的冤家,问题A,D,E这些是我们在做架构的时候不得不考虑的问题,并且也可能是花费时间最多的问题。

6、分布式处理

对于2.0网站由于其高互动性,CDN实现的效果基本上为0,内容是实时更新的,我们常规的处理。为了保证各地的访问速度,我们就需要面对一个绝大的问题,就是如何有效的实现数据同步和更新,实现各地服务器的实时通讯有是一个不得不需要考虑的问题。

7、Ajax的利弊分析

成也AJAX,败也AJAX,AJAX成为了主流趋势,突然发现基于XMLHTTP的post和get是如此的容易。客户端get或者post 到服务器数据,服务器接到数据请求之后返回来,这是一个很正常的AJAX请求。但是在AJAX处理的时候,如果我们使用一个抓包工具的话,对数据返回和处 理是一目了然。对于一些计算量大的AJAX请求的话,我们可以构造一个发包机,很容易就可以把一个webserver干掉。

8、数据安全性的分析

对于HTTP协议来说,数据包都是明文传输的,也许我们可以说我们可以用加密啊,但是对于G问题来说的话,加密的过程就可能是明文了(比如我们知道 的QQ,可以很容易的判断他的加密,并有效的写一个跟他一样的加密和解密方法出来的)。当你站点流量不是很大的时候没有人会在乎你,但是当你流量上来之 后,那么所谓的外挂,所谓的群发就会接踵而来(从qq一开始的群发可见端倪)。

也许我们可以很的意的说,我们可以采用更高级别的判断甚至HTTPS来实 现,注意,当你做这些处理的时候付出的将是海量的database,io以及CPU的成本。对于一些群发,基本上是不可能的。笔者已经可以实现对于百度空 间和qq空间的群发了。大家愿意试试,实际上并不是很难。

9、数据同步和集群的处理的问题

当我们的一台databaseserver不堪重负的时候,这个时候我们就需要做基于数据库的负载和集群了。而这个时候可能是最让人困扰的的问题 了,数据基于网络传输根据数据库的设计的不同,数据延迟是很可怕的问题,也是不可避免的问题,这样的话,我们就需要通过另外的手段来保证在这延迟的几秒或 者更长的几分钟时间内,实现有效的交互。比如数据散列,分割,内容处理等等问题。

10、数据共享的渠道以及OPENAPI趋势

Openapi已经成为一个不可避免的趋势,从google,facebook,myspace到海内校内,都在考虑这个问题,它可以更有效的留住 用户并激发用户的更多的兴趣以及让更多的人帮助你做最有效的开发。这个时候一个有效的数据共享平台,数据开放平台就成为必不可少的途径了,而在开放的接口 的情况保证数据的安全性和性能,又是一个我们必须要认真思考的问题了。

Henry H

unread,
Sep 15, 2011, 7:29:51 PM9/15/11
to dev...@googlegroups.com

五层拆解 听酒哥讲网站架构


从以前维护大型的CDN广告网站,然后独立做股票类的资讯网站,再到维护目前公司的电子商务网站,网站的架构或多或少的接触了不少;很多同学或同行也在向我咨询网站架构的事,所以我将维护过的网站架构稍为整理下,希望能给大家带来帮助,了解网架构到底是怎么一回事。

众所周知,大家习惯将网站分成三层:即负载均衡层、web层、数据库层,但我根据线上的实际压力情况,强烈建议分成五层,即硬件防护层、负载均衡层、web层、文件服务器层(图片)、数据库层,这样大家理解一个简单的网站可能更容易。理解了最基础的网站后,再理解大型网站架构可能就更容易了。

 

硬件防火墙层:

这一层最重要的是安全防护,最基本的是要防止DDOS攻击及应用层的防护等。我目前应用得比较好的是华赛的三层防火墙+天泰七层应用防火墙,具体实施案例请参考我在51cto.com的文章,这里限于篇幅我就不详细说明了;如果成本预算不是太高的话,可考虑Juniper系统的防火墙,效果也不错。

负载均衡层

这一层要考虑的东西其实很多,包括:

一、你考虑布署的网站到底要承受多大的并发量;

二、负载均衡层是否能稳定,存在单点故障吗;

三、成本的考虑有时要高于技术的;

四、网络的情况也决定了你到底要考虑哪种负载均衡器。

基于以上几点情况,我拿实际情况分明下:

我最早之前维护的CDN广告网站,并发长期在6000以上,所以只能考虑F5,而又要做到高可用,此时不是单F5了,所以上了二台F5,当然成本也非常的高;公司光在F5上的投入,大约应该在60-80万之间,相信这样的投入,未必会被你所在公司的决策层所接受;而我后期维护及布署的证券类资讯网站,并发比较小,大约在200之间,所以我用了二台Linux机器作的LVS+Keepalived,效果也不错,相当稳定;而现在维护的公司的电子商务网站,并发大约在1.1K左右,初期我们其时也考虑的是LVS+Keepalived,但上上去就发现公司的网络情况非常乱,每台服务器至少有六七条静态路由,lvs上上去根本就发挥不了作用,所以换上了Nginx+keepalived,我也编写了shell监控nginx服务进程,实现真正意义上的负载高可用。这一层我总结了下,其时考虑以下几点情况,即成本、网络、并发、高可用。

web集群层

这一层为了避免单点故障,大家都用的是Apache、Nginx或tomcat集群,其好处也很明显:①避免单点故障;②负载客户端的高并发请求。Apache是LAMP架构最核心的WebServer,开源、稳定、模块丰富是Apache的优势。但Apache的缺点是有些臃肿,内存和CPU开销大,性能上有损耗,不如一些轻量级的Web服务器(例如Nginx)高效,轻量级的Web服务器对于静态文件的响应能力来说远高于Apache服务器。而且现在根据实际的线上环境,Nginx服务器抗并发确实高于Apache,这一点张宴的博客已作了大量详细叙述,但在Apache在高内存(>=16G)的情况下,单Apache的抗并发能力也是很强的,高于6000。我现在的做法是,如果是生级现有的以Apache作为webserver的网站,我单纯只是考虑加上Nginx作负载均衡,不会动原有网站的架构;如果是架构新网站,我会采用Nginx作为webserver。

文件服务器层

这一层的作用容易被人忽视,其实现在服务器的性能都上上去了,并发情况也都被大家重视,但服务器层的压力却甚少有人关心,在大规划的频繁的访问过程中,单NFS越来越不能满足网站的需求了,我们有时接到用户反映网站慢的情况,结果采用故障排查才发现,居然是NFS不堪重负,针对于这种情况,目前采用的方案有:

①可采用田逸推荐的分布式文件系统MFS(moosefs)实现存储共享,他目前将此系统应用于遨游,线上用的东西毕竟比较有说服力;

②直接用NEC的存储,虽然强悍,但增加了网站的实施成本及复杂度;

③用DRDB+Heartbeat+NFS组建NFS集群,效果也很稳定,但也要注意Heartbeat的脑裂问题。

数据库层

为了更好的说明力,我这里用的网站都以电子商务和广告网站,这些对数据库要求严苛的网站来说明,这些网站对数据库的要求是很高的,在数据库并发、稳定及延时性方面均有要求,MySQL在性能、稳定性和功能上是首选,可以达到百万级别的数据存储。目前采用的方案有:

①目前多采用MySQL的主从方案,实际读写都采用单一服务器,服务器采用公司性能最好的服务器充当(MySQL的cluster暂时不敢用于线上环境);

②采用oracle的RAC双机方案,在实际高并发的数据库需求下,效果还是相当不错。

加速缓存层

PHP的负载采用Apache集群,使用squid进行缓存,html或图片的请求可以直接由squid返回给用户。这一层可以根据你的网站情况来考虑,现在由于Nginx的反向代理越做越好,我们其实可以用最前端的Nginx来充当反向代理,这时的Nginx服务器,充当的作用是负载均衡器/反向代理;张宴已将其用于了生产环境,具体可参考他的相关文档.

网站架构是一个艺术活,责任重大;系统架构师不等于系统工程师,要想从系统工程师到系统架构师,不仅需要许多多年的运维经验和广泛的运维知识,还需要付出大量的努力,希望大家都成为未来的系统架构师,最后祝大家工作愉快!


Henry H

unread,
Sep 15, 2011, 7:38:01 PM9/15/11
to dev...@googlegroups.com

CDN Discussion


在介绍网站架构之前,我们先介绍一些网站架构中最基础和常见的概念,以便更好的理解后面的有关负载均衡和分布式存储等技术。第一个,首先讲讲CDN。

1、CDN是什么

CDN(Content Delivery Network),就是内容发布网或者内容分发网,它的主要目的:通过在现有的Internet中增加一层新的网络架构,将网站的内容发布到最接近用户的网络边缘,使用户可以就近取得所需的内容,从而提高用户访问网站的响应速度,提升用户体验,同时能够分散访问压力,把本来用户集中访问分散到各地去。网站的内容提供商(比如新浪、搜狐、网易等等)使用CDN,就可以在宏观层解决一部分大流量、海量用户并发等令人头疼的问题。

2、CDN的组成

内容发布网(CDN)是一个经策略性部署的整体系统,包括分布式存储、负载均衡、网络请求的重定向和内容管理4个要件,而内容管理和全局的网络流量管理是CDN的核心所在。通过用户就近性和服务器负载的判断,CDN确保内容以一种极为高效的方式为用户的请求提供服务,达到用户所要求的服务距用户仅有"一跳"(Single Hop)之遥。

我们通常的内容发布模式都是将网站数据放到一处,然后应对来自世界各地的访问,我们多数考虑的是软件部署架构,很少考虑网络硬件架构。与之形成对比的是,CDN则强调了网络在内容发布中的重要性。通过引入主动的内容管理层的和全局负载均衡,CDN从根本上区别于传统的内容发布模式。

内容提供商承担了他们不该干也干不好的内容发布服务。

3、互联网服务的产业链

纵观整个宽带服务的价值链,内容提供商和用户位于整个价值链的两端,中间依靠网络服务提供商将其串接起来。随着互联网工业的成熟和商业模式的变革,在这条价值链上的角色越来越多也越来越细分,出现了内容运营商、托管服务提供商、骨干网络服务提供商、接入服务提供商等等。在这一条价值链上的每一个角色都要分工合作、各司其职才能为客户提供良好的服务,从而带来多赢的局面。从内容与网络的结合模式上看,内容的发布已经走过了ICP的内容(应用)服务器和IDC这两个阶段。IDC的热潮也催生了托管服务提供商这一角色。但是,IDC并不能解决内容的有效发布问题。内容位于网络的中心并不能解决骨干带宽的占用和建立IP网络上的流量秩序。因此将内容推到网络的边缘,为用户提供就近性的边缘服务,从而保证服务的质量和整个网络上的访问秩序就成了一种显而易见的选择,这就是CDN服务模式。CDN的建立解决了困扰内容运营商的内容"集中与分散"的两难选择,无疑对于构建良好的互联网价值链是有价值的,也是不可或缺的最优网站加速服务。

4、CDN服务提供商

ChinaCache是中国最大的CDN服务提供商,是不是唯一未可知也。要想成为CDN服务提供商,恐怕要摆平电信、网通、铁通等等运营商,这得需要什么样的能力和背景不得而知。它的服务节点在全球已经超过130个,其中国内节点超过80个,覆盖全国主要6大网络(所谓6线机房,就是这么来的)的主要省份,象各大门户网站,比如新浪、网易等等都是租用了他们的服务。所以,你无论是在南方,或者北方,还是在北美,访问这些门户网站,感觉速度都很快,最主要的原因之一就是CDN发挥了效果。一般小网站是用不起这服务的,所以慢点就慢点了吧,可以租用互联互通的6线机房,如果网络足够宽的话,用户也可以忍受。如果想继续提升用户体验的话,就需要做一些网站镜像,部署在具有代表性的几个大城市,比如华南可以部署在广州,华东可以部署在上海,华北可以部署在北京,不过内容镜像的过程,就需要自己去部署和维护。还有的网站,采用内容分割的方式,比如建立针对各地的分站,业务情况不同,可能部署的策略不同。CDN可以认为是基础网络建设的一种策略。

前面介绍了cdn的一些原理和概念,以及提供cdn基础网络服务的途径。cdn看起来对于静态内容的,比如html,js,image是非常合适的,通过cdn的部署,用户只需要一跳就可以访问到网站的内容。那对于动态内容怎么办呢?我回答一下:

动态内容按照存在形态可以分为三类。

第一类:内容长时间不需变化,这类内容一般是通过网页静化技术,实现动态内容转换成静态内容,从而达到cdn部署,典型的就是内容类网站,比如新浪、搜狐、网易等等的内容发布系统cms,内容的增删改等管理工作被准实时同步到各个节点。

第二类:内容可能会短时间内发生变动,但是最终会稳定。比如论坛、博客等应用,这类服务提供的内容按照一定的时间间隔,实现批量静化,当然也有实时静化,像Mop的大杂烩、网易社区就是使用了这样的策略。

第三类:内容会实时变化,非常个性化。比如邮箱应用,这类服务提供的内容无法实现静化,只能通过实行分区域部署和负载均衡等手段进行优化。

对于提供cdn服务的厂商来讲,静态内容的cdn自然没有问题,对于第三类服务,只能从通信链路层进行相应的优化。

对于很多网站的伪静化,有的出于Seo的考虑,有的出于安全性的考虑,手段基本上是rewrite Url。它只不过是一种外在的表现形式,与Html静化是两回事,它依然是一种动态内容。

1. 负载均衡的分类

负载均衡技术在网站运营过程中应用非常普遍,技术也很成熟。负载均衡技术按照软硬件形式分为软均衡和硬均衡。软均衡就是基于软件技术的均衡,硬均衡是基于硬件技术的均衡;

按照网络协议划分又分为四层均衡和七层均衡。四层均衡就是基于OSI网络层的数据均衡,七层均衡是基于OSI应用层的数据均衡。

各种均衡方式在大型网站中均有采用,而且大多数情况下,是多种均衡方式的组合。

2. DNS轮询均衡

这种方式,算是比较独立的一种方式,不在上述划分之列,但使用比较广泛,一般用在网站最前端。你可以做个试验,在dos命令行中运行nslook命令。比如:nslookup www。163。com,你会看到命令给出了一堆解析后的IP地址。这些地址就是www.163.com这个域名绑定的多条A记录。我们从浏览器发起的访问请求http://www.163.com/,那么你输入的域名首先需要经过DNS服务器进行解析,Dns服务器的解析的过程就是按照A记录的顺序,依次分配IP地址。Dns轮询方式实现均衡就是利用这个原理,在一个域名下面绑定N个IP地址,访问请求被均衡到不同的设备。Dns轮询方式提供的IP地址,在大型网站中往往是一个集群的地址,可能是均衡交换机也可能是均衡服务器。对于小网站的话,挂接多台服务器也没有问题。

DNS轮询均衡的优点:

1、零成本:只是在Dns服务器上绑定几个A记录,域名注册商一般都提供;

2、部署简单:就是在网络拓扑进行设备扩增,然后在Dns服务器上添加记录。

DNS轮询均衡的缺点:

1、流量分配不均:Dns解析过程其实环节很多,而且是一种层层缓存的机制,你的dns服务器虽然进行更新,但是客户机、以及网络上其它的dns服务器不会实时更新,所以流量很难保证100%的平均。目前,dns服务器都提供了多种手段可以调整dns轮询分配的策略,但是确实无法保证很完美的均衡。

2、健康检查:Dns服务器中A记录地址中的某一台服务器宕机,DNS服务器是无法知道的,仍旧会将访问分配到此服务器。所以需要人员或者工具进行实时检测,在某台机器宕机之后,把备份机推上生产线,如果想要从A记录地址摘除某个地址,这个通知过程需要几个小时甚至更久才能扩散到所有的客户机。

Dns轮询方式推到服务的最前端还是很有效的,它通过最原始的方式,把访问用户映射到不同的服务集群上。对于大型网站来讲,对外服务的IP地址是不可能经常变动的,而且后端的集群一旦宕掉,可以迅速推上冗余集群。再加上,一般都是经过CDN部署,服务被拆分到各个局部,所以在运营过程中不会产生太大的影响。

3. OSI七层模型

我们接下来讲讲七层均衡。要理解四七层均衡的原理,就先要回忆一下大学课本里学的网络七层模型(OSI)。

OSI是一个开放性的通行系统互连参考模型,他是一个定义的非常好的协议规范。OSI模型有7层结构,每层都可以有几个子层。

OSI七层模型是一个很好的理论模型,但是在实际应用中都做了裁剪。尤其是TCP/IP的盛行,把7层结构压成了4层,

所以很多人都批评OSI七层模型过于复杂,但是作为一个完整的全面的网络模型,还是被大家非常认可的。OSI的7层从上到下分别是应用层、表示层、会话层、传输层、网络层、数据链路层、物理层。

OSI 7层的功能描述:

(1)应用层:与其他计算机进行通讯的一个应用,它是对应应用程序的通信服务的。例如,一个没有通信功能的字处理程序就不能执行通信的代码,从事字处理工作的程序员也不关心OSI的第7层。但是,如果添加了一个传输文件的选项,那么字处理器的程序员就需要实现OSI的第7层。示例:telnet,HTTP,FTP,WWW,NFS,SMTP等。

(2)表示层:这一层的主要功能是定义数据格式及加密。例如,FTP允许你选择以二进制或ASII格式传输。如果选择二进制,那么发送方和接收方不改变文件的内容。如果选择ASII格式,发送方将把文本从发送方的字符集转换成标准的ASII后发送数据。在接收方将标准的ASII转换成接收方计算机的字符集。示例:加密,ASII等。

(3)会话层:他定义了如何开始、控制和结束一个会话,包括对多个双向小时的控制和管理,以便在只完成连续消息的一部分时可以通知应用,从而使表示层看到的数据是连续的,在某些情况下,如果表示层收到了所有的数据,则用数据代表表示层。示例:RPC,SQL等。

(4)传输层:这层的功能包括是否选择差错恢复协议还是无差错恢复协议,及在同一主机上对不同应用的数据流的输入进行复用,还包括对收到的顺序不对的数据包的重新排序功能。示例:TCP,UDP,SPX。

(5)网络层:这层对端到端的包传输进行定义,他定义了能够标识所有结点的逻辑地址,还定义了路由实现的方式和学习的方式。为了适应最大传输单元长度小于包长度的传输介质,网络层还定义了如何将一个包分解成更小的包的分段方法。示例:IP,IPX等。

(6)数据链路层:他定义了在单个链路上如何传输数据。这些协议与被讨论的歌种介质有关。示例:ATM,FDDI等。

(7)物理层:OSI的物理层规范是有关传输介质的特性标准,这些规范通常也参考了其他组织制定的标准。连接头、针、针的使用、电流、电流、编码及光调制等都属于各种物理层规范中的内容。物理层常用多个规范完成对所有细节的定义。

Henry H

unread,
Sep 15, 2011, 8:46:04 PM9/15/11
to dev...@googlegroups.com

之前也有一些介绍大型网站架构演变的文章,例如LiveJournal的、ebay的,都是非常值得参考的,不过感觉他们讲的更多的是每次演变的结果,而没有很详细的讲为什么需要做这样的演变,再加上近来感觉有不少同学都很难明白为什么一个网站需要那么复杂的技术,于是有了写这篇文章的想法,在这篇文章中将阐述一个普通的网站发展成大型网站过程中的一种较为典型的架构演变历程和所需掌握的知识体系,希望能给想从事互联网行业的同学一点初步的概念,文中的不对之处也请各位多给点建议,让本文真正起到抛砖引玉的效果。

架构演变第一步:物理分离webserver和数据库

最开始,由于某些想法,于是在互联网上搭建了一个网站,这个时候甚至有可能主机都是租借的,但由于这篇文章我们只关注架构的演变历程,因此就假设这个时候 已经是托管了一台主机,并且有一定的带宽了,这个时候由于网站具备了一定的特色,吸引了部分人访问,逐渐你发现系统的压力越来越高,响应速度越来越慢,而这个时候比较明显的是数据库和应用互相影响,应用出问题了,数据库也很容易出现问题,而数据库出问题的时候,应用也容易出问题,于是进入了第一步演变阶段:将应用和数据库从物理上分离,变成了两台机器,这个时候技术上没有什么新的要求,但你发现确实起到效果了,系统又恢复到以前的响应速度了,并且支撑住了更高的流量,并且不会因为数据库和应用形成互相的影响。

看看这一步完成后系统的图示:

 


这一步涉及到了这些知识体系:

这一步架构演变对技术上的知识体系基本没有要求。

架构演变第二步:增加页面缓存

好景不长,随着访问的人越来越多,你发现响应速度又开始变慢了,查找原因,发现是访问数据库的操作太多,导致数据连接竞争激烈,所以响应变慢,但数据库连 接又不能开太多,否则数据库机器压力会很高,因此考虑采用缓存机制来减少数据库连接资源的竞争和对数据库读的压力,这个时候首先也许会选择采用squid 等类似的机制来将系统中相对静态的页面(例如一两天才会有更新的页面)进行缓存(当然,也可以采用将页面静态化的方案),这样程序上可以不做修改,就能够 很好的减少对webserver的压力以及减少数据库连接资源的竞争,OK,于是开始采用squid来做相对静态的页面的缓存。

看看这一步完成后系统的图示:


这一步涉及到了这些知识体系:

前端页面缓存技术,例如squid,如想用好的话还得深入掌握下squid的实现方式以及缓存的失效算法等。

架构演变第三步:增加页面片段缓存

增加了squid做缓存后,整体系统的速度确实是提升了,webserver的压力也开始下降了,但随着访问量的增加,发现系统又开始变的有些慢了,在尝 到了squid之类的动态缓存带来的好处后,开始想能不能让现在那些动态页面里相对静态的部分也缓存起来呢,因此考虑采用类似ESI之类的页面片段缓存策略,OK,于是开始采用ESI来做动态页面中相对静态的片段部分的缓存。

看看这一步完成后系统的图示:


这一步涉及到了这些知识体系:

页面片段缓存技术,例如ESI等,想用好的话同样需要掌握ESI的实现方式等;

架构演变第四步:数据缓存

在采用ESI之类的技术再次提高了系统的缓存效果后,系统的压力确实进一步降低了,但同样,随着访问量的增加,系统还是开始变慢,经过查找,可能会发现系 统中存在一些重复获取数据信息的地方,像获取用户信息等,这个时候开始考虑是不是可以将这些数据信息也缓存起来呢,于是将这些数据缓存到本地内存,改变完毕后,完全符合预期,系统的响应速度又恢复了,数据库的压力也再度降低了不少。

看看这一步完成后系统的图示:


这一步涉及到了这些知识体系:

缓存技术,包括像Map数据结构、缓存算法、所选用的框架本身的实现机制等。

架构演变第五步: 增加webserver

好景不长,发现随着系统访问量的再度增加,webserver机器的压力在高峰期会上升到比较高,这个时候开始考虑增加一台webserver,这也是为了同时解决可用性的问题,避免单台的webserver down机的话就没法使用了,在做了这些考虑后,决定增加一台webserver,增加一台webserver时,会碰到一些问题,典型的有:
1、如何让访问分配到这两台机器上,这个时候通常会考虑的方案是Apache自带的负载均衡方案,或LVS这类的软件负载均衡方案;
2、如何保持状态信息的同步,例如用户session等,这个时候会考虑的方案有写入数据库、写入存储、cookie或同步session信息等机制等;
3、如何保持数据缓存信息的同步,例如之前缓存的用户数据等,这个时候通常会考虑的机制有缓存同步或分布式缓存;
4、如何让上传文件这些类似的功能继续正常,这个时候通常会考虑的机制是使用共享文件系统或存储等;
在解决了这些问题后,终于是把webserver增加为了两台,系统终于是又恢复到了以往的速度。

看看这一步完成后系统的图示:


这一步涉及到了这些知识体系:

负载均衡技术(包括但不限于硬件负载均衡、软件负载均衡、负载算法、linux转发协议、所选用的技术的实现细节等)、主备技术(包括但不限于ARP欺骗、linux heart-beat等)、状态信息或缓存同步技术(包括但不限于Cookie技术、UDP协议、状态信息广播、所选用的缓存同步技术的实现细节等)、共享文件技术(包括但不限于NFS等)、存储技术(包括但不限于存储设备等)。

架构演变第六步:分库

享受了一段时间的系统访问量高速增长的幸福后,发现系统又开始变慢了,这次又是什么状况呢,经过查找,发现数据库写入、更新的这些操作的部分数据库连接的 资源竞争非常激烈,导致了系统变慢,这下怎么办呢,此时可选的方案有数据库集群和分库策略,集群方面像有些数据库支持的并不是很好,因此分库会成为比较普遍的策略,分库也就意味着要对原有程序进行修改,一通修改实现分库后,不错,目标达到了,系统恢复甚至速度比以前还快了。

看看这一步完成后系统的图示:


这一步涉及到了这些知识体系:

这一步更多的是需要从业务上做合理的划分,以实现分库,具体技术细节上没有其他的要求;

但同时随着数据量的增大和分库的进行,在数据库的设计、调优以及维护上需要做的更好,因此对这些方面的技术还是提出了很高的要求的。

架构演变第七步:分表、DAL和分布式缓存

随着系统的不断运行,数据量开始大幅度增长,这个时候发现分库后查询仍然会有些慢,于是按照分库的思想开始做分表的工作,当然,这不可避免的会需要对程序 进行一些修改,也许在这个时候就会发现应用自己要关心分库分表的规则等,还是有些复杂的,于是萌生能否增加一个通用的框架来实现分库分表的数据访问,这个在ebay的架构中对应的就是DAL,这个演变的过程相对而言需要花费较长的时间,当然,也有可能这个通用的框架会等到分表做完后才开始做,同时,在这个阶段可 能会发现之前的缓存同步方案出现问题,因为数据量太大,导致现在不太可能将缓存存在本地,然后同步的方式,需要采用分布式缓存方案了,于是,又是一通考察和折磨,终于是将大量的数据缓存转移到分布式缓存上了。

看看这一步完成后系统的图示:


这一步涉及到了这些知识体系:

分表更多的同样是业务上的划分,技术上涉及到的会有动态hash算法、consistent hash算法等;

DAL涉及到比较多的复杂技术,例如数据库连接的管理(超时、异常)、数据库操作的控制(超时、异常)、分库分表规则的封装等;

架构演变第八步:增加更多的webserver

在做完分库分表这些工作后,数据库上的压力已经降到比较低了,又开始过着每天看着访问量暴增的幸福生活了,突然有一天,发现系统的访问又开始有变慢的趋势 了,这个时候首先查看数据库,压力一切正常,之后查看webserver,发现apache阻塞了很多的请求,而应用服务器对每个请求也是比较快的,看来 是请求数太高导致需要排队等待,响应速度变慢,这还好办,一般来说,这个时候也会有些钱了,于是添加一些webserver服务器,在这个添加 webserver服务器的过程,有可能会出现几种挑战:
1、Apache的软负载或LVS软负载等无法承担巨大的web访问量(请求连接数、网络流量等)的调度了,这个时候如果经费允许的话,会采取的方案是购 买硬件负载,例如F5、Netsclar、Athelon之类的,如经费不允许的话,会采取的方案是将应用从逻辑上做一定的分类,然后分散到不同的软负载集群中;
2、原有的一些状态信息同步、文件共享等方案可能会出现瓶颈,需要进行改进,也许这个时候会根据情况编写符合网站业务需求的分布式文件系统等;
在做完这些工作后,开始进入一个看似完美的无限伸缩的时代,当网站流量增加时,应对的解决方案就是不断的添加webserver。

看看这一步完成后系统的图示:


这一步涉及到了这些知识体系:

到了这一步,随着机器数的不断增长、数据量的不断增长和对系统可用性的要求越来越高,这个时候要求对所采用的技术都要有更为深入的理解,并需要根据网站的需求来做更加定制性质的产品。

架构演变第九步:数据读写分离和廉价存储方案

突然有一天,发现这个完美的时代也要结束了,数据库的噩梦又一次出现在眼前了,由于添加的webserver太多了,导致数据库连接的资源还是不够用,而这个时候又已经分库分表了,开始分析数据库的压力状况,可能会发现数据库的读写比很高,这个时候通常会想到数据读写分离的方案,当然,这个方案要实现并不 容易,另外,可能会发现一些数据存储在数据库上有些浪费,或者说过于占用数据库资源,因此在这个阶段可能会形成的架构演变是实现数据读写分离,同时编写一些更为廉价的存储方案,例如BigTable这种。

看看这一步完成后系统的图示:

 


这一步涉及到了这些知识体系:

数据读写分离要求对数据库的复制、standby等策略有深入的掌握和理解,同时会要求具备自行实现的技术;

廉价存储方案要求对OS的文件存储有深入的掌握和理解,同时要求对采用的语言在文件这块的实现有深入的掌握。

架构演变第十步:进入大型分布式应用时代和廉价服务器群梦想时代

经过上面这个漫长而痛苦的过程,终于是再度迎来了完美的时代,不断的增加webserver就可以支撑越来越高的访问量了,对于大型网站而言,人气的重要毋 庸置疑,随着人气的越来越高,各种各样的功能需求也开始爆发性的增长,这个时候突然发现,原来部署在webserver上的那个web应用已经非常庞大 了,当多个团队都开始对其进行改动时,可真是相当的不方便,复用性也相当糟糕,基本是每个团队都做了或多或少重复的事情,而且部署和维护也是相当的麻烦, 因为庞大的应用包在N台机器上复制、启动都需要耗费不少的时间,出问题的时候也不是很好查,另外一个更糟糕的状况是很有可能会出现某个应用上的bug就导 致了全站都不可用,还有其他的像调优不好操作(因为机器上部署的应用什么都要做,根本就无法进行针对性的调优)等因素,根据这样的分析,开始痛下决心,将 系统根据职责进行拆分,于是一个大型的分布式应用就诞生了,通常,这个步骤需要耗费相当长的时间,因为会碰到很多的挑战:
1、拆成分布式后需要提供一个高性能、稳定的通信框架,并且需要支持多种不同的通信和远程调用方式;
2、将一个庞大的应用拆分需要耗费很长的时间,需要进行业务的整理和系统依赖关系的控制等;
3、如何运维(依赖管理、运行状况管理、错误追踪、调优、监控和报警等)好这个庞大的分布式应用。
经过这一步,差不多系统的架构进入相对稳定的阶段,同时也能开始采用大量的廉价机器来支撑着巨大的访问量和数据量,结合这套架构以及这么多次演变过程吸取的经验来采用其他各种各样的方法来支撑着越来越高的访问量。

看看这一步完成后系统的图示:


这一步涉及到了这些知识体系:

这一步涉及的知识体系非常的多,要求对通信、远程调用、消息机制等有深入的理解和掌握,要求的都是从理论、硬件级、操作系统级以及所采用的语言的实现都有清楚的理解。

运维这块涉及的知识体系也非常的多,多数情况下需要掌握分布式并行计算、报表、监控技术以及规则策略等等。

说起来确实不怎么费力,整个网站架构的经典演变过程都和上面比较的类似,当然,每步采取的方案,演变的步骤有可能有不同,另外,由于网站的业务不同,会有不同的专业技术的需求,这篇blog更多的是从架构的角度来讲解演变的过程,当然,其中还有很多的技术也未在此提及,像数据库集群、数据挖掘、搜索等,但在真实的演变过程中还会借助像提升硬件配置、网络环境、改造操作系统、CDN镜像等来支撑更大的流量,因此在真实的发展过程中还会有很多的不同,另外一个大型网站要做到的远远不仅仅上面这些,还有像安全、运维、运营、服务、存储等,要做好一个大型的网站真的很不容易,写这篇文章更多的是希望能够引出更多大型网站架构演变的介绍。

原文链接:http://www.blogjava.net/BlueDavy/archive/2008/09/03/226749.html

Reply all
Reply to author
Forward
0 new messages