redis 或者memcache session 存储 同步

来源:互联网 发布:贪吃蛇的c语言代码 编辑:程序博客网 时间:2024/05/22 00:52

session可以存放在文件中,可以存放在memcache中,本以为session是不可以存放到redis中了,今天尝试了一下,竟然可以。session存文件是没问题的,存memcache也是没有问题的,这个我测试过,请参考:web集群时利用memcache来同步session但是redis是部分是走内存,部分是走文件的。我在想redis是怎么对待session的呢,费话不多了,看下文。

一,redis服务端,以及php扩展php-redis的安装

  1. [root@mysqlMaster www]# yum install redis php-devel php-redis  

如果找不到redis,php-redis包的话,换源。如果不想换源的,请参考:linux redis 安装配置, 以及redis php扩展

二,配置redis服务端

查看复制打印?
  1. [root@mysqlMaster www]# mv /etc/redis.conf /etc/redis.conf_bak //备份原有redis配置文件  
  2. [root@mysqlMaster www]# cat /etc/redis.conf    //添加以下内容  
  3. daemonize yes  
  4. pidfile /var/run/redis/redis.pid  
  5. port 6379  
  6. timeout 300  
  7. loglevel verbose  
  8. logfile /var/log/redis/redis.log  
  9. databases 16  
  10. save 900 1  
  11. save 300 10  
  12. save 60 10000  
  13. rdbcompression yes  
  14. dbfilename dump.rdb  
  15. dir /var/lib/redis/  
  16. slave-serve-stale-data yes  
  17. appendonly no  
  18. appendfsync everysec  
  19. no-appendfsync-on-rewrite no  
  20. vm-enabled no  
  21. vm-swap-file /tmp/redis.swap  
  22. vm-max-memory 0  
  23. vm-page-size 32  
  24. vm-pages 134217728  
  25. vm-max-threads 4  
  26. hash-max-zipmap-entries 512  
  27. hash-max-zipmap-value 64  
  28. list-max-ziplist-entries 512  
  29. list-max-ziplist-value 64  
  30. set-max-intset-entries 512  
  31. activerehashing yes  

参数说明:linux redis 安装配置, 以及redis php扩展,这篇博客里面有。

三,启动redis服务端,并且查看php-redis扩展

1,启动服务端

  1. [root@mysqlMaster ~]# /etc/init.d/redis start  

2,修改php.ini配置

查看复制打印?
  1. session.save_handler = redis  
  2. session.save_path = "tcp://127.0.0.1:6379"  

3,查看redis的php扩展

查看一下phpinfo要有以下二样,才能将session存储到redis中,

redis php扩展

redis php扩展

有了redis扩展,还要看php.ini有没有配置好。

session 可以存到redis中

session 可以存到redis中

四,session存储到redis中测试

查看复制打印?
  1. <?php  
  2. session_start();  
  3. $_SESSION['redis'] = "aaaaaa";  
  4. echo session_id();  
  5. echo "<br>";  
  6. echo $_SESSION['redis'];  
  7. echo "<br>";  
  8. $redis = new redis();  
  9. $redis->connect('192.168.1.108', 6379);  
  10. echo $redis->get("PHPREDIS_SESSION:ruk5i2vlu2hvtmfr5hig4l55f6");//这个key我是通过telnet到redis查的。  
  11. ?>  
页面显示结果

页面显示结果

echo session_id();显示出来是ruk5i2vlu2hvtmfr5hig4l55f6,开始的时候,echo $redis->get("ruk5i2vlu2hvtmfr5hig4l55f6");不管怎么样都取不到值,因为memcache这样是可以取到值的,所以我就想redis估计也是这样。telnet到redis看了一下,原来命名key值的方式是不一样的,看下图

redis telnet查看session

redis telnet查看session

到这儿session存储到redis是没有问题了,怎么同步呢。多服务器时,redis是可以配置同步的,当一台机子有session就可以准实时的同步到另一台


web服务器集群session共享策略

web集群时session同步的3种方法

 

在做了web集群后,你肯定会首先考虑session同步问题,因为通过负载均衡后,同一个IP访问同一个页面会被分配到不同的服务器上,如果session不同步的话,一个登录用户,一会是登录状态,一会又不是登录状态。所以本文就根据这种情况给出三种不同的方法来解决这个问题:

一,利用数据库同步session

在做多服务器session同步时我没有用这种方法,如果非要用这种方法的话,我想过二种方法:

1,用一个低端电脑建个数据库专门存放web服务器的session,或者,把这个专门的数据库建在文件服务器上,用户访问web服务器时,会去这个专门的数据库check一下session的情况,以达到session同步的目的。

