选redis还是memcache

memcache和redis是互联网分层架构中,最常用的KV缓存。不少同学在选型的时候会纠结,到底是选择memcache还是redis。

画外音:不鼓励粗暴的实践,例如“memcache提供的功能是redis提供的功能的子集,不用想太多,选redis准没错”。

虽然redis比memcache更晚出来,且功能确实也更丰富,但对于一个技术人,了解“所以然”恐怕比“选择谁”更重要一些

什么时候倾向于选择redis?

业务需求决定技术选型,当业务有这样一些特点的时候,选择redis会更加适合。

复杂数据结构

value是哈希,列表,集合,有序集合这类复杂的数据结构时,会选择redis,因为mc无法满足这些需求。

最典型的场景,用户订单列表,用户消息,帖子评论列表等。

持久化

mc无法满足持久化的需求,只得选择redis。

但是,这里要提醒的是,真的使用对了redis的持久化功能么?

千万不要把redis当作数据库用:

(1)redis的定期快照不能保证数据不丢失

(2)redis的AOF会降低效率,并且不能支持太大的数据量

不要期望redis做固化存储会比mysql做得好,不同的工具做各自擅长的事情,把redis当作数据库用,这样的设计八成是错误的。

缓存场景,开启固化功能,有什么利弊?

如果只是缓存场景,数据存放在数据库,缓存在redis,此时如果开启固化功能:

优点是,redis挂了再重启,内存里能够快速恢复热数据,不会瞬时将压力压到数据库上,没有一个cache预热的过程。

缺点是,在redis挂了的过程中,如果数据库中有数据的修改,可能导致redis重启后,数据库与redis的数据不一致。

因此,只读场景,或者允许一些不一致的业务场景,可以尝试开启redis的固化功能。

天然高可用

redis天然支持集群功能,可以实现主动复制,读写分离。

redis官方也提供了sentinel集群管理工具,能够实现主从服务监控,故障自动转移,这一切,对于客户端都是透明的,无需程序改动,也无需人工介入。

而memcache,要想要实现高可用,需要进行二次开发,例如客户端的双读双写,或者服务端的集群同步。

但是,这里要提醒的是,大部分业务场景,缓存真的需要高可用么?

(1)缓存场景,很多时候,是允许cache miss

(2)缓存挂了,很多时候可以通过DB读取数据

所以,需要认真剖析业务场景,高可用,是否真的是对缓存的主要需求?

画外音:即时通讯业务中,用户的在线状态,就有高可用需求。

存储的内容比较大

memcache的value存储,最大为1M,如果存储的value很大,只能使用redis。

什么时候倾向于memcache?

纯KV,数据量非常大,并发量非常大的业务,使用memcache或许更适合。

这要从mc与redis的底层实现机制差异说起。

内存分配

memcache使用预分配内存池的方式管理内存,能够省去内存分配时间。

redis则是临时申请空间,可能导致碎片。

从这一点上,mc会更快一些。

虚拟内存使用

memcache把所有的数据存储在物理内存里。

redis有自己的VM机制,理论上能够存储比物理内存更多的数据,当数据超量时,会引发swap,把冷数据刷到磁盘上。

从这一点上,数据量大时,mc会更快一些。

网络模型

memcache使用非阻塞IO复用模型,redis也是使用非阻塞IO复用模型。

但由于redis还提供一些非KV存储之外的排序,聚合功能,在执行这些功能时,复杂的CPU计算,会阻塞整个IO调度。

从这一点上,由于redis提供的功能较多,mc会更快一些。

线程模型

memcache使用多线程,主线程监听,worker子线程接受请求,执行读写,这个过程中,可能存在锁冲突。

redis使用单线程,虽无锁冲突,但难以利用多核的特性提升整体吞吐量。

从这一点上,mc会快一些。

最后说两点

代码可读性,代码质量

看过mc和redis的代码,从可读性上说,redis是我见过代码最清爽的软件,甚至没有之一,或许简单是redis设计的初衷,编译redis甚至不需要configure,不需要依赖第三方库,一个make就搞定了。

而memcache,可能是考虑了太多的扩展性,多系统的兼容性,代码不清爽,看起来费劲。

例如网络IO的部分,redis源码1-2个文件就搞定了,mc使用了libevent,一个fd传过来传过去,又pipe又线程传递的,特别容易把人绕晕。

画外音:理论上,mc只支持kv,而redis支持了这么多功能,mc性能应该高非常多非常多,但实际并非如此,真的可能和代码质量有关。

水平扩展的支持

不管是mc和redis,服务端集群没有天然支持水平扩展,需要在客户端进行分片,这其实对调用方并不友好。如果能服务端集群能够支持水平扩展,会更完美一些。

memcache 和 memcached 的区别

1、memcache最早是在2004年2月开发的,最后更新是在2013年4月,而 memcached 最早是在2009年1月开发的,最后更新是在2014年1月更新的。因此 memcache的历史 比 memcached 早。更多信息大家可以参考:

memcache:http://pecl.php.net/package/memcache
memcached:http://pecl.php.net/package/memcached

2、 memcache 是一个原生版本,完全是在 PHP 框架内开发的,支持 OO(面向对象) 和非 OO 两套接口并存,而 memcached 是建立在 libmemcached 的基础上的,只支持 OO 接口。这就意味着在安装 memcache 扩展的时候不要求安装其他的东西,但是在安装 memcached 的时候会要求你安装 libmemcached。别嫌麻烦!因为 libmemcached 是 memcache 的 C 客户端,它具有低内存,线程安全等优点。据说新浪微博之前就全面将 PHP 的 memcache 替换成 PHP 的 memcached,在高并发下,稳定性果断提高。

