您的位置:首页 > 数据库 > Memcache

关于Redis的和Memcached的澄清

2015-11-13 00:00 471 查看
摘要: 选择redis,还是memcached,或许你不清楚,不妨听一下创作者的建议再做决定。

翻译前言:

选择redis,还是memcached,或许你不清楚,不妨听一下创作者的建议再做决定。

----------------------------------------------------------------------------------
http://antirez.com/news/94
原文翻译:

如果你了解我,我不是那种认为比较会产生差的产品的人。 事实上我喜欢用户有多种多样的选择,所以我很少那redis和其他技术做比较。但它也确实,

为了选择合适的解决方案,用户必须正确认识到各种产品,以免被误导。

这篇博客是阅读迈克·佩勒姆发表的一篇文章后有感而发,这个人写了一个比较出名的库,叫Sidekiq,而碰巧它是使用redis作为后端。

所以我完全不认为这个迈克·佩勒姆是redis的反对者。然而在他的博客,他写道,对于缓存,“你应该使用memcached”,你可以在下面

这个地址找到这篇文章:http://www.mikeperham.com/2015/09/24/storing-data-with-redis/

从他的文章看出,他简单地,内心又十分地相信,redis作为缓存来说不够好,同时他的文章陈述了以下观点:

1)Memcached是专为缓存而设计。

2)完全不执行磁盘I / O的。

3)它是多线程的,通过多核,可以处理100,000每秒的请求。

针对上面的观点,我会做一一陈述,同时我会提供更多的信息而上面没提及到的信息和使用实例,这些信息主要是发自我的观点,而非使用者的观点。

1:Memcached是专为缓存而设计的:我会跳过这一点,因为它是没什么好争辩的。 事实上,我也可以说“Redis的是专为缓存而设计”。

所以在这方面他们是完全一样的,让我们看一下接下来的观点。

2:完全不执行磁盘I / O的:在Redis的,如果你想, 你完全可以禁用磁盘I / O,为你提供全内存操作的体验。特别地,如果你需要操作磁盘IO,你可以在你重启之前

通过命令“SHUTDOWN SAVE”来将数据保存到磁盘中,重启之后可以恢复之前的数据了。磁盘操作的作用是作为附加的功能,并可以作为最后的防线,即使你完全不需要它。

3:它是多线程的:这是真实的,而我的目标是让Redis的I / O线程化(这个方面如同memcached一样,这里的数据访问本身不是多线程的,redis大概是这样的情况)。

然而redis每个实例可以达到每秒请求数量惊人的效果,尤其是开启管道功能,(使用管道一般性能都达到50万每秒的请求,不使用管道的情况下可以达到10万每秒的请求。)

在专业的缓存场景中,每个redis实例是一样的,并作为master运行,并且禁止磁盘操作,并且时间分片采决与客户端的访问,跟“memcached的时间分片模式一样”。

每个系统运行多个redis进程,并不可怕,一旦你这样做,你得到的是多个线程的redis,并且这些线程之间没有任何的共享,因此,你能得到的性能是每个线程的性能之和。

最后一次我测试redis的时候,单个redis的性能最少有memcached那么快。随着时间的流逝,开发的不断进行,新功能的增加,这个性能有可能高了,也有可能低了,

但是我打赌他们能提供的性能几乎是差不多的,因为他们都最大化的利用机器的资源了。

memcached多线程仍然是一个优势,因为它使事情更易于使用和管理,但我认为这些不是一个系统的关键部分(指的是易于使用和管理方面),事实上redis也是很容易管理和使用。

还有更多的事实:

迈克谈及每秒操作性能的时候并没设计这些操作的质量。这主要是指在redis和memcached中,涉及到命令的分发和I/O的性能比较,这些比较涉及到内存的数据结构问题。

基本上来说,在redis当中,执行一个简单set,get,或者更复杂的命令,例如zrank,它们的操作消耗成本基本上是一样的。但从应用层的角度来说,执行这样复杂的工作

是需要很多的工作才能做到的,无形中节省了应用程序的效率。例如,当你要获取5个缓存值的时候,你可以发送一个lua脚本去一次完成。

因此在扩展性方面,两个系统存在很多维度的不一样,不能完全替代,因为上面的迈克的陈述,只是其中之一。

