知名网站的技术实现

发表于:2013-04-10来源:homeAboutPhotosBlueDavy之技术b作者:bluedavy点击数: 标签:软件测试
在上一篇《知名网站的技术发展历程》中,介绍了一些知名网站在发展的过程中技术的演变,在这篇文章中则会根据这些网站的发展经验,来总结通常网站是如何来应对可伸缩性、可用性、高性能以及低成本这四方面的挑战的。

  在上一篇《知名网站的技术发展历程》中,介绍了一些知名网站在发展的过程中技术的演变,在这篇文章中则会根据这些网站的发展经验,来总结通常网站是如何来应对可伸缩性、可用性、高性能以及低成本这四方面的挑战的。

  在上一篇文章中,介绍了一些Alexa排名较前的网站的技术发展历程,在这篇文章中,将结合提及到的网站的技术发展历程,来总结下网站在可伸缩性、可用性、高性能以及低成本四点上通常采用的技术。

  对于一个网站而言,最重要的是要支撑住不断增长的访问量和数据量,如果能做到简单的增加机器即可支撑,那自然是最好的,但这就要求技术上必须付出一定的努力,这也是网站都追求的可伸缩性(Scalability),而在做到可伸缩性后,不断增加的机器也带来了成本的上升,因此发展到了一定规模后,成本也会成为关注的重点。

  除了可伸缩性外,可用性对于各网站而言也非常重要,一个经常不能使用的网站必被用户抛弃,这也是为什么各网站都很强调全年的可用性。

  除了上面这三点外,还有另外一点影响也很明显,就是性能,美国的一个对网站访问速度的调查数据:1/4的用户因为一个网站载入的时间超过4秒而放弃这个网站,50%的手机用户会放弃一个超过10秒还没载入完成的网站,其中的3/5用户将不再光顾这个网站,而Google对其数据分析后,发现搜索结果只要慢1/4秒,一天的搜索量就要减少800万。

  可伸缩

  可伸缩分为垂直伸缩和水平伸缩,垂直伸缩为通过升级机器的硬件来解决问题,水平伸缩为通过增加机器来解决问题,不同网站在可伸缩上采用了不同的策略,例如Google完全依赖水平伸缩来解决问题,而其他网站多数是先依赖垂直伸缩来解决数据存储的问题。

  垂直伸缩要求的是软件上要能在硬件升级的情况下,发挥出硬件的能力,例如可配置的并行数、内存等,硬件的发展速度非常迅猛,网站的机器的配置自然也是每年都在升级,因此其实我们的软件时刻都在被检验是否能垂直伸缩。

  水平伸缩主要要解决的是如何做到仅通过增加机器就解决问题,主要又分成了应用层和存储层两个层次来解决。

  在应用层要做到水平伸缩,通常采用的策略是Share Nothing/Stateless,状态信息放入客户端或存储层(例如用户的Session信息放入Cookie,或放入服务器端的缓存系统),应用系统做到了无状态,那么在访问量上涨后只需要增加机器即可,在应用系统由单台增加到多台组成Cluster时,这时就会有负载均衡的引入,可能是硬件的也可能是软件的。

  在应用层的结构演变上,我们会发现,随着网站的不断发展,以上提到的各家网站在应用层上最后形成的结构几乎都完全一样,均为前端Web系统Cluster + Services Cluster,前端Web系统和Services到了一定的阶段后通常又会按照一定的规则来进行拆分,如按业务领域等,可见SOA其实在大网站中是落地了的,而不像企业领域中宣传的那么虚。

  在存储层要做到水平伸缩,难度就比应用层大多了,从前面各家网站的发展历程也可看出,很多时候都在解决存储层的问题,而且可以看出,很多网站由于业务发展的压力较大,一开始都会选择采用垂直伸缩的方式来解决存储层的问题。

  存储层主要是Cache、文件和数据三种类型。

  Cache可以看到基本上各家网站都采用了Memcache来保证伸缩性,在规模大了,也会碰到一些问题,具体可以看看facebook所做的改造,现在也有些网站开始采用redis了,但redis本身不具备可伸缩性,需要自行进行改造。

  文件的存储可以看到各家网站都采用了分布式文件系统来保证伸缩性,思路多数都源于GFS,但由于存储的文件的大小不同、对响应时间和吞吐量的要求不同,各家网站可能都各自实现。

  数据的存储上可以看到各家网站基本都采用了分库分表的策略,分库分表后由于很多关系型数据库的特性(例如自增ID、join、事务等)都难以再使用了,对应用的设计会带来一些挑战,不过最大难点还是在于需要根据业务来考虑如何分是合适的,在最近几年也有一些网站开始采用NoSQL来更好的做到数据存储的可伸缩性。

  存储层为了做到可伸缩性,通常采用的方案是单点写(是指在某个粒度的单点,例如对HBase而言,是单行数据一定是在同一台机器上进行写操作),但读可能是多点,读多点的话主要要考虑不一致的问题,无论读是单点还是多点,数据都会在软件层面做到写多份,策略主要有同步写多份、投票写多份、异步复制最终一致等(例如HDFS、Cassandra、Zookeeper),采用自动分裂的方法来实现数据量增长时的自动伸缩,采用一致性hash或根据某种规则的自动balance策略等来实现机器增减时的相应处理,同时也需要有感知机器增减的方法(例如采用zookeeper)。

  从上面可以看到存储层上要做到可伸缩,技术上的难点很多,这也是为什么大规模的网站都不在数据库上做复杂的运算,而只是把其当做一种存储来使用,例如存储过程这种就更是基本不会出现了,以降低数据库的压力。

  除了应用层和存储层需要做到可伸缩外,硬件层面的可伸缩在设计系统时也是需要考虑的,例如硬件负载设备只能支撑到一定的流量,同样也需要考虑如何让其能够可伸缩。

  除了尽可能做到系统可伸缩外,减少对系统的压力也是缓解系统的可伸缩面临挑战的方法,例如批量提交、最终一致、youtube提到的“欺骗”、适当的正确性等策略。

  可伸缩性是网站从小到大要经历的第一关挑战,而且随着网站的不断发展,还要不断的做技术改造才能保证网站在每个不同的阶段(例如同机房阶段、同城多机房阶段、异地多机房阶段)都具备优秀的可伸缩性,不过幸运的是不同阶段的可伸缩性方案都已经比较成熟。

  可用性

  可伸缩性保证了网站在不断增长的访问量和数据量的情况下生存下来,这也一定程度保证了网站的可用性,但除了这点外,要保障系统的可用性,还得付出很多的努力。

  在设计高可用性的系统时,避免单点是其中最重要的一点,通常采用主备和集群的方法来避免单点,例如负载均衡设备、MySQL等通常采用主备的方式,在BigTable里采取了一种比较特殊的方法来避免Tablet Server的单点:通过Chubby来感知Tablet Server的健康状况,如发现Tablet Server挂掉了,则由Master将此Tablet Server负责的Tablet迁移到其他的Tablet Servers上。

原文转自:http://bluedavy.me/?p=396