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

503错误

  在上篇,我讲到某些网站在高并发下会报出503错误,503错误的含义是指网站服务端暂时无法提供服务,503还表达了网站服务端现在有问题,但是以后可能会提供正常的服务,对http协议熟悉的人都知道,5开头的响应码表达了服务端出现了问题,在我们开发测试时候最为常见的是500错误,500代表的含义是服务端程序出现了错误导致网站无法正常提供服务,500通常是服务端异常和错误所致,如果生产系统里发现了500错误,那么只能说明网站存在逻辑性的错误,这往往是系统上线前的测试做的不到位所致。回到503错误,我上文解释为拒绝访问,其实更加准确的回答应该是服务不可用,那么为什么我会说503错误在高并发的情况下90%的原因是数据库所致呢?

  上文我做出了详细的解释,但是今天我回味了一下,发现那个解释还不是太突出重点,问题的重点是在高并发的情况整个网站系统首先暴露出问题的是数据库,如果我们把整个网站系统比作一个盛水的木桶,那么木桶最短的那个板就是数据库了,一般而言网站的服务应用出问题都会是解决存储问题之后才会出现。

  数据库出现了瓶颈并不是程序存在逻辑性错误,数据库瓶颈的表现就是数据库因为承受了太多的访问后,数据库无法迅速的做出响应,严重时候数据库会拒绝进一步操作死锁在哪里不能做出任何反应。数据库犹如一把巨型的大锁,很多人争抢这个锁时候会导致这个大锁完全被锁死,最终请求的处理就停留在这个大锁上,最终导致网站提示出503错误,503错误最终会传递到所有的客户端上,最终的现象就是全站不可用了。

  session共享的一个方案是将session数据存储在外部一个独立的缓存服务器里,我开始说用一台服务器做缓存服务器,后面提到如果觉得一台服务器做缓存不安全,那么采用分布式缓存服务器例如memcached,那么这里就有一个问题了,为了保证Web服务的可用性,我们会把Web服务分开部署到不同的服务器上,这些服务器都是对等关系,其中一台服务器不能正常提供服务不会影响到整个网站的稳定性,那么我们采取memcached集群是不是可以达到同样的效果了?

  即缓存服务器集群中一台服务器挂掉,不会影响到用户对网站的使用了?问题的答案是令人失望了,假如我们使用两台服务器做缓存服务器来存储session信息,那么如果其中一台服务器挂掉了,那么网站将会有一半的用户将不能正常使用网站,原因是他们的session信息丢失了,网站无法正常的跟踪用户的会话状态。

  我之所以提到这个问题是想告诉大家以memcached为代表的分布式缓存和我们传统理解的分布式系统是有区别的,传统的分布式系统都会包含一个容灾维护系统稳定性的功能,但实际的分布式技术是多种多样的,例如memcached的分布式技术并不是为了解决容灾维护系统稳定性的模式设计,换个说法就是memcached集群的设计是没有过分考虑冗余的问题,而只有适当的冗余才能保证系统的健壮性问题。分布式技术的实现是千差万别的,每个优秀的分布式系统都有自身独有的特点。

  memcached技术

  全面的讲述memcached技术并非本文的主题,而且这个主题也不是一两句话能说清楚的,这里我简单的介绍下memcached实现的原理,当网站使用缓存集群时候,缓存数据是通过一定的算法将缓存数据尽量均匀分布到不同服务器上,如果用户A的缓存在服务器A上,那么服务器B上是没有该用户的缓存数据,早期的memcache数据分布式的算法是根据缓存数据的key即键值计算出一个hash值,这个hash值再除以缓存服务器的个数,得到的余数会对应某一台服务器,例如1对应服务器A,2对应服务器B,那么余数是1的key值缓存就会存储在服务器A上,这样的算法会导致某一台服务器挂掉,那么网站损失的缓存数据的占比就会比较高,为了解决这个问题,memcached引入了一致性hash算法。

  关于一致性hash网上有很多资料,这里我就贴出一个链接,本文就不做过多论述了。链接地址如下:http://blog.csdn.net/kongqz/article/details/6695417

  一致性hash可以服务器宕机时候这台服务器对整个缓存数据的影响最小。

  读/写分离方案

  上文里我讲到了读写分离的设计方案,而读写分离方案主要是应用于网站读写比例严重失衡的网站,而互联网上绝大部分网站都是读操作的比例远远大于写操作,这是网站的主流,如果一个网站读写比例比较均衡,那么这个网站一般都是提供专业服务的网站,这种网站对于个人而言是一个提供生活便利的工具,它们和企业软件类似。大部分关注大型网站架构技术关心的重点应该是那种对于读写比例失衡的网站,因为它们做起来更加有挑战性。

  将数据库进行读写分离是网站解决存储瓶颈的第一步,为什么说是第一步呢?因为读写分离从业务角度而言它是一种粗粒度的数据拆分,因此它所包含的业务复杂度比较低,容易操作和被掌控,从技术而言,实现手段也相对简单,因此读写分离是一种低成本解决存储瓶颈的一种手段,这种方案是一种改良方案而不是革命性的的方案,不管是从难度,还是影响范围或者是经济成本角度考虑都是很容易让相关方接受的。

  那么我们仅仅将数据库做读写分离为何能产生好的效率了?我们首先要了解下硬盘的机制,硬盘的物理机制就有一个大圆盘飞速旋转,然后有个磁头不断扫描这个大圆盘,这样的物理机制就会导致硬盘数据的顺序操作比随机操作效率更高,这点对于硬盘的读和写还算公平,但是写操作在高并发情况下会有点复杂,写操作有个特性就是我们要保证写操作的准确性,但是高并发下可能会出现多个用户同时修改某一条数据,为了保证数据能被准确的修改,那么我们通常要把并行的操作转变为串行操作,这个时候就会出现一个锁机制,锁机制的实现是很复杂的,它会消耗很多系统性能,如果写操作掺杂了读操作情况就更复杂,效率会更加低效,相对于写操作读操作就单纯多了,如果我们的数据只有读操作,那么读的性能也就是硬盘顺序读能力和随机读能力的体现,即使掺杂了并发也不会对其有很大的影响,因此如果把读操作和写操作分离,效率自然会得到很大提升。

  为什么要引入缓存系统和搜索技术?

  既然读写分离可以提升存储系统的效率,那么为什么我们又要引入缓存系统和搜索技术了?缓存将数据存在内存中,内存效率是硬盘的几万倍,这样的好处不言而喻,而选择搜索技术背后的原理就不同了,数据库存储的数据称之为结构化数据。

  结构化数据的限制很多,当结构化数据遇到了千变万化的随机访问时候,其效率会变得异常低效,但是如果一个网站不能提供灵活、高效的随机访问能力,那么这个网站就会变得单板没有活力。例如我们在淘宝里查找我们想要的商品,但是时常我们并不清楚自己到底想买啥,如果是在实体店里店员会引导我们的消费,但是网站又如何引导我们的消费,那么我们必须要赋予网站通过人们简单意向随机找到各种不同的商品,这个对于数据库就是一个like操作的,但是数据里数据量达到了一定规模以后like的低效是无法让人忍受的,这时候搜索技术在随机访问的能力正好可以弥补数据库这块的不足。

  拆分数据

  业务再接着的增长下去,数据量也会随之越来越大了,这样发展下去总有一天主库也会产生瓶颈了,那么接下来我们又该如何解决主库的瓶颈了?

  方法很简单就是我们要拆分主库的数据了,那么我该以什么维度拆分数据了?一个数据库里有很多张表,不同的表都针对不同的业务,网站的不同业务所带来的数据量也不是不同的,这个时候系统的短板就是那些数据量最大的表,所以我们要把那些会让数据库产生瓶颈的表拆出来,例如电商系统里商品表和交易表往往数据量非常大,那么我们可以把这两种表建立在单独的两个数据库里,这样就拆分了数据库的压力,这种做法叫做数据垂直拆分,不过垂直拆分会给原有的数据库查询,特别是有事务的相关操作产生影响,这些问题我们必须要进行改造,关于这个问题,我将在下篇里进行讨论。

  当我们的系统做完了读写分离,数据垂直拆分后,我们的网站还在迅猛发展,最终一定又会达到新的数据库瓶颈,当然这些瓶颈首先还是出现在那些数据量大的表里,这些表数据的处理已经超出了单台服务器的能力,这个时候我们就得对这个单库单表的数据进行更进一步的拆分,也就是将一张表分布到两台不同的数据库里,这个做法就是叫做数据的水平拆分了。

  这两篇文章我们可以理出一个解决大型网站数据瓶颈的一个脉络了,具体如下:

  单库数据库-->数据库读写分离-->缓存技术-->搜索技术-->数据的垂直拆分-->数据的水平拆分

  以上的每个技术细节在具体实现中可能存在很大的不同,但是问题的缘由大致是一致的,我们理清这个脉络就是想告诉大家我们如果碰到这样的问题应该按何种思路进行思考和设计解决方案。

