Home  >  Article  >  Backend Development  >  memcache与redis替代session如何?是不是有redis就不需要memcache了?

memcache与redis替代session如何?是不是有redis就不需要memcache了?

WBOY
WBOYOriginal
2016-06-06 20:43:261265browse

看了知乎与segmentfault的架构,都是用的是redis,但是这个session存储也用的是redis吗?

回复内容:

看了知乎与segmentfault的架构,都是用的是redis,但是这个session存储也用的是redis吗?

Memcached创建者Dormando很早就写过两篇文章[1][2],告诫开发人员不要用memcached存储Session.

http://mp.weixin.qq.com/s?__biz=MjM5NjQ4MjYwMQ==&mid=202805903&idx=2&sn=94d0c60d0f86672aac527b658b7e1bcd#rd

1)首先redis和memcache(后面简写mc)取舍问题。
在很多mc的应用场景下,都可以使用redis也是可行的解决方案。当key比较大的时候,mc有更好的性能。当让mc存在key的大小限制(默认参数最大允许存1MB的字符串,-I参数的默认值)。
而redis在key较大的情况,读写性能非常低效。而选择mc有更好的性能和吞吐量
下面是生产上的测试,200并发的情况系,单个key为500kB的情况下。

<code>     redis-benchmark -d 500000 -t get,set -n 1000 -c  200 -q 
     SET: 306.84 requests per second
     GET: 1449.28 requests per second
</code>

redis的优势主要体现在两方面:
1)丰富的数组结构,无疑提高了开发效率。list(queue)、set/zset、hashmap、HyperLogLog非常好用。
redis is a data structure server。构建简单的消息队列,set去重操作,hashmap存放简单的关系型数据,HyperLogLog做唯一计数,等等。
2)redis支持主从复制,对与构建支持auto-failover的ha方案提供了必要的条件--multi replicas。比如简单的keepalive + vip的方式。
3)另外,twemproxy,redis sentinel、redis-cluster的出现,可以让运维或者DBA构建大规模的分布式缓存系统。(我本人是DBA)
具体的对比,查看[http://segmentfault.net/q/1010000002588088?_ea=147671][1]。

2)关于session存储。
session是web服务器端存放的用户行为数据,存储方式有很多中。比如nfs共享文件系统,tomcat集群提供了共享session存储。其他的用db(RDBMS)存储的也有。
nosql出现之后,常见的选择有redis、mc、mongodb。redis、mc的php直接提供调用模块(函数),都很方便使用。
虽然很多人说,session存储crash了,影响不大,大不了用户重新登录。但是我觉得session数据千万不能丢失。
1)首先,session数据丢失,用户需要重新登录,用户的体验非常差。
2)对一些购物网站,session的数据更为重要。session数据对于追踪用户的行为非常重要,比如做推荐系统、网站防刷系统(是否是机器人在爬去数据)。
因而我个人比较认同mc开发的观点,不要使用mc作为session存储。而选择redis,可以做数据复制和ha方案的。

楼主应该说的是替代默认的file的session。
一般来说用memcache就好了,
除非项目其他地方用了redis,那就也存redis吧,

有了redis就不需要memcache,有了memcache就不需要redis。
不是一定不能,而是没必要搞那么复杂。

1.SESSION是一种储存机制,而不是软件
2.虽然redis和memcache有很多地方都一样。但是储存临时性数据,还是memcache比较合适。redis主要是数据在内存中,定时或者定量写入,因此读取和写入都很快
3.SESSION既可以储存在memcache中,也可以储存在redis中。但是考虑到SESSION的临时性,个人认为更适合储存在memcache中

使用Redis实现Session共享,最重要的一个原因在于,Redis支持Hash结构(Session本质上就是服务器维护的一个哈希表)。

假设一个场景来说明,现在要在Session中要存入用户ID、用户头像两个字段信息,如果使用Memcached存储,有两种方式来存储:

  1. 将用户ID、用户头像分别使用两个Key来存储,key1 = #userId、key2 = #avatar

  2. 使用一个Map结构将用户ID、用户头像两个字段包装起来,如此可以将用户ID及头像信息视作一个对象来存储,key = {userId : #userId ,avatar : #avatar}

现有一个业务,需要从Session中取出#userId信息,第一种存储方式,可以直接使用key1找到#userId,第二种则需要使用key将包装过的用户信息整体取出,再取出其中的#userId信息,由此不难看出,第二种方式比较浪费网络资源。第一种方式看似可用,其实也是一个坑~
现有另一个业务,需要从Session中同时取出#userId和#avatar两个字段信息,第一种方式则需要分别使用key1和key2进行两次网络交互才能取得所需信息(字段数量越多,网络开销也越大),反而使用第二种式,更加合算。由此可见使用memcached来实现Session共享是不合适的。
同样的业务场景,使用Redis,可以将用户信息以Hash结构存储,同样将用户信息作为一个整体存入:

<code class="redis"># 将用户信息作为一个整体写入Redis
HMSET key userId #userId avatar #avatar name #name
# 一次取出全部字段信息
HGETALL key
# 只取出其中一个或多个字段
HGET key name
HMGET key name avatar
...</code>

由示例可以看出无论是取出部分信息还是全部信息,网络开销都只需要一次,写入也是同样的道理,仅此一点,也能证明Redis比Memcached更适合用来实现Session共享。

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn