2011年初Marc Kwiatkowski通过Memecache@Facebook介绍了Facebook的Memcache架构,现在重新审视这个架构,仍有很多方面在业界保持先进性。作为weibo内部数据处理量最大,对数据延迟最敏感的部门,基于本厂2年多来对mc的使用心得,我在本文总结对MC架构的一些新思考。
1. Memcache使用中的雷区
通常你可能考虑不到,但又隐藏在某处等着你踩的称之为“雷”。
带宽和连接数
Memcache具有很高吞吐能力,Memecache@Facebook中介绍Memcache支持8万/s读和2万/s写,在weibo内部我们通常认为单个Memcache实例支持7w/s读,2w/s写是安全的。和Facebook一样,为了充分榨取服务器性能,我们会在一台物理机上部署多个Memcache。为了确保Memcache的正常工作,我们通常会通过定期执行MC stats命令来对内存使用量,踢出率,命中率等进行监控。比如微博早期监控中就包括如图所示的这些内容,
这些监控中我们最重视的往往是内存使用量和命中率。但随着前端服务不断增加和cache层不断扩容,单台缓存物理机上的连接数,带宽都成为新的瓶颈。因此必须重视对带宽和连接数的监控。Memecache@Facebook中介绍单台MC服务器可支撑10w连接。
Hot Key
Hot Key通常不常见,但Weibo和Facebook都遇到这类问题,简单的讲就是在大并发下,有大量的请求到同一个在MC中不存在的资源,然后全部read through到后端数据库,把数据库读跨。具体方法请见TimYang的博客:http://timyang.net/programming/memcache-mutex/,同时后面的讨论也很精彩。不过我查阅大量微博代码却没有发现有使用MC mutex,也就是说Hot Key是个不常见的问题,一个不容易踩到的雷。
Memcache Client
不记得是不是在Memecache@Facebook提到过,也和淘宝的同行交流过,共同的的经验是:Memcache优化的重点和难点在客户端。这个展开起来很大,概况讲有2个重点:(1)TCP连接池(2)基于NIO的multiget;可以参考我的另一篇文章:通过NIO实现Memcached multi get (http://maoyidao.iteye.com/blog/1739282)
2. Memcache集群是否支持线性扩容?
扩容问题之一:如果不降低命中率?
扩容Memcache不降低命中率,好像在高速路上给汽车换轮胎。
我们通常从课本上学到的是,前端采用一致性Hash,逻辑节点达2^32个,物理节点扩容也不会导致大量cache命中移动。一致性Hash足以应对大多数场景,但在微博业务中,每秒超过十几万次读,及时下降1%的命中率也会直接读跨数据库,因此我们的要求是扩容不能降低命中率。为达到该目的,我们把水平扩展,变为垂直扩展,即通过多层Cache解决扩容而同时不降低命中率的问题。
另外一个好处是,新加入的cache层无需预热,当线上服务出现意外高峰时,可以立刻投入使用。
扩容问题之二:Memcache集群具备水平扩展性吗?
随着缓存层的增长,数据被分散到更多缓存服务器上,获取相同信息需要发送的网络包的数量也在不断增长。比如,只有一台缓存服务器时,由于操作系统网络层发送缓冲区的设计,get 100个key的数据可以在一个IP packet中传输,结果可以也可以在一个IP packet中获取。但当有100台缓存服务器时,获取100个key的数据就有需要向100台服务器发送100个IP packet(假设100个数据均匀的分布在100台物理机上),相应的内核中断也显著增加。
因此,我不认为Memcache集群在这个概念下具备水平扩展能力。但通常我们通过划分不同数据大小的缓存池控制Memcache集群的大小,而且随着96G或以上大内存服务器的广泛使用。即便在微博这个场景下,12台服务器一组的缓存就已经非常大规模的了。
3. Memcache其实还能更快?
如果你追求极致的Memcache访问速度,可以登录上你的Memcache服务器,检查一下CPU使用情况。我找了一台线上服务,情况如下:
显然CPU7的系统使用率比其他CPU要高。检查一下软中断:
再看看线上服务的版本:
[jichao1@yf179 ~]$ uname -a
Linux yf179 2.6.18-164.el5 #1 SMP Thu Sep 3 03:28:30 EDT 2009 x86_64 x86_64 x86_64 GNU/Linux
在kernel-2.6.18-194.3.1.el 版本以下的Redhat以及CentOS 操作系统,使用Broadcom 5709网卡芯片的服务器存在cpu软中断不均衡,只有1个cpu处理软中断。
解决方法可以是升级内核,不过也有朋友说没用,需要通过VIP绑定2块网卡的方式解决,具体方案见:http://hi.baidu.com/higkoo/item/42ba6c353bc8aed76d15e9c3
通过对比内核支持4个队列的服务器(最多只能利用到4核,无法在硬件驱动层直接配置成更多队列),只分配一个CPU的Memcache服务器在大压力下可能会慢1~2ms。