找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索

[ Ngnix与高并发服务器 ] 【守望者 缓存】微博cacheService架构浅析

2014-10-12 16:33| 发布者: zhouy | 查看: 1334 | 收藏

摘要: 微博作为国内最大的社交媒体网站之一,每天承载着亿万用户的服务请求,这些请求的背后,需要消耗着巨大的计算、内存、网络、I/O等资源。而且因为微博的产品特性,节假日、热门事件等可能带来突发数倍甚至十几倍的访 ...
微博作为国内最大的社交媒体网站之一,每天承载着亿万用户的服务请求,这些请求的背后,需要消耗着巨大的计算、内存、网络、I/O等资源。而且因为微博的产品特性,节假日、热门事件等可能带来突发数倍甚至十几倍的访问峰值,这些都对于支撑微博的底层基础架构提出了比较严苛的要求,需要满足:


每秒数十万的用户请求
数据更新的实时性
服务请求的低响应时间
99.99%以上的服务可用性
为了满足业务的发展需要,微博平台开发了一套高性能高可用的CacheService架构用于支撑现有线上的业务系统的运转。但“冰动三尺非一日之寒”,微博的Cache架构也是经历了从无到有,不断的演进过程。


基于MySQL的Web架构


最初的微博系统,系统的访问量都比较小,简单的基于数据库(MySQL)已经能够满足业务需求,开发也比较简单,简单的架构示意图如下:

  
随着微博的推广和名人用户入驻微博,带动了用户量的快速增长,访问量也与日俱增,这个时候,简单基于MySQL的架构已经略感吃力,系统响应也比较缓慢,因为MySQL是一个持久化存储的解决方案,数据的读写都会经过磁盘,虽然MySQL也有buffer pool,但是无法根据业务的特性做到很细粒度的控制,而在微博这种业务场景下,配置了SAS盘的MySQL服务单机只能支撑几千的请求量,远小于微博的业务请求量。


基于单层Cache+MySQL的Web架构

针对请求量增大的问题,一般有几种解决方案:

相关厂商内容

阿里交易平台的架构演变及并行化实践 京东应用架构设计与治理 第三方支付风控系统的演进过程
相关赞助商


全球架构师峰会,7月18-19日,深圳万科会议中心举办,精彩呈现!务架构改造,但是在这种场景下,这种方案的可行性不高。MySQL进行从库扩容,虽然能够解决问题,但是带来的成本也会比较高,而且即使能够抗住请求量,但是资源的响应时间还是无法满足期望的结果,因为磁盘的读取的响应时间要相对比较慢,普通的15000转/分钟的SAS盘的读取延迟平均要达到2ms以上。


在MySQL之上架构一层缓存,把热门请求数据缓存到Cache,基于Cache+MySQL的架构来提供服务请求。考虑到整体的改动和成本的因素,基于方案3)比较适合微博的业务场景。而应该使用什么类型的Cache比较合适呢?比较常见的Cache解决方案有:


Local Cache,通过在Web应用端内嵌一个本地的Cache,这种的优势是访问比较快,但是存在的问题也比较明显,数据更新的一致性比较难保证,因此使用的范围会有一定的限制。
单机版的远程Cache,通过部署一套远程的Cache服务,然后应用端请求通过网络请求与Cache交互,为了解决应用的水平扩展和容灾问题,往往通过在client层面来实现数据的路由等。
分布式的Cache,Cache服务本身是一个大集群,能够提供给各种业务应用使用,并提供了一些基本的分布式特性:水平扩展、容灾、数据一致性等等。
从系统的简单性考虑和微博场景的适用问题,最终选择了2)的方式,基于开源的Memcached来作为微博的Cache方案。


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等基本命令的操作,而无需要他们关心底层的任何细节。

分布式CacheService架构

为了解决这些问题,微博的Cache服务架构进行了演进,通过把Cache服务化,提供一个分布式的CacheService架构,简化业务开发方的使用,实现系统的动态伸缩容、容灾、多层Cache等相关功能。


CacheService架构示意图如下:
  


系统由几个模块组成:

ConfigService

这一模块是基于现有微博的配置服务中心,它主要是管理静态配置和动态命名服务的一个远程服务,能够在配置发生变更的时候实时通知监听的config client。

