作者:夏天的森林

出处:cnblogs.com/sharpxiajun/p/4237704.html

一,题记

前不久公司请来了位互联网界的技术大牛跟我们做了一次大型网站架构的培训,两天12个小时信息量非常大,知识的广度和难度也非常大,培训完后我很难完整理出全部听到的知识,今天我换了个思路是回味这次培训,这个思路就是通过本人目前的经验和技术水平来思考下大型网站技术演进的过程。

二,什么网站是大型网站

首先我们要思考一个问题,什么样的网站才是大型网站,从网站的技术指标角度考虑这个问题人们很容易犯一个毛病就是认为网站的访问量是衡量的指标,懂点行的人也许会认为是网站在单位时间里的并发量的大小来作为指标,如果按这些标准那么像hao123这样的网站就是大型网站了,如下图所示:

其实这种网站访问量非常大,并发数也非常高,但是它却能用最为简单的web技术来实现:我们只要保持网站的充分的静态化,多部署几台服务器,那么就算地球上所有人都用它,网站也能正常运行。

我觉得大型网站是技术和业务的结合,一个满足某些用户需求的网站只要技术和业务二者有一方难度很大,必然会让企业投入更多的、更优秀的人力成本实现它,那么这样的网站就是所谓的大型网站了。

三,初建的网站

一个初建的网站往往用户群都是很小的,最简单的网站架构就能解决实际的用户需求,当然为了保证网站的稳定性和安全性,我们会把网站的应用部署到至少两台机器上,后台的存储使用数据库,如果经济实力允许,数据库使用单台服务器部署,由于数据是网站的生命线,因此我们常常会把部署数据库的服务器使用的好点,这个网站结构如下所示:

这个结构非常简单,其实大部分初建网站开发里往往业务逻辑没有企业级系统那么复杂,所以只要有个好的idea,建设一个新网站的成本是非常低的,所使用的技术手段也是非常的基本和简单,不过该图我们要准备三台服务器,而且还要租个机房放置我们的服务器,这些成本对于草根和屌丝还是非常高的。

幸运的是当下很多大公司和机构提供了云平台,我们可以花费很少的钱将自己的应用部署到云平台上,这种做法我们甚至不用去考虑把应用、数据库分开部署的问题,更加进一步的降低了网站开发和运维的成本,但是这种做法也有一个问题,就是网站的小命被这个云平台捏住了,如果云平台挂了,俺们的网站服务也就跟着挂了。

四,网站遇到的问题

这里我先讲讲自己独立使用服务器部署网站的问题,如果我们要把网站服务应用使用多台服务器部署,这么做的目的一般有两个:

  1. 保证网站的可用性,多台服务器部署应用,那么其中一些服务器挂掉了,只要网站还有服务器能正常运转,那么网站对外任然可以正常提供服务。

  2. 提高网站的并发量,服务器越多那么网站能够服务的用户,单位时间内能承载的请求数也就越大。

  

不过要做到以上两点,并不是我们简单将网站分开部署就可以满足的,因为大多数网站在用户使用时候都是要保持用户的状态,具体点就是网站要记住请求是归属到那一个客户端,而这个状态在网站开发里就是通过会话session来体现的。

分开部署的web应用服务要解决的一个首要问题就是要保持不同物理部署服务器之间的session同步问题,从而达到当用户第一次请求访问到服务器A,第二个请求访问到服务器B,网站任然知道这两个请求是同一个人,解决方案很直接:服务器A和服务器B上的session信息要时刻保持同步,那么如何保证两台服务器之间session信息的同步呢?

为了回答上面的问题,我们首先要理解下session的机制,session信息在web容器里都是存储在内存里的,web容器会给每个连接它的客户端生成一个sessionid值,这个sessionid值会被web容器置于http协议里的cookie域下,当响应被客户端处理后,客户端本地会存储这个sessionid值,用户以后的每个请求都会让这个sessionid值随cookie一起传递到服务器,服务器通过sessionid找到内存中存储的该用户的session内容,session在内存的数据结构是一个map的格式。

五,服务器越多,并发数反而越慢

那么为了保证不同服务器之间的session共享,那么最直接的方案就是让服务器之间session不断的传递和复制,例如java开发里常用的tomcat容器就采用这种方案,以前我测试过tomcat这种session同步的性能,我发现当需要同步的web容器越多,web应用所能承载的并发数并没有因为服务器的增加而线性提升,当服务器数量达到一个临界值后,整个web应用的并发数甚至还会下降,为什么会这样了?

原因很简单,不同服务器之间session的传递和复制会消耗服务器本身的系统资源,当服务器数量越大,消耗的资源越多,当用户请求越频繁,系统消耗资源也会越来越大。如果我们多部署服务器的目的只是想保证系统的稳定性,采用这种方案还是不错的,不过web应用最好部署少点,这样才不会影响到web应用的性能问题,如果我们还想提升网站的并发量那么就得采取其他的方案了。

时下使用的比较多的方案就是使用独立的缓存服务器,也就是将session的数据存储在一台独立的服务器上,如果觉得存在一台服务器不安全,那么可以使用memcached这样的分布式缓存服务器进行存储,这样既可以满足了网站稳定性问题也提升了网站的并发能力。

不过早期的淘宝在这个问题解决更加巧妙,他们将session的信息直接存储到浏览器的cookie里,每次请求cookie信息都会随着http一起传递到web服务器,这样就避免了web服务器之间session信息同步的问题,这种方案会让很多人诟病,诟病的原因是cookie的不安全性是总所周知的,如果有人恶意截取cookie信息那么网站不就不安全了吗?这个答案还真不好说,但是我觉得我们仅仅是跟踪用户的状态,把session存在cookie里其实也没什么大不了的。

其实如此专业的淘宝这么做其实还是很有深意的,还记得本文开篇提到的hao123网站,它是可以承载高并发的网站,它之所以可以做到这一点,原因很简单它是个静态网站,静态网站的特点就是不需要记录用户的状态,静态网站的服务器不需要使用宝贵的系统资源来存储大量的session会话信息,这样它就有更多系统资源来处理请求,而早期淘宝将cookie存在客户端也是为了达到这样的目的,所以这个方案在淘宝网站架构里还是使用了很长时间的。

在我的公司里客户端的请求到达web服务器之前,会先到F5,F5是一个用来做负载均衡的硬件设备,它的作用是将用户请求均匀的分发到后台的服务器集群,F5是硬件的负载均衡解决方案,如果我们没那么多钱买这样的设备,也有软件的负载均衡解决方案,这个方案就是大名鼎鼎的LVS了!

这些负载均衡设备除了可以分发请求外它们还有个能力,这个能力是根据http协议的特点设计的,一个http请求从客户端到达最终的存储服务器之前可能会经过很多不同的设备,如果我们把一个请求比作高速公路上的一辆汽车,这些设备也可以叫做这些节点就是高速路上的收费站,这些收费站都能根据自己的需求改变http报文的内容,所以负载均衡设备可以记住每个sessionid值对应的后台服务器。

当一个带有sessionid值的请求通过负载均衡设备时候,负载均衡设备会根据该sessionid值直接找到指定的web服务器,这种做法有个专有名词就是session粘滞,这种做法也比那种session信息在不同服务器之间拷贝复制要高效,不过该做法还是比存cookie的效率低下,而且对于网站的稳定性也有一定影响即如果某台服务器挂掉了,那么连接到该服务器的用户的会话都会失效。