时间: 2024-10-12 09:11:20

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

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

本文开篇提个问题给大家,关系数据库的瓶颈有哪些?我想有些朋友看到这个问题肯定会说出自己平时开发中碰到了一个跟数据库有关的什么什么问题,然后如何解决的等等,这样的答案没问题,但是却没有代表性,如果出现了一个新的存储瓶颈问题,你在那个场景的处理经验可以套用在这个新问题上吗?这个真的很难说. 其实不管什么样的问题场景最后解决它都要落实到数据库的话,那么这个问题场景一定是击中了数据库的某个痛点,那么我前面的六篇文章里那些手段到底是在解决数据库的那些痛点,下面我总结下,具体如下: 痛点一:数据库的连接数不

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

如果数据库需要进行水平拆分,这其实是一件很开心的事情,因为它代表公司的业务正在迅猛的增长,对于开发人员而言那就是有不尽的项目可以做,虽然会感觉很忙,但是人过的充实,心里也踏实. 数据库水平拆分简单说来就是先将原数据库里的一张表在做垂直拆分出来放置在单独的数据库和单独的表里后更进一步的把本来是一个整体的表进一步拆分成多张表,每一张表都用独立的数据库进行存储.当表被水平拆分后,原数据表成为了一个逻辑的概念,而这个逻辑表的业务含义需要多张物理表协同完成,因此数据库的表被水平拆分后,那么我们对这张表的操