proxy层

这一模块是作为独立的应用对外提供代理服务,用来接收来自业务端的请求,并基于路由规则转发到后端的Cache资源,它本身是无状态的节点。它包含了如下部分:

异步事件处理(event handler): 用来管理连接、接收数据请求、回写响应。
Processor: 用来对请求的数据进行解析和处理。
Adapter:用来对底层协议进行适配,比如支持MC协议,Redis协议。
Router: 用来对请求进行路由分发,分发到对应的Cache资源池,进而隔离不同业务。
LRU Cache: 用来优化性能,缓解因为经过proxy多一跳(网络请求)而带来的性能弱化。
Timer: 用来执行一些后端的任务,包含对底层Cache资源健康状态的探测等。
Proxy启动后会去从config Service加载后端Cache资源的配置列表进行初始化,并接收configService的配置变更的实时通知。

Cache资源池

这一模块是作为实际数据缓存的模块,通过多层结构来满足服务的高可用。 其中Main-node是主缓存节点,Ha-Node是备份节点,当Main-node挂掉后,数据还能够从Ha-Node节点获取避免穿透到后端资源,L1-node主要用来抗住热点的访问,它的容量一般比Main-node要小,其中L1-node可支持多组,方便进行水平扩容以支撑更高的吞吐。

Client客户端

这一模块主要是提供给业务开发方使用的client(sdk包),对外屏蔽掉了所有细节,只提供了最简单的get/set/delete等协议接口,从而简化了业务开发方的使用。

应用启动时,Client基于namespace从configService中获取相应的proxy节点列表,并建立与后端proxy的连接。正常一个协议处理,比如set命令,client会基于负载均衡策略挑选当前最小负载的proxy节点,发起set请求,并接收proxy的响应返回给业务调用端。


Client会识别configService推送的proxy节点变更的情况重建proxy连接列表,同时client端也会做一些容灾,在proxy节点出现问题的时候,把proxy进行摘除,并定期探测是否恢复。


目前微博平台部分业务子系统的Cache服务已经迁移到了CacheService之上,它在实际的运行过程中也取得了良好的性能表现,目前整个集群在线上每天支撑着超过300W的QPS,平均响应耗时低于1ms。

它本身具备了以下特性:


高可用保证

所有的数据写入请求,CacheService会把数据双写到ha的节点,这样,在main-node挂掉的时候,会从ha-node读取数据,从而防止节点fail的时候给后端资源(DB等)带来过大的压力。


服务的水平扩展

CacheService proxy节点本身是无状态的,在proxy集群存在性能问题的时候,能够简单的通过增减节点来伸缩容。而对于后端的Cache资源,通过增减L1层的Cache资源组,来分摊对于main-node的请求压力。这样多数热点数据的请求都会落L1层,而L1层可以方便的通过增减Cache资源组来进行伸缩容。


实时的运维变更

通过整合内部的config Service系统,能够在秒级别做到资源的扩容、节点的替换等相关的运维变更。


跨机房特性:

微博系统会进行多机房部署,跨机房的服务器网络时延和丢包率要远高于同机房,比如微博广州机房到北京机房需要40ms以上的时延。CacheService进行了跨机房部署,对于Cache的查询请求会采用就近访问的原则,对于Cache的更新请求支持多机房的同步更新。


目前微博的分布式CacheService架构在简化了业务开发使用的同时,提高了系统的可运维性和可用性。接下来的架构的改造方向是提供后端Cache资源的低成本解决方案,从单机的存储容量和单机的极限性能层面不断优化。因为对于微博的业务场景,冷热数据相对比较明显,同时长尾数据请求的比例也不小,因而如果减少了Cache的容量,那么会导致后端资源无法抗住请求,而扩大Cache的容量,又会导致成本的浪费。而全内存的解决方案相比而言成本相对比较高,所以热数据存放到内存,基于LRU的策略把冷数据交换到固体硬盘(SSD),这是一种可能选择的方向。


本文由守望者watchmen收集整理,部分内容源于网络。本文仅代表作者个人观点,不代表守望者的本意。如有违法侵权内容,请提交到守望者管理员处,立即处理。

推荐阅读