解决session的问题的本质也就是解决session的存储问题,其本质也就是解决网站的存储问题,一个初建的网站在早期的运营期需要解决的问题基本都是由存储导致的。上文里我提到时下很多新建的web应用会将服务器部署后云平台里,好的云平台里或许会帮助我们解决负载均衡和session同步的问题,但是云平台里有个问题很难解决那就是数据库的存储问题,如果我们使用的云平台发生了重大事故,导致云平台存储的数据丢失,这种会不会导致我们在云平台里数据库的信息也会丢失了,虽然这个事情的概率不高,但是发生这种事情的几率还是有的,虽然很多云平台都声称自己多么可靠,但是真实可靠性有多高不是局中人还真不清楚哦,因此使用云平台我们首要考虑的就是要做好数据备份,假如真发生了数据丢失,对于一个快速成长的网站而言可能非常致命。

六,网站的瓶颈

写到这里一个婴儿般的网站就这样被我们创造出来了,我们希望网站能健康快速的成长,如果网站真的按我们预期成长了,那么一定会有一天我们制造的宝宝屋已经满足不了现实的需求,这个时候我们应该如何抉择了?换掉,全部换掉,使用新的架构例如我们以前长提的SOA架构,分布式技术,这个方法不错,但是SOA和分布式技术是很难的,成本是很高的,如果这时候我们通过添加几台服务器就能解决问题的话,我们绝对不要去选择什么分布式技术,因为这个成本太高了。上面我讲到几种session共享的方案,这个方案解决了应用的水平扩展问题,那么当我们网站出现瓶颈时候就多加几台服务器不就行了吗?那么这里就有个问题了,当网站成长很快,网站首先碰到的瓶颈到底是哪个方面的问题?

本人是做金融网站的,我们所做的网站有个特点就是当用户访问到我们所做的网站时候,目的都很明确就是为了付钱,用户到了我们所做的网站时候都希望能快点,再快点完成本网站的操作,很多用户在使用我们做的网站时候不太去关心网站的其他内容,因此我们所做的网站相对于数据库而言就是读写比例其实非常的均匀,甚至很多场景写比读要高,这个特点是很多专业服务网站的特点,其实这样的网站和企业开发的特点很类似:业务操作的重要度超过了业务展示的重要度,因此专业性网站吸纳企业系统开发的特点比较多。但是大部分我们日常常用的网站,我们逗留时间很长的网站按数据库角度而言往往是读远远大于写,例如大众点评网站它的读写比率往往是9比1。

12306或许是中国最著名的网站之一,我记得12306早期经常出现一个问题就是用户登录老是登不上,甚至在高峰期整个网站挂掉,页面显示503网站拒绝访问的问题,这个现象很好理解就是网站并发高了,大量人去登录网站,购票,系统挂掉了,最后所有的人都不能使用网站了。

当网站出现503拒绝访问时候,那么这个网站就出现了最致命的问题,解决大用户访问的确是个超级难题,但是当高并发无法避免时候,整个网站都不能使用这个只能说网站设计上发生了致命错误,一个好的网站设计在应对超出自己能力的并发时候我们首先应该是不让他挂掉,因为这种结果是谁都不能使用,我们希望那些在可接受的请求下,让在可接受请求范围内的请求还是可以正常使用,超出的请求可以被拒绝,但是它们绝对不能影响到全网站的稳定性,现在我们看到了12306网站的峰值从未减少过,而且是越变越多,但是12306出现全站挂掉的问题是越来越少了。通过12036网站改变我们更进一步思考下网站的瓶颈问题。

排除一些不可控的因素,网站在高并发下挂掉的原因90%都是因为数据库不堪重负所致,而应用的瓶颈往往只有在解决了存储瓶颈后才会暴露,那么我们要升级网站能力的第一步工作就是提升数据库的承载能力,对于读远大于写的网站我们采取的方式就是将数据库从读写这个角度拆分,具体操作就是将数据库读写分离,如下图所示:

我们这时要设计两个数据库,一个数据库主要负责写操作我们称之为主库,一个数据库专门负责读操作我们称之为副库,副库的数据都是从主库导入的,数据库的读写分离可以有效的保证关键数据的安全性,但是有个缺点就是当用户浏览数据时候,读的数据都会有点延时,这种延时比起全站不可用那肯定是可以接受的。

