信管家软件吧 关注:143贴子:3,946
  • 3回复贴,共1

微博软件CacheService架构浅析

只看楼主收藏回复

微博作为国内最大的社交媒体网站之一,每天承载着亿万用户的服务请求,这些请求的背后,需要消耗着巨大的计算、内存、网络、I/O等资源。而且因为微博的产品特性,节假日、热门事件等可能带来突发数倍甚至十几倍的访问峰值,这些都对于支撑微博的底层基础架构提出了比较严苛的要求,需要满足:
每秒数十万的用户请求
数据更新的实时性
服务请求的低响应时间
99. 99%以上的服务可用性
  为了满足业务的发展需要,微博平台开发了一套高性能高可用的CacheService架构用于支撑现有线上的业务系统的运转。但“冰动三尺非一日之寒”,微博的Cache架构也是经历了从无到有,不断的演进过程。
  基于MySQL的Web架构
  最初的微博系统,系统的访问量都比较小,简单的基于数据库(MySQL)已经能够满足业务需求,开发也比较简单,简单的架构示意图如下:


1楼2017-05-06 08:56回复
    随着微博的推广和名人用户入驻微博,带动了用户量的快速增长,访问量也与日俱增,这个时候,简单基于MySQL的架构已经略感吃力,系统响应也比较缓慢。因为MySQL是一个持久化存储的解决方案,数据的读写都会经过磁盘,虽然MySQL也有buffer pool,但是无法根据业务的特性做到很细粒度的控制。而在微博这种业务场景下,配置了SAS盘的MySQL服务单机只能支撑几千的请求量,远小于微博的业务请求量。
      基于单层Cache+MySQL的Web架构
      针对请求量增大的问题,一般有几种解决方案:
    业务架构改造,但是在这种场景下,这种方案的可行性不高。
    MySQL进行从库扩容,虽然能够解决问题,但是带来的成本也会比较高,而且即使能够抗住请求量,但是资源的响应时间还是无法满足期望的结果,因为磁盘的读取的响应时间要相对比较慢,普通的15000转/分钟的SAS盘的读取延迟平均要达到2ms以上。
    在MySQL之上架构一层缓存,把热门请求数据缓存到Cache,基于Cache+MySQL的架构来提供服务请求。
      考虑到整体的改动和成本的因素,基于方案3)比较适合微博的业务场景。而应该使用什么类型的Cache比较合适呢?
      比较常见的Cache解决方案有:
    Local Cache,通过在Web应用端内嵌一个本地的Cache,这种的优势是访问比较快,但是存在的问题也比较明显,数据更新的一致性比较难保证,因此使用的范围会有一定的限制。
    单机版的远程Cache,通过部署一套远程的Cache服务,然后应用端请求通过网络请求与Cache交互,为了解决应用的水平扩展和容灾问题,往往通过在client层面来实现数据的路由等。
    分布式的Cache,Cache服务本身是一个大集群,能够提供给各种业务应用使用,并提供了一些基本的分布式特性:水平扩展、容灾、数据一致性等等。
      从系统的简单性考虑和微博场景的适用问题,最终选择了2)的方式,基于开源的Memcached来作为微博的Cache方案。


    2楼2017-05-06 08:56
    回复
      Memcached是一个分布式Cache Server,提供了key-value型数据的缓存,支持LRU、数据过期淘汰,基于Slab的方式管理内存块,提供简单的set/get/delete等操作协议,本身具备了稳定、高性能等优点,并在业界已经得到广泛的验证。它的server端本身是一个单机版,而分布式特性是基于client端的实现来满足,通过部署多个Memcached节点,在client端基于一致性hash(或者其他hash策略)进行数据的分散路由,定位到具体的memcached节点再进行数据的交互。当某个节点挂掉后,对该节点进行摘除,并把该节点的请求分散到其他的节点。通过client来实现一定程度的容灾和伸缩的能力。

        这种架构经过一段时间的蜜月期后,也逐步遇到了一些问题。
      节点挂掉导致的瞬间的峰值问题
      比如部署有5个Memcached节点,对key做一致性hash将key散落分布到5个节点上,那么如果其中有1个节点挂掉,那么这个时候会有20%原本Cache hit的请求穿透到后端资源(比如DB)。对于微博而言,多数核心资源的Cache hit的比例是99%,单组资源的QPS可能就达到100W以上的级别,如果这个时候有20%的穿透,那么相当于后端资源需要抗住20W以上的请求,这对于后端资源来说,明显压力过大。
      某组资源请求量过大导致需要过多的节点
      微博的Feed业务是Cache资源的消耗大户,几十万的QPS,GB(Byte)级别以上的带宽消耗,这个时候,至少需要十几个Memcached节点单元才能够抗住请求,而过多的Memcached节点请求会导致multiget的性能有弱化,因为这个时候keys分散到的Memcached节点会比较多,因此当进行拉取聚合的时候,性能会受影响,同时mutliget的响应时间受最慢的那个节点的影响,从而无法达到服务的SLA要求。
      Cache的伸缩容和节点的替换动静太大
      对于微博这种会在热点事件、节假日等发生时会有一些变态峰值(往往是数倍或者数十倍)的场景而言,实时的动态伸缩容很是必要,而因为通过client端实例化的Memcached资源节点相对比较固定,因此要进行伸缩容需要:
      进行一次代码的线上变更,进行节点配置的变更,而如果依赖该某组资源的应用系统比较多,比如底层的认证资源,那么需要对多个业务系统变更,这一动静不可谓不小,特别是遇到紧急情况,这个会导致操作的执行很缓慢。
      需要解决读写导致的一致性问题,假如有一些业务系统在读取Cache,有一些业务系统在写入Cache,而正常的变更是比较难让这些系统在某一刻全部执行节点的配置切换。
      需要使用新的节点替换老的节点(比如更换物理机),面临和上面类似的问题。
      过多资源带来的运维问题
        Cache资源组是按业务去申请,当业务特别多的时候,Cache资源组也会很多,这个时候要对这些资源进行运维管理如调整,将会变得不容易。而且随着时间的演进,一些比较古老的资源年老失修的情况,要进行运维调整就更为不容易。
      Cache架构要用得好的复杂度
        会用和用得好是两个不同概念。如果Cache架构需要每个业务开发很熟练才能够用得好,而不会因为Cache的不当使用而导致线上服务出现稳定性问题、以及成本的浪费等各种问题的话,这种对于需要陆续补进新人的团队现状而言,出问题将会是一种常态。 因此要解决这种问题,那么需要提供一种足够简单的Cache使用方式给业务应用方,简单到只有set/get/delete等基本命令的操作,而无需要他们关心底层的任何细节。


      3楼2017-05-06 08:56
      回复
        分布式CacheService架构
          为了解决这些问题,微博的Cache服务架构进行了演进,通过把Cache服务化,提供一个分布式的CacheService架构,简化业务开发方的使用,实现系统的动态伸缩容、容灾、多层Cache等相关功能。
          CacheService架构示意图如下:

          系统由几个模块组成:


        4楼2017-05-06 08:57
        回复