2,这种方法是把存放session的表和其他数据库表放在一起,如果mysql也做了集群了话,每个mysql节点都要有这张表,并且这张session表的数据表要实时同步。

说明:用数据库来同步session,会加大数据库的负担,数据库本来就是容易产生瓶颈的地方,如果把session还放到数据库里面,无疑是雪上加霜。上面的二种方法,第一点方法较好,把放session的表独立开来,减轻了真正数据库的负担

二,利用cookie同步session

session是文件的形势存放在服务器端的,cookie是文件的形势存在客户端的,怎么实现同步呢?方法很简单,就是把用户访问页面产生的session放到cookie里面,就是以cookie为中转站。你访问web服务器A,产生了session把它放到cookie里面了,你访问被分配到web服务器B,这个时候,web服务器B先判断服务器有没有这个session,如果没有,在去看看客户端的cookie里面有没有这个session,如果也没有,说明session真的不存,如果cookie里面有,就把cookie里面的sessoin同步到web服务器B,这样就可以实现session的同步了。

说明:这种方法实现起来简单,方便,也不会加大数据库的负担,但是如果客户端把cookie禁掉了的话,那么session就无从同步了,这样会给网站带来损失;cookie的安全性不高,虽然它已经加了密,但是还是可以伪造的。

三,利用memcache同步session

memcache可以做分布式,如果没有这功能,他也不能用来做session同步。他可以把web服务器中的内存组合起来,成为一个"内存池",不管是哪个服务器产生的sessoin都可以放到这个"内存池"中,其他的都可以使用。

优点:以这种方式来同步session,不会加大数据库的负担,并且安全性比用cookie大大的提高,把session放到内存里面,比从文件中读取要快很多。

缺点:memcache把内存分成很多种规格的存储块,有块就有大小,这种方式也就决定了,memcache不能完全利用内存,会产生内存碎片,如果存储块不足,还会产生内存溢出。

四,总结

上面三种方法都是可行的

第一种方法,最影响系统速度的那种,不推荐使用;

第二种方法,效果不错,不过安全隐患一样的存在;

第三种方法,个人觉得第三种方法是最好的,推荐大家使用


Memcache共享session 

设置session用memcache来存储

方法I: 在 php.ini 中全局设置

Php.ini代码  收藏代码
  1. session.save_handler = memcache  
  2. session.save_path = "tcp://127.0.0.1:11211"  


方法II: 某个目录下的 .htaccess
Php.ini代码  收藏代码
  1. php_value session.save_handler "memcache"  
  2. php_value session.save_path  "tcp://127.0.0.1:11211"  


方法III: 再或者在某个一个应用中
Php代码  收藏代码
  1. ini_set("session.save_handler""memcache");  
  2. ini_set("session.save_path""tcp://127.0.0.1:11211");  


使用多个 memcached server 时用逗号","隔开,并且和 Memcache::addServer() 文档中说明的一样,可以带额外的参数"persistent"、"weight"、"timeout"、"retry_interval" 等等,类似这样的:"tcp://host1:port1?persistent=1&weight=2,tcp://host2:port2" 。

如果安装的PECL是memcached(依赖libmemcached库的那个扩展),则配置应为
Php代码  收藏代码
  1. ini_set("session.save_handler""memcached"); // 是memcached不是memcache  
  2. ini_set("session.save_path""127.0.0.1:11211"); // 不要tcp:[/b]  


代码例子(不依赖libmemcached库的那个)
Php代码  收藏代码
  1. <?php  
  2. session_start();  
  3. if (!isset($_SESSION['TEST'])) {  
  4.     $_SESSION['TEST'] = time();  
  5. }  
  6.    
  7. $_SESSION['TEST3'] = time();  
  8.    
  9. print $_SESSION['TEST'];  
  10. print "<br><br>";  
  11. print $_SESSION['TEST3'];  
  12. print "<br><br>";  
  13. print session_id();  
  14. ?>  


用 sessionid 去 memcached 里查询一下:
Php代码  收藏代码
  1. <?php  
  2. $memcache = memcache_connect('localhost', 11211);  
  3. var_dump($memcache->get('19216821213c65cedec65b0883238c278eeb573e077'));  
  4. $memcache->set('aaaa''hello everyone');  
  5. var_dump($memcache->get('aaaa'));  
  6. ?>  


会看到
string(37) "TEST|i:1177556731;TEST3|i:1177556881;"
这样的输出,证明 session 正常工作。
0 0