[守望者 算法视频]01_数据存储(链表与数组)
[守望者 算法视频]01_数据存储(链表与
本章重点介绍数据的在计算机的存储方式 :连续存储(数组)与链式存储,同时
[守望者   java初中级视频]22_javaNIO,AIO编程
[守望者 java初中级视频]22_javaNIO,
内容简介:本课程介绍阻塞,非阻塞,同步和异步的基本概念,介绍javaNIO,AIO
[守望者   java初中级视频]00_java初中级课程学习导航
[守望者 java初中级视频]00_java初中
内容简介:全面贾少这套视频课程学习需要具备的理论基础,以及适合的学习人群
[守望者 linux视频]01_开发工具与开发平台
[守望者 linux视频]01_开发工具与开发
本课主要介绍gcc,gdb等系列开发工具,开始编写程序之旅。要求理解Linux开发平
[守望者 算法视频]08_数据查找_hash算法
[守望者 算法视频]08_数据查找_hash算
守望者:普通逐个查找O(n),组织方式可以无序的数组或者普通链表。已经排序的
[守望者 linux视频]02 进程内存管理与valgrind的使用
[守望者 linux视频]02 进程内存管理与v
本课主要介绍Linux可执行文件与进程内存结构, Linux进程结构及内存申请与释放
[守望者 C和指针]11_高级指针_C_面向对象
[守望者 C和指针]11_高级指针_C_面向对
(1) 彻底解决指针、取地址后的类型问题。(2) 回调函数示例。
[守望者 算法视频]02_数据逻辑组织_线性关联_栈与队列
[守望者 算法视频]02_数据逻辑组织_线
数组与链表是数据存储的基本方法。栈与队列是两种特殊的数据成员管理方式。栈
[守望者 算法视频]07_数据查找_普通查找与二分查找
[守望者 算法视频]07_数据查找_普通查
守望者:二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好;
[守望者  java初中级视频]01_java环境搭建
[守望者 java初中级视频]01_java环境
内容介绍:学习如何搭建一个java的开发环境,配置JAVA_HOME,Classpath,path等
[守望者 算法视频]03_数据逻辑组织_树_二叉树
[守望者 算法视频]03_数据逻辑组织_树_
树是为了解决链表查找时是线性特点,树采用一分为多的方式,例如二叉树采用一
[守望者  java初中级视频]02_java语法基础
[守望者 java初中级视频]02_java语法
内容简介:介绍java语法的基础,包括常量,变量,作用域,以及常用运算符,对
[守望者 算法视频]05_数据逻辑组织__红黑树
[守望者 算法视频]05_数据逻辑组织__红
守望者:1972年 由Rudolf Bayer发明的,他称之为“对称二叉B树”,它现代的名
[守望者 Linux 视频]09_执行单元_进程异步_信号
[守望者 Linux 视频]09_执行单元_进程
本章重点介绍Linux系统下信号的基本原理,异步与同步区别,信号的产生,安装
[守望者 算法视频] 04_数据逻辑组织_AVL树
[守望者 算法视频] 04_数据逻辑组织_AV
守望者:二叉排序树的最坏情况下其退化为一个链表,相应的查找时间复杂度退化

行业聚焦  面试交流  职位推荐  开发视频   技术交流  腾讯微博  新浪微博

友情链接:课课家教育  阿里云  鲜果  W3Cfuns前端网  中国企业家  环球企业家  投资界  传媒梦工场  MSN中文网  Android开发者社区  cnbeta  投资中国网  又拍云存储  美通说传播  IT茶馆  网商在线  商业评论网  TechOrange  IT时代周刊  3W创新传媒  开源中国社区  二维工坊  Iconfans  推酷  智能电视网  FreeBuf黑客与极客  财经网  DoNews  凤凰财经  新财富  eoe移动开发者社区  i黑马  网易科技  新浪科技  搜狐IT  创业家  创业邦  腾讯财经  福布斯中文网  天下网商  TechWeb  雷锋网  新浪创业  和讯科技  品途O2O  极客公园  艾瑞网  抽屉新热榜  卖家网  人民网通信频道  拉勾网  创新派  简单云主机  

手机版|黑名单|守望者在线 在线教育 linux 高级程序设计 C/C++ 大数据 ( 蜀ICP备14029946号

成都守望者科技有限公司 © 2013-2016 All Rights Reserved