memcached不那么好用

memcached是运用非常广泛的缓存服务,但最近折腾了一下,感觉它其实非常弱,有很多坑爹之处。

memcached是这么被描述的:high-performance, distributed memory object caching system, 即所谓的高性能分布式对象缓存系统,但其实就是一个简单的内存kv存储器,当然在内存kv存取方面性能不错,但其实跟分布式对象存储无关。 当你部署多台memcached时,你需要自己实现hash策略,选择存到哪个memcached上,分布式就得考虑未来扩容,就得自己实现一致性hash算法。 分布式就得考虑稳定,得自己实现数据冗余策略。总之,memcached没有像mysql那样主从同步,或者像beehive那样多机集群的功能。在实现调度策略的同时,还得实现socket连接池的管理,探活呀什么的。 至于对象存储,也是不行的,你得自己实现序列化和反序列号功能,在python里,使用json.dumps或者cPickle.dumps, 可以很方便的序列号,尤其是后者,非常强大的对象序列号功能,要是其他语言可能就没这么幸运了。

假定希望某个用户相关的数据全存在一个缓存里,就得考虑使用用户ID来hash选择机器,只是简单地拿key来hash,会导致一个用户的各类数据分散在不同机器的memcached上。 这有什么好处呢,memcached是没有mget和mset之类的一次取多个,或者一次存多个的接口的,而且考虑到分布式数据也都不会在一台机器上,也不会有这样的接口。 如果要取的数据都在一台机器上,至少可以一直使用一条socket连接,一次性把请求全发过去,然后一次性把结果全读回来。python的MemCached就是这么实现的。

使用memcached的初衷多是减少对mysql数据库的压力,对于mysql之间的主从延迟是不可避免的,这时就容易存在一个恶心的问题。当DB中某个数据更新了,这个数据涉及到其他一些统计信息的修改, 程序便删除了缓存中的统计信息,正常情况下,接下来的请求到来时,发现缓存中没有,会重新计算这些统计信息,但如果此时读DB落在了从库,而主从又没有同步,这时老数据的统计信息会重新写入缓存, 主从同步了,也不会被更新。如果你说,应该在写入DB,删除缓存时,立马将新的统计信息存入缓存,这时有两个绕不过的问题, 其一,统计信息访问频次很低,或者统计信息计算复杂,都不值得立马更新,其二,A线程写DB之后,正要新缓存之时,B线程又写了DB,并且更新了缓存, 然后A再更新缓存时,一样会是老信息在缓存里。所以,总之是,memcached在设计时,需要考虑延迟删除问题。

不能认证连接,要么监听本机请求,即-l 127.0.0.1,要么就来者不拒,再或者使用第三方库,如SASL authentication。 如果你的机器有限,这些机器跑WEB,对外提供页面,又跑memcached,这时你就尴尬了,如果想多机分布式使用memcached, 就只得接收所有来源的socket连接,这会非常不安全。

不能扩展空间,如果想扩展一下memcached的内存大小,就只能重启了,等待缓存重新填满。当缓存用满,memcached会进行各种淘汰策略。

不能dump到磁盘,因为是内存缓存,一重启就啥都没有了,对于专门的缓存集群,再次填充会是很耗时的。

不能使用配置文件,启动是直接杠参数的,程序员脑袋已经够忙了,能使用配置,在配置文件中写点注释,下次来看时,能省不少脑力。

发表于 2014年11月18日 01:17   评论:0   阅读:2055  



回到顶部

首页 | 关于我 | 关于本站 | 站内留言 | rss
python logo   django logo   tornado logo