不过针对12306的场景,仅仅读写分离还是远远不够的,特别是负责读操作的副库,在高访问下也是很容易达到性能的瓶颈的,那么我们就得使用新的解决方案:使用分布式缓存,不过缓存的缺点就是不能有效的实时更新,因此我们使用缓存前首先要对读操作的数据进行分类,对于那些经常不发生变化的数据可以事先存放到缓存里,缓存的访问效率很高,这样会让读更加高效,同时也减轻了数据库的访问压力。

至于用于写操作的主库,因为大部分网站读写的比例是严重失衡,所以让主库达到瓶颈还是比较难的,不过主库也有一个读的压力就是主库和副库的数据同步问题,不过同步时候数据都是批量操作,而不是像请求那样进行少量数据读取操作,读取操作特别多,因此想达到瓶颈还是有一定的难度的。听人说,美国牛逼的facebook对数据的任何操作都是事先合并为批量操作,从而达到减轻数据库压力的目的。

七,海量数据检索

上面的方案我们可以保证在高并发下网站的稳定性,但是针对于读,如果数据量太大了,就算网站不挂掉了,用户能很快的在海量数据里检索到所需要的信息又成为了网站的一个瓶颈,如果用户需要很长时间才能获得自己想要的数据,很多用户会失去耐心从而放弃对网站的使用,那么这个问题又该如何解决了?

解决方案就是我们经常使用的百度,谷歌哪里得来,对于海量数据的读我们可以采用搜索技术,我们可以将数据库的数据导出到文件里,对文件建立索引,使用倒排索引技术来检索信息,我们看到了百度,谷歌有整个互联网的信息我们任然能很快的检索到数据,搜索技术是解决快速读取数据的一个有效方案,不过这个读取还是和数据库的读取有所区别的,如果用户查询的数据是通过数据库的主键字段,或者是通过很明确的建立了索引的字段来检索,那么数据库的查询效率是很高的,但是使用网站的人跟喜欢使用一些模糊查询来查找自己的信息,那么这个操作在数据库里就是个like操作,like操作在数据库里效率是很低的,这个时候使用搜索技术的优势就非常明显了,搜索技术非常适合于模糊查询操作。

推荐阅读:

技术:分布式唯一ID极简教程

职场:程序员职业规划

分享:2T架构师学习资料干货分享

觉得有帮助?请转发给更多人!

架构师小秘圈,聚集10万架构师的小圈子!不定期分享技术干货,行业秘闻!汇集各类奇妙好玩的话题和流行动向!长按左侧图片,扫码加入架构师微信群!

存储的瓶颈--大型网站技术演进思考相关推荐

  1. 关于大型网站技术演进的思考--存储的瓶颈

    (一)第一部分 前不久公司请来了位互联网界的技术大牛跟我们做了一次大型网站架构的培训,两天12个小时信息量非常大,知识的广度和难度也非常大,培训完后我很难完整理出全部听到的知识,今天我换了个思路是回味 ...

  2. 关于大型网站技术演进的思考

    关于大型网站技术演进的思考(一)--存储的瓶颈(1) 前不久公司请来了位互联网界的技术大牛跟我们做了一次大型网站架构的培训,两天12个小时信息量非常大,知识的广度和难度也非常大,培训完后我很难完整理出 ...

  3. 关于大型网站技术演进的思考--网站静态化处理

    转自: 夏天的森林blog:(系统设计与架构(47)) 一 在存储瓶颈的开篇我提到像hao123这样的导航网站只要它部署的web服务器数量足够,它可以承载超大 规模的并发访问量,如果是一个动态的网站, ...

  4. 关于大型网站技术演进的思考(十六)--网站静态化处理—前后端分离—下(8)

    出处:夏天的森林博客 我第一次听说nodejs技术大概是在2009年年末,不过我真正认真在网络上进一步了解nodejs还是在2010年年中,当时对nodejs的认识和我现在对nodejs的认识有着天壤 ...

  5. 关于大型网站技术演进的思考(五)--存储的瓶颈(5)

    上文里我遗留了两个问题,一个问题是数据库做了水平拆分以后,如果我们对主键的设计采取一种均匀分布的策略,那么它对于被水平拆分出的表后续的查询操作将有何种影响,第二个问题就是水平拆分的扩容问题.这两个问题 ...

  6. 关于大型网站技术演进的思考(一)--存储的瓶颈(上)

    首先我们要思考一个问题,什么样的网站才是大型网站,从网站的技术指标角度考虑这个问题人们很容易犯一个毛病就是认为网站的访问量是衡量的指标,懂点行的人也许会认为是网站在单位时间里的并发量的大小来作为指标, ...

  7. 关于大型网站技术演进的思考(二)--存储的瓶颈(2)

    上篇里我讲到某些网站在高并发下会报出503错误,503错误的含义是指网站服务端暂 时无法提供服务的含义,503还表达了网站服务端现在有问题但是以后可能会提供正常的服务,对http协议熟悉的人都知道,5 ...

  8. 关于大型网站技术演进的思考(七)--存储的瓶颈(7)

    本文开篇提个问题给大家,关系数据库的瓶颈有哪些?我想有些朋友看到这个问题肯定会说出自己平时开发中碰到了一个跟数据库有关的什么什么问题,然后如何解决的等等,这样的答案没问题,但是却没有代表性,如果出现了 ...

  9. 关于大型网站技术演进的思考(三)--存储的瓶颈(3)

    存储的瓶颈写到现在就要进入到深水区了,如果我们所做的网站已经到了做数据库垂直拆分和水平拆分的阶段,那么此时我们所面临的技术难度的挑战也会大大增强. 这里我们先回顾下数据库的垂直拆分和水平拆分的定义: ...

最新文章

  1. 他开发了基因界的百科全书,贡献却少有人知
  2. 九、序列参数集Sequence Paramater Set(SPS)解析
  3. Cisco设备静态NAT基本配置步骤
  4. 了解CUDA计算(一)
  5. 提高抗打击能力_输不起、爱放弃,孩子抗挫能力差怎么办?3招教你培养孩子抗挫力...
  6. 尚展垒等编著c语言程序设计,C语言程序设计技术实践指导
  7. kali查看共享 linux_在Linux下访问Windows共享文件夹
  8. JS 学习笔记--11---内置对象(Global/Math)
  9. LeetCode 6062. 设计一个 ATM 机器
  10. Flask之Flask实例有哪些参数
  11. Setting property 'source' to 'org.eclipse.jst.jee.server
  12. .NET平台常用的框架整理
  13. 《码出高效---java》PDF,有学习java的小伙伴可以看看,阿里巴巴出版的书籍
  14. 高效记忆/形象记忆(10)110数字编码表 41-50
  15. hadoop测试环境完全分布式安装配置
  16. 国内外神经网络研究现状,神经网络的发展现状
  17. liquibase的changelog详解
  18. [陕师大校赛] A 正正的毒奶粉
  19. 【Python案例】基于Pygame黑白棋游戏(附源码)
  20. 谷歌翻译插件imtranslator安装使用步骤

热门文章

  1. P5667 拉格朗日插值2(拉格朗日插值,NTT, 倒推求逆元)
  2. P4735 最大异或和(可持久化trie树、求最大区间异或和)
  3. 【图论专题】无向图的双连通分量
  4. 时间复杂度,O(1), O(n), O(logn), O(nlogn) 的区别+样例分析
  5. android饼状图简书,Charts-饼状图
  6. c++ 调用labview_LabVIEW面向对象编程_初窥门径(5):开发方式漫谈
  7. Mysql中分页查询两个方法比较
  8. 道医秘传,开通奇经八脉法!
  9. Windows command tools
  10. 思科:全球近75%的物联网项目失败