关于大型网站技术演进的思考(转)

作者写了一个系列,很值得学习 关于大型网站技术演进的思考(一)--存储的瓶颈(1) 关于大型网站技术演进的思考(二)--存储的瓶颈(2) 关于大型网站技术演进的思考(三)--存储的瓶颈(3) 关于大型网站技术演进的思考(四)--存储的瓶颈(4) 关于大型网站技术演进的思考(五)--存储的瓶颈(5) 关于大型网站技术演进的思考(六)--存储的瓶颈(6) 后面可能还有,见博主”夏天的森林“的博客http://www.cnblogs.com/sharpxiajun/

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

关于大型网站技术演进的思考(一)--存储的瓶颈(1)  http://www.cnblogs.com/sharpxiajun/p/4237704.html#!comments

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

(一)第一部分 前不久公司请来了位互联网界的技术大牛跟我们做了一次大型网站架构的培训,两天12个小时信息量非常大,知识的广度和难度也非常大,培训完后我很难完整理出全部听到的知识,今天我换了个思路是回味这次培训,这个思路就是通过本人目前的经验和技术水平来思考下大型网站技术演进的过程. 首先我们要思考一个问题,什么样的网站才是大型网站,从网站的技术指标角度考虑这个问题人们很容易犯一个毛病就是认为网站的访问量是衡量的指标,懂点行的人也许会认为是网站在单位时间里的并发量的大小来作为指标,如果按这些标准那

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

前不久公司请来了位互联网界的技术大牛跟我们做了一次大型网站架构的培训,两天12个小时信息量非常大,知识的广度和难度也非常大,培训完后我很难完整理出全部听到的知识,今天我换了个思路是回味这次培训,这个思路就是通过本人目前的经验和技术水平来思考下大型网站技术演进的过程. 首先我们要思考一个问题,什么样的网站才是大型网站,从网站的技术指标角度考虑这个问题人们很容易犯一个毛病就是认为网站的访问量是衡量的指标,懂点行的人也许会认为是网站在单位时间里的并发量的大小来作为指标,如果按这些标准那么像hao123

【转】关于大型网站技术演进的思考(一)--存储的瓶颈(1)

前不久公司请来了位互联网界的技术大牛跟我们做了一次大型网站架构的培训,两天12个小时信息量非常大,知识的广度和难度也非常大,培训完后我很难完整理出全部听到的知识,今天我换了个思路是回味这次培训,这个思路就是通过本人目前的经验和技术水平来思考下大型网站技术演进的过程. 首先我们要思考一个问题,什么样的网站才是大型网站,从网站的技术指标角度考虑这个问题人们很容易犯一个毛病就是认为网站的访问量是衡量的指标,懂点行的人也许会认为是网站在单位时间里的并发量的大小来作为指标,如果按这些标准那么像hao123

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

我第一次听说nodejs技术大概是在2009年年末,不过我真正认真在网络上进一步了解nodejs还是在2010年年中,当时对nodejs的认识和我现在对nodejs的认识有着天壤的区别,开始想了解nodejs我只是为了感慨谷歌公司开发的V8引擎居然如此强大,它不仅仅可以作为chrome浏览器的javascript内核运行平台,居然还能为服务端使用javascript语言作为平台,通过对nodejs的了解让我认识到chrome浏览器是如此的优秀,但是如此相对的是我并不认为javascript作为服

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

我第一次听说nodejs技术大概是在2009年年末,不过我真正认真在网络上进一步了解nodejs还是在2010年年中,当时对nodejs的认识和我现在对nodejs的认识有着天壤的区别,开始想了解nodejs我只是为了感慨谷歌公司开发的V8引擎居然如此强大,它不仅仅可以作为chrome浏览器的javascript内核运行平台,居然还能为服务端使用javascript语言作为平台,通过对nodejs的了解让我认识到chrome浏览器是如此的优秀,但是如此相对的是我并不认为javascript作为服