大型网站架构之系列——死了都要说的缓存&分布式中的异步通信

来源:互联网 发布:程序员如何年薪百万 编辑:程序博客网 时间:2024/05/01 01:15

  说到缓存,我想大家跟我一样都很兴奋,当我们遭遇网站性能瓶颈的时候,缓存是一剂强心针,也是一粒紧急妈富隆,从而在优化网站

性能方面冠上了第一定律的帽子,我们前年在做淘应用的时候,就遭遇了性能瓶颈,短时间内采用缓存紧急优化,给我们大优化之前争取了

宝贵的时间。

 

一:缓存的种类

     要说缓存有多少种,太多了,比如浏览器缓存,文件缓存,片段缓存,数据库缓存等等,合理利用这些缓存则能大幅度的提高系统性能,

利用不好反而会偷鸡不成蚀把米,给服务器造成巨大的压力,所以这里就存在一个缓存的使用原则的问题。

 

二:合理的使用缓存

1.  读写小于10:1的情况下,不适合用缓存,我们用缓存的目的就是想分摊下数据库的压力以及利用内存来提速性能,如果读写差不多,或者

     压根就没读过,这样的死数据就会造成内存资源的浪费。

2.  既然是缓存,就注定了它的资源是有限的,宝贵的,也就注定了我们必须合理利用它的内存空间,也就被迫的让我们清楚的认识到热点数据,

   不易修改的应该放在缓存,反之不宜放。

3.  大公司在缓存方面做的好的地方就是在一个“控”字上,他们会为缓存专门做一套“缓存系统”,当系统预加载的时候,同时也充当内存数据库

     使用,将这些元数据加载到缓存系统中,比如“县市区”,“分类信息”等等作为预热数据。

 

三:分布式缓存

   一般情况下,会有两种形式,第一种就是主从复制的模式,第二种就是分片的模式。

1:主从复制模式

  这种模式曾今在项目中也用过,就是一份内存,多处备份,当其中某一个缓存内容中的数据有变化时,会及时通知其他机器进行缓存更新

或清除,这种模式的缺点在于比较容易受制于单台机器的内存限制,优点在于用心跳机制及时用另一台缓存机器顶替,那个时候我们使用120G

的大内存,得益于项目业务规模的限制,否则当机器内存爆满的时候就比较尴尬了,所以做大型网站还是谨慎使用吧,毕竟这个也是我们曾今做

了一些为了提升性能的尝试。

 

2:分片的模式

    这种模式在大型网站中还是被大量使用的,它的特点就是可以把一大坨数据通过一定的算法和配置分摊到集群中的若干台机器上,如果集群中

的某一台机器挂了,没关系,只会影响到该台机器中的数据,对数据库不会造成很大的影响。一个典型的应用就是memcache,memcache是一

个非常简单,实用,高效的分布式缓存架构,其实memcache最值得一提的就是“路由算法的一致性hash”技术使得我们的memcache集群可以

自由伸缩,不过现在已经有很多的nosql产品,比如redis,couchdb,mongodb等等,让我们在这个世界上有了更多的选择吧。

 

最近看到园子里面有很多抱怨声,没关系,如果觉得自己屈才了,欢迎来携程试一试,只有你达不到的能力,没有给不起你的薪资。



们知道在面向对象编程中,总会想着各种办法来实现代码的解耦,从而让项目中的各种人员面对自己熟悉的业务进行开发,

做到术业有专攻,比如大家非常熟悉的三层架构,MVC,MVP以及MVVM模式,让前端设计专注于html的制作,让后端开发人员

更加专注于业务逻辑的编写,可以看到,我们这么做的目的就是想最大程度的做到系统的可扩展和可维护性,那么我们的大型网站

是不是也要遵守这种模式呢?

 

一:分层和分割

1:分层

    对于分层,我们可能非常熟知了,数据访问层,业务逻辑层,缓存层,应用层,层层专注于自己的业务,然后根据需要建立起

 各自的集群,各自分离部署,而从达到系统的扩展性和维护性。

 

2:分割

    如果说前面是横向切割,那分割就是纵向切割,我们可以把网站的整体业务切分成很多的小业务,比如博客园的导航栏,我们都

可以认为是一个独立的网站,配上各自的二级域名,建立各自的集群来实现系统的扩展性,当然这个粒度可大可小。

如果说这些子网站不存在相互调用,那么我们新增模块或者修改模块基本上都不会对其他模块造成影响,这也是我们做扩展性的终极

目标,现在既然都做到解耦了,下面的目标就是做如何通信了,通信可以分为“同步”和“异步”,这篇主要是讨论下异步操作,在分布式

系统中做到"异步操作“,当然少不了强大的消息队列。

 

二:消息队列

    在分布式的系统中使用消息队列后,我们的生产者只管向消息队列中甩完数据后立即返回,而不管是哪个消费者来消费,可以看到

其实消息队列有如下三个优点。

 

1.  加快网站的相应速度

    这个刚才也说了,应用层直接把消息给消息队列然后直接返回调用端,这样就避免了处理复杂的业务逻辑然后同步的插入到数据

  库后再返回造成的响应延迟,在很多网站上用户提交订单就是这么处理的,应用层生成一个订单号之后,将订单丢给消息队列,然后

  直接到订单成功页面,此时后端消费者对订单还没有处理完毕,因为后面会有比较多的数据操作,比如减库存,数据库同步等等,而

  用户如果想要看到订单详情,需要点击“订单号”才能进入到订单详情页,这种处理也是因为消息队列的非及时性,所以需要得到网站

  设计方改进和支持

 

2. 提供系统的可用性

    既然是异步操作,就造成了生产者不知道消费者的存在,而反过来消费者不知道生产者的存在,如果消费者挂了就不会影响到生产者,

  生产者还会照常无误的向消息队列甩消息,当消费者恢复正常后就会继续消费消息队列,系统的表现可能就是email或者短信延迟收到,

  不会对系统造成太大的影响。

 

3. 并发削峰

   既然是大型网站就免不了高并发的读写操作,很典型的一个例子就是电商中的秒杀,这种高并发的写操作,如果一下子都涌入到数据库

里面去了,会导致数据库的压力非常大,从而导致客户端的访问延迟,就是不挂也容易造成数据库的死锁从而造成很多灵异事件,遇到这

种一拥而入的情况,我们就必须进行线性化操作,在代码层面上我们可以用lock机制来串行化,在分布式中我们用“消息队列”来串行化,

而且还可以通过逻辑操作来对消息队列进行动态的防洪,控洪。

 

 在消息队列的选择上,微软有自己的MSMQ,但是在大型网站中,我们的消息队列同样需要集群,并且希望能跑在内存中,并且支持序列

化硬盘,同时在“伸缩性”和“可靠性”上要有好的作为,所以推荐大家用用开源的RabbitMQ,网址:http://www.rabbitmq.com/  不过很

多公司都有自己开发的消息队列,比如携程的CMessage,淘宝的MetaQ。


0 0
原创粉丝点击