php使用redis的几种常见操作方式和用法示例
发布:smiling 来源: PHP粉丝网 添加日期:2022-02-12 11:04:30 浏览: 评论:0
本文实例讲述了php使用redis的几种常见操作方式和用法,分享给大家供大家参考,具体如下:
一、简单的字符串缓存
比如针对一些sql查询较慢,更新不频繁的数据进行缓存。
- <?php
- $redis = new Redis();
- $redis->connect('127.0.0.1', 6379, 60);
- $sql = 'select * from tb_order order by id desc limit 10';
- //伪代码,从数据库中获取数据
- $data = $db->query($sql);
- $data = json_encode($data, JSON_UNESCAPED_UNICODE);
- $key = md5($sql);
- //缓存数据
- $redis->set($key, $value, 60);
- //获取数据
- $data = $redis->get($key);
- print_r(json_decode($data, true));
二、通过列表模拟简单队列
比如我们需要批量的发送邮件,可以把发送邮件的任务存入队列中,然后启多个php脚本从队列中读取任务去发送邮件。
也可以用来处理商品秒杀,用户点击抢购时,把一个个的用户抢购任务放入队列中,串行化处理,判断队列数量,防止超卖的发生。
- <?php
- $redis = new Redis();
- $redis->connect('127.0.0.1', 6379, 60);
- //循环的把发送1000条邮件任务插入队列
- for ($ix = 0; $ix < 1000; $ix++) {
- $redis->lPush('send_email_queue', json_encode([
- 'id' => $ix,
- 'send' => 'xxx@qq.com',
- 'receive' => 'yyy@qq.com',
- 'title' => 'xxx',
- 'body' => 'xxx',
- ]));
- }
- sleep(3);
- //从队列中取任务,执行任务
- while ($count = $redis->lLen('send_email_queue')) {
- echo "当前任务队列数 {$count} <br>";
- $task = $redis->rpop('send_email_queue');
- $task = json_decode($task, true);
- //伪代码,发送邮件
- $mailer->send($task['send'], $task['receive'], $task['title'], $task['body']);
- echo "任务 {$task['id']} 邮件发送成功<br>";
- }
三、通过watch + multi 来实现乐观锁
乐观锁,顾名思义,乐观的认为数据不会被修改,只有当更新时才去判断数据是否被修改过,通常用版本号或时间戳来实现。
redis中通过watch和multi来实现,watch会监视给定的key是否发生更改,当exec的时候如果监视的key发生过改变,则整个事务会失败。
当然我们可以调用多次watch监视多个key。
- <?php
- $redis = new Redis();
- $redis->connect('127.0.0.1', 6379, 60);
- //设置商品的库存数为100
- $redis->set('goods_stock_nums', 100);
- //监视该key
- $redis->watch('goods_stock_nums');
- //开启事务
- $redis->multi();
- //修改库存数
- $redis->decr('goods_stock_nums');
- //提交事务,如果在此期间有其他请求修改了该key,那么事务会失败
- if ($redis->exec()) {
- echo '抢购成功';
- } else {
- echo '数据错误,请重新再试';
- }
四、使用 set 来实现悲观锁
悲观锁,顾名思义,悲观的认为数据总是会被修改,所以在操作前都会先加上锁,操作完后,再释放锁。
- <?php
- function getRedis()
- {
- $redis = new Redis();
- $redis->connect('127.0.0.1', 6379, 60);
- return $redis;
- }
- function lock($key, $random)
- {
- $redis = getRedis();
- return $redis->set($key, $random, ['nx', 'ex' => 3]);
- }
- function unlock($key, $random)
- {
- $redis = getRedis();
- //使用lua脚本保证原子性
- $script = 'if redis.call("get",KEYS[1]) == ARGV[1] then return redis.call("del",KEYS[1]) else return 0 end';
- return $redis->eval($script, [$key, $random], 1);
- }
- function decrGoodsStockNums()
- {
- $redis = getRedis();
- //获取商品库存数
- $ret = $redis->get('goods_stock_nums');
- if ($ret === false) {
- return false;
- }
- if ($ret <= 0) {
- return false;
- }
- $random = mt_rand();
- //先获取锁
- if (lock('goods_stock_nums_lock', $random)) {
- //修改库存数
- $redis->decr('goods_stock_nums');
- //释放锁
- unlock('goods_stock_nums_lock', $random);
- return true;
- } else {
- usleep(100);
- decrGoodsStockNums();
- }
- }
- decrGoodsStockNums();
五、使用 publish + subscribe 完成发布和订阅
发布代码:
- <?php
- $redis = new Redis();
- $redis->pconnect('127.0.0.1', 6379);
- $ix = 0;
- //发布内容
- while (true) {
- $redis->publish('news', json_encode([
- 'title' => '我是新闻标题' . $ix,
- 'content' => '我是新闻内容' . $ix,
- 'time' => date('Y-m-d H:i:s'),
- ]));
- $ix++;
- sleep(1);
- }
订阅代码:
- <?php
- $redis = new Redis();
- $redis->pconnect('127.0.0.1', 6379);
- //订阅内容
- $redis->subscribe(['news'], function ($redis, $channel, $msg) {
- $msg = json_decode($msg, true);
- echo "标题: {$msg['title']} 内容: {$msg['content']} 时间: {$msg['time']} <br>";
- });
Tags: redis操作方式 redis用法
- 上一篇:PHP使用openssl扩展实现加解密方法示例
- 下一篇:最后一页
推荐文章
热门文章
最新评论文章
- 写给考虑创业的年轻程序员(10)
- PHP新手上路(一)(7)
- 惹恼程序员的十件事(5)
- PHP邮件发送例子,已测试成功(5)
- 致初学者:PHP比ASP优秀的七个理由(4)
- PHP会被淘汰吗?(4)
- PHP新手上路(四)(4)
- 如何去学习PHP?(2)
- 简单入门级php分页代码(2)
- php中邮箱email 电话等格式的验证(2)