bbs php redis,PHP DIY 系列------框架篇:7. 使用 Redis 加速 Session 读写

大家都知道,默认的session是存储在文件里的,一般情况下这是没什么问题的,然而一旦访问很多,session的使用就会频繁读写文件,必然会影响应用的性能。另外,假如是多机部署,session的共享也是个问题。

既然我们知道有Redis这个利器,而PHP也是支持session自定义的,那么为何不要性能更好又能实现共享session的Redis呢?

Redis是什么?

Redis 是完全开源免费的,遵守 BSD 协议,是一个高性能的 key - value 数据库

Redis数据结构

string

hash

set

sorted set

pub/sub

list

另外还有HyperLogLog,geo….

Redis的优势

性能极佳,官网显示QPS能达到100k/s

数据结构丰富,不止于字符串,hash

稳定性不错,持久化

支持集群

社区不错,使用率高,对于PHP程序员,除了LNMP/LAMP,然后应该就是Redis了

Redis应用

缓存

分布式锁

计数器

队列

geo

……

Redis命令

使用redis存储session

我介绍两种方法给大家:

session_start带参

session_set_save_handler托管session

下面我们里一一说明:

session_start

session_start ([ array $options = array() ] ) : bool —— 启动新会话或者重用现有会话(点击查看更多参数)

来看demo:

session_start([

'save_path' => 'tcp://127.0.0.1:6379',

'save_handler' => 'redis',

]);

$_SESSION['user_id'] = 10001;

$_SESSION['userInfo'] = ['name' => 'sai'];

p($_SESSION['user_id']);

p($_SESSION['userInfo']);

输出如下:

10001

Array

(

[name] => sai

)

我们可以使用redis-cli连接查看:

redis-cli -h 127.0.0.1 -p 6379

// 如设置密码再输入(auth 你设置的密码)即可

36a46b4b8f371fb7c66d6a854a0d683b.png

我们可以看到redis里有了PHPREDIS_SESSION:nmo65igogqnq8ur2gia94jt15u,里面存储了我们的session信息。

session_set_save_handler

建议session.serialize_handler = php_serialize,默认php写入和读取略微繁琐。

这里说明我们成功了将session信息通过Redis进行了读写。下面我们使用session_set_save_handler来实现:

namespace Library\Sessions;

use SessionHandler;

class RedisSession extends SessionHandler

{

private $redis;

private $lifeTime = 7200;

private $config;

private $prefix = 'PHPREDIS_SESSION:';

public function __construct($config)

{

$this->config = $config;

}

private function getRedisInstance()

{

if (empty($this->redis)) {

$redis = new \Redis();

$redis->connect($this->config['host'], $this->config['port'], $this->config['timeout']);

if (!$this->config['auth']) {

$redis->auth($this->config['auth']);

}

$this->redis = $redis;

}

return $this->redis;

}

public function read($id)

{

return $this->getRedisInstance()->get($this->prefix.$id);

}

public function write($id, $data)

{

if ($this->getRedisInstance()->setex($this->prefix.$id, $this->lifeTime, $data)) {

return true;

}

return false;

}

public function destroy($id)

{

if($this->getRedisInstance()->delete($id)){//删除redis中的指定记录

return true;

}

return false;

}

public function gc($maxlifetime)

{

return true;

}

public function __destruct()

{

session_write_close();

}

}

$handler = new RedisSession([

'host' => '127.0.0.1',

'port' => 6379,

'auth' => null,

'timeout' => 5,

]);

session_set_save_handler($handler, true);

session_start();

$_SESSION['user_id'] = 10001;

$_SESSION['userInfo'] = ['name' => 'sai'];

p($_SESSION['user_id']);

p($_SESSION['userInfo']);

知识点:

这里需要注意下read方法,里面需要加一下serialize,以便于我们存储复杂的session结构。如果不加会报错(Warning: session_start(): Failed to read session data: user (path: ))这是因为Redis无法直接存储array结构,需要转化为string类型存储。

我们也来看看Redis客户端存储情况:

130e8b0cce2c2cbe924393c4bb474c06.png

通用我们也看到redis存储了session,与前面略有不同的只是存储的key不一样。但是我们可以定义一个私有属性:

private $prefix = ‘PHPREDIS_SESSION:’;

然后做一下调整即可:

public function read($id)

{

return serialize($this->getRedisInstance()->get($this->prefix.$id));

}

public function write($id,$data)

{

if ($this->getRedisInstance()->setex($this->prefix.$id, $this->lifeTime, $data)) {

return true;

}

return false;

}

运行后会发现把之前第一种设置的session覆盖掉。

当然我比较建议使用第二种方法,便于我们定制化编码。

总结

总的来说,两种方法配置都比较简单,个人建议使用第二种方式实现,这样也比较适合集成到框架,后期我们可以在进行扩展。

本作品采用《CC 协议》,转载必须注明作者和本文链接

收藏前不妨点个赞试试!!!

分享开发知识,欢迎交流。qq交流群:965666112,公众号:程序员涛子

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值