3.memcached 有个比较 nice 的地方,就是 flag 不是在操作的时候设置的,而是有一个统一的 setOption() 函数进行设置,我们可以举添加缓存数据为例子:

#memcache:
bool Memcache::add ( string $key , mixed $var [, int $flag [, int $expire ]] )

#memcached:
public bool Memcached::add ( string $key , mixed $value [, int $expiration ] )

 

从上面各自的 add 方法可以看到,memcache 的 add 方法中的第三个参数代表是否对数据进行压缩,这样假如说我的缓存需要设置过期时间,但是 flag 参数在前面,我就得每一次都对 flag 进行设置!
而 memcached 中是使用 setOption() 来进行统一设置的(默认开启压缩)。

4、memcached 比 memcache 支持更多的 memcache 协议,大概也就是说 memcached 有更多的方法,比如 getMulti() 和 setMulti() 函数非常有用,但是 memcache 并不支持。

5、差别比较大的一点是,memcached 支持 Binary Protocol,而 memcache 不支持,这意味着 memcached 会有更高的性能。但是网上很多博客说 memcached 不支持长连接,这其实不然。

6、比较尴尬的一点是 memcached 和 memcache 对应的服务端名字都是 memcached,大家使用 ps aux | grep memcache 就会发现守护进程的名字是 memcached(我的环境是 ubuntu),其实后面的 d 可以理解为守护进程,因此网上有的人说 memcache 是客户端, memcached 是服务端就是这个意思,同学们不要将客户端的 memcached 和服务端的 memcached 混淆了就好。

7、两者在实现某些相同功能时所使用的算法也是有一定差异的,由于内容比较深,我也不太懂。。。。。

总结

1、本篇博客参考了很多网上的资料,加上自己的理解总结出来的。

2、从上面的分析也可以得出一个结论:memcached 比 memcache 好,因此在以后的开发过程中,大家尽量使用 memcached。

转自:https://blog.csdn.net/baidu_30000217/article/details/53586536

 

mac安装memcache扩展问题

执行php -i 报错:

Warning: PHP Startup: memcached: Unable to initialize module
Module compiled with build ID=API20131226,NTS
PHP    compiled with build ID=API20131226,NTS,debug
These options need to match
 in Unknown on line 0

解决办法:

1.brew search memcached
2.重装加上 —build-from-source
brew reinstall -v homebrew/php/php56-memcached --build-from-source

设置memcache有效期超过30天的方法

以前写过一个php 的memcache操作类,里面提到了在设置memcache有效期时,不能大于30天,其实memcache是可以设置大于30天有效期的。

设置方法:

$this->_memcache->set($key, $var, 0, time()+31*24*60*60);

 

上面代码与我们正常使用的时候多了个 time() 当前时间戳,在设置大于30天有效期时需使用此方法进行设置。

Wampserver下安装memcache

1.Memcached-32位 下载

http://pan.baidu.com/s/1c1AsMfY

如果上面的不好使,再试试这个:

https://pan.baidu.com/s/1H7iBsgsl8V0cBUr-Wt90_A

2.Memcached-64位 下载

(1)最新版本下载:http://blog.couchbase.com/memcached-windows-64-bit-pre-release-available
(2)本站下载:memcached-win64-1.4.4-14.zip

3.将上述下载文件解压放到某个目录下,例如

D:\wamp\bin\memcached\memcached.exe

4.安装Memcached

在cmd命令行执行以下命令:

D:\wamp\bin\memcached\memcached.exe -d install

[提示错误:failed to install service or service already installed]
解决方法:在系统盘中找到cmd.exe文件,点击右键,以管理员身份运行

5.启动Memcached

D:\wamp\bin\memcached\memcached.exe -d start

测试memcache是否连接成功:

方法一:
>telnet 127.0.0.1 11211

[提示错误:’telnet’ 不是内部或外部命令,也不是可运行的程序或批处理文件。]

注:windows7带有telnet,只是默认没有安装。

解决方法:依次打开“开始”→“控制面板”→“打开或关闭Windows功能”,寻找并勾选“Telnet客户端”,然后点击“确定”。顺利安装后,再输入此命令即可。

方法二:
netstat -an 查看11211是否存在

6.安装Memcached的PHP扩展

(1)php_memcache.dll 下载:php_memcache.dll
(2)将上述文件解压并放到 D:\wamp\bin\php\php5.4.12\ext (可根据自己实际情况放入自己的对应目录)
(3)在php.ini文件中添加下面一行

extension=php_memcache.dll

7.重启Wamp的Apache服务

在phpinfo()界面搜索Memcache,如果有Memcache出现则安装成功!

memcache与memcached

Memcache是什么?

Memcache是一个自由和开放源代码、高性能、分配的内存对象缓存系统。用于加速动态web应用程序,减轻数据库负载。它可以应对任意多个连接,使用非阻塞的网络IO。由于它的工作机制是在内存中开辟一块空间,然后建立一个Hash表,Memcached自管理这些Hash表。

Memcached是简单而强大的。它简单的设计促进迅速部署,易于发展所面临的问题,解决了很多大型数据缓存。它的API可供最流行的语言。
Memcache官方网站:http://memcached.org/

Memcached又是什么?

Memcached是memcache的守护进程,随时接受客户端的连接操作。

Memcache客户端(php)

PHP有两个memcache客户端:php memcachephp memcached

php memcache独立用php实现,是老客户端,从我们实践中已发现有多个问题,而且功能少,属性也可设置的少;

http://pecl.php.net/package/memcache

php memcached是基于原生的c的libmemcached的扩展,更加完善,建议替换为php memcached。

http://pecl.php.net/package/memcached