上篇里我讲到某些网站在高并发下会报出503错误,503错误的含义是指网站服务端暂 时没法提供服务的含义,503还表达了网站服务端如今有问题可是之后可能会提供正常的服务,对http协议熟悉的人都知道,5开头的响应码表达了服务端出 现了问题,在咱们开发测试时候最为常见的是500错误,500表明的含义是服务端程序出现了错误致使网站没法正常提供服务,500一般是服务端异常和错误 所致,若是生产系统里发现了500错误,那么只能说明网站存在逻辑性的错误,这每每是系统上线前的测试作的不到位所致。回到503错误,我上文解释为拒绝 访问,其实更加准确的回答应该是服务不可用,那么为何我会说503错误在高并发的状况下90%的缘由是数据库所致呢?上文我作出了详细的解释,可是今天 我回味了一下,发现那个解释还不是太突出重点,问题的重点是在高并发的状况整个网站系统首先暴露出问题的是数据库,若是咱们把整个网站系统比做一个盛水的木桶,那么木桶最短的那个板就是数据库了,通常而言网站的服务应用出问题都会是解决存储问题以后才会出现。web
数据库出现了瓶颈并非程序存在逻辑性错误,数据库瓶颈的表现就是数据库由于承受了太多的访问后,数据库没法迅速的作出响应,严重时候数据库会拒绝进一 步操做死锁在哪里不能作出任何反应。数据库犹如一把巨型的大锁,不少人争抢这个锁时候会致使这个大锁彻底被锁死,最终请求的处理就停留在这个大锁上最终导 致网站提示出503错误,503错误最终会传递到全部的客户端上,最终的现象就是全站不可用了。算法
上文里我讲到session共享的一个方案是将session数据存储在外部一个独立的缓存服务器里,我开始说用一台服务器作缓存服务器,后面提到若是 以为一台服务器作缓存不安全,那么采用分布式缓存服务器例如memcached,那么这里就有一个问题了,为了保证web服务的可用性,咱们会把web服 务分开部署到不一样的服务器上,这些服务器都是对等关系,其中一台服务器不能正常提供服务不会影响到整个网站的稳定性,那么咱们采起memcached集群 是否是能够达到一样的效果了?即缓存服务器集群中一台服务器挂掉,不会影响到用户对网站的使用了?问题的结果是使人失望了,假如咱们使用两台服务器作缓存 服务器来存储session信息,那么若是其中一台服务器挂掉了,那么网站将会有一半的用户将不能正常使用网站,缘由是他们的session信息丢失了, 网站没法正常的跟踪用户的会话状态。我之因此提到这个问题是想告诉你们以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能够服务器宕机时候这台服务器对整个缓存数据的影响最小。服务器
上文里我讲到了读写分离的设计方案,而读写分离方案主要是应用于网站读写比例严重失衡的网站,而互联网上绝大部分网站都是读操做的比例远远大于写操做,这 是网站的主流,若是一个网站读写比例比较均衡,那么这个网站通常都是提供专业服务的网站,这种网站对于我的而言是一个提供生活便利的工具,它们和企业软件 相似。大部分关注大型网站架构技术关心的重点应该是那种对于读写比例失衡的网站,由于它们作起来更加有挑战性。session
将数据库进行读写分离是网站解决存储瓶颈的第一步,为何说是第一步呢?由于读写分离从业务角度而言它是一种粗粒度的数据拆分,所以它所包含的业务复杂度 比较低,容易操做和被掌控,从技术而言,实现手段也相对简单,所以读写分离是一种低成本解决存储瓶颈的一种手段,这种方案是一种改良方案而不是革命性的的 方案,不论是从难度,仍是影响范围或者是经济成本角度考虑都是很容易让相关方接受的。架构
那么咱们仅仅将数据库作读写分离为什么能产生好的效率了?回答这个问题咱们首先要了解下硬盘的机制,硬盘的物理机制就有一个大圆盘飞速旋转,而后有个磁头不 断扫描这个大圆盘,这样的物理机制就会致使硬盘数据的顺序操做比随机操做效率更高,这点对于硬盘的读和写还算公平,可是写操做在高并发状况下会有点复杂, 写操做有个特性就是咱们要保证写操做的准确性,可是高并发下可能会出现多个用户同时修改某一条数据,为了保证数据能被准确的修改,那么咱们一般要把并行的操做转变为串行操做, 这个时候就会出现一个锁机制,锁机制的实现是很复杂的,它会消耗不少系统性能,若是写操做掺杂了读操做状况就更复杂,效率会更加低效,相对于写操做读操做 就单纯多了,若是咱们的数据只有读操做,那么读的性能也就是硬盘顺序读能力和随机读能力的体现,即便掺杂了并发也不会对其有很大的影响,所以若是把读操做 和写操做分离,效率天然会获得很大提高。并发
既然读写分离能够提高存储系统的效率,那么为何咱们又要引入缓存系统和搜索技术了?缓存将数据存在内存中,内存效率是硬盘的几万倍,这样的好处不言而 喻,而选择搜索技术的背后的原理就不一样了,数据库存储的数据称之为结构化数据,结构化数据的限制不少,当结构化数据遇到了变幻无穷的随机访问时候,其效率 会变得异常低效,可是若是一个网站不能提供灵活、高效的随机访问能力,那么这个网站就会变得单板没有活力,例如咱们在淘宝里查找咱们想要的商品,可是时常 咱们并不清楚本身到底想买啥,若是是在实体店里店员会引导咱们的消费,可是网站又如何引导咱们的消费,那么咱们必需要赋予网站经过人们简单意向随机找到各 种不一样的商品,这个对于数据库就是一个like操做的,可是数据里数据量达到了必定规模之后like的低效是没法让人忍受的,这时候搜索技术在随机访问的 能力正好能够弥补数据库这块的不足。分布式
业务再接着的增加下去,数据量也会随之愈来愈大了,这样发展下去总有一天主库也会产生瓶颈了,那么接下来咱们又该如何解决主库的瓶颈了?方法很简单就是 咱们要拆分主库的数据了,那么我该以什么维度拆分数据了?一个数据库里有不少张表,不一样的表都针对不一样的业务,网站的不一样业务所带来的数据量也不是不一样 的,这个时候系统的短板就是那些数据量最大的表,因此咱们要把那些会让数据库产生瓶颈的表拆出来,例如电商系统里商品表和交易表每每数据量很是大,那么咱们能够把这两种表创建在单独的两个数据库里,这样就拆分了数据库的压力,这种作法叫作数据垂直拆分,不过垂直拆分会给原有的数据库查询,特别是有事务的相关操做产生影响,这些问题咱们必需要进行改造,关于这个问题,我将在下篇里进行讨论。
当咱们的系统作完了读写分离,数据垂直拆分后,咱们的网站还在迅猛发展,最终必定又会达到新的数据库瓶颈,固然这些瓶颈首先仍是出如今那些数据量大的表 里,这些表数据的处理已经超出了单台服务器的能力,这个时候咱们就得对这个单库单表的数据进行更进一步的拆分,也就是将一张表分布到两台不一样的数据库里,这个作法就是叫作数据的水平拆分了。
Ok,今天内容就讲到这里了,有这两篇文章咱们能够理出一个解决大型网站数据瓶颈的一个脉络了,具体以下:
单库数据库-->数据库读写分离-->缓存技术-->搜索技术-->数据的垂直拆分-->数据的水平拆分
以上的每一个技术细节在具体实现中可能存在很大的不一样,可是问题的原因大体是一致的,咱们理清这个脉络就是想告诉你们咱们若是碰到这样的问题应该按何种思路进行思考和设计解决方案,好了,今天就写到这里了,晚安。