在迈克关注的事情中,我能看到的是他关注最多是多线程问题。如果我们考虑将redis作为memcached替换的情况下,那么我们只需要启动多个redis实例即可,如果执行memcached

相似的操作,我们只要启动一个实例即可,因为这将是非常非常困难的让其单个线程饱和。

真正的区别:

现在可以说一下两个系统之间的真正不同了。

* 内存效率

这是Memcached比Redis好的地方。 在一个系统中,用来string存储一个字符串,这种简单的表示能更好的节约内存,但是这种差异并不明显,

就像都已经5年了,我都没注意这个地方,因为它并不明显,但是它很容易被注意到不是最节约内存的。

然而当我们考虑一个长期运行的进程时,内存的效率等问题时,事情就变得不一样了。

回归到这个节约内存的问题上,你可以将一些字符串保存到redis的特殊编码的小集合上,是非常节约内存的。例如redis的整数集合,表示8,16,32,64

位整数时,访问它们可以达到log的时间效率,因为它们是有序的,并且你可以使用二分搜索算法去搜索访问。

不使用json而使用redis的hash也能达到节省内存的效果。因此对于评估是否节约内存,内存使用率的问题上,必须使用实际的例子来评估,不能单纯的从字符串出发。

* redis的LRU算法和slab分配方法的比较

从内存的使用率的角度来看,memcached并不完美,如果你碰巧有一个随着时间的改变而改变缓存大小的应用程序,你的系统将会得到很内存碎片,最后唯一的办法

就是重启进程。(Redis is a lot more deterministic from this point of view, 不明白作者的意思)。

此外Redis的LRU最近提高了很多,现在跟真正的LRU的一个非常接近。在下面的URL中可以找到关于Redis LRU更多的信息:http://redis.io/topics/lru-cache。

如果我理解正确的话,memcached的LRU超时仍根据它的slab分配器,所以有时的行为会远离真正的LRU算法,但我想听听专家们说这个。 如果你想测试redis LRU算法,

你可以使用Redis-cli LRU 测试模式,最近的一些版本都具备这个功能。

* 聪明的缓存方式

如果你想使用redis作为缓存,或者将它仅仅作为memcached的替代,那么事实上你忽视了一些使用redis的重要事实。

这是在我看来,迈克的博客写的文章的最大的错误观点。越来越多的人转向redis,因为他们发现可以使用平常的一些数据结构的方式来将数据保存在缓存中,即redis具备丰富的数据

结构,可以使你方便的存储数据,像你平时一样使用。例如,获取最近N个主题,使用有限的队列,可以用下标的方式访问缓存,还有有序集合等等。

* 持久性和复制

如果你需要这些功能,那么它们可以节省你很多重要的工作,例如对于访问量很大的地方,可以使用这个特性来扩展你的缓存服务。

同样,关于持久化问题,它可以在重启的时候加载之前的缓存,可以使用快照的方式把数据保存起来,快照可以一段时间做一次,使得可以定点恢复数据。

这两个完全不相关的特性,却有着巨大的作用,我想说的是,作为“纯缓存”的使用情况下,持久性和复制功能同样是很重要的。

* 可监控性

Redis的是非常非常易于监控的。可以监控到成吨的数据,意思是可以监控到它几乎所有的内部状态,你可以扫描的整个数据库,观察即将过期的缓存等等。

配置性LRU算法, 多种过期方式,可以给链接进来的客户端命名,可以看到所有的客户端列表,可以使用“MONITOR”来调试应用程序,以及许多其他先进的东西。

我相信这是redis的一个巨大优势。

* Lua脚本

我相信,Lua脚本是许多缓存使用案例里面是一个令人印象深刻的一个缓存功能。

例如,如果你有一个缓存的JSON博客,使用LUA命令你可以随意的获取到某一个字段,同时返回给客户端,而不是将所有数据都返回

(事实上,你也可以使用hash来直接表示物体,作用是一样的。)

* 结论

Memcached是一个伟大的软件,我读过它的源代码多次,它是我们行业的一次革命。在选择哪一个之前,你应该检查它,并做一些比较,例如和redis的比较。

但是比较这事情必须基于它们真实的特性进行真实的评估,最后,阅读Mike的报告使得我很恼火,以及多年来非常类似的报告。所以,我决定向你们表达我的观点。

如果您发现任何事实不符合事实,请ping命令我,我会根据“编辑”部分来更新这篇博客文章。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: