资讯专栏INFORMATION COLUMN

Redis常见7种使用场景(PHP实战)

邹强 / 1665人阅读

摘要:是一个开源的使用语言编写支持网络可基于内存亦可持久化的日志型数据库,并提供多种语言的。本篇文章,主要介绍利用使用,主要的应用场景。场景如果项目中使用了缓存且对缓存设置了超时时间。如果连接断开,监视和事务都会被自动清除。

Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。

本篇文章,主要介绍利用PHP使用Redis,主要的应用场景。

简单字符串缓存实战
$redis->connect("127.0.0.1", 6379);
$strCacheKey  = "Test_bihu";

//SET 应用
$arrCacheData = [
    "name" => "job",
    "sex"  => "男",
    "age"  => "30"
];
$redis->set($strCacheKey, json_encode($arrCacheData));
$redis->expire($strCacheKey, 30);  # 设置30秒后过期
$json_data = $redis->get($strCacheKey);
$data = json_decode($json_data);
print_r($data->age); //输出数据

//HSET 应用
$arrWebSite = [
    "google" => [
        "google.com",
        "google.com.hk"
    ],
];
$redis->hSet($strCacheKey, "google", json_encode($arrWebSite["google"]));
$json_data = $redis->hGet($strCacheKey, "google");
$data = json_decode($json_data);
print_r($data); //输出数据
简单队列实战
$redis->connect("127.0.0.1", 6379);
$strQueueName  = "Test_bihu_queue";

//进队列
$redis->rpush($strQueueName, json_encode(["uid" => 1,"name" => "Job"]));
$redis->rpush($strQueueName, json_encode(["uid" => 2,"name" => "Tom"]));
$redis->rpush($strQueueName, json_encode(["uid" => 3,"name" => "John"]));
echo "---- 进队列成功 ---- 

"; //查看队列 $strCount = $redis->lrange($strQueueName, 0, -1); echo "当前队列数据为:
"; print_r($strCount); //出队列 $redis->lpop($strQueueName); echo "

---- 出队列成功 ----

"; //查看队列 $strCount = $redis->lrange($strQueueName, 0, -1); echo "当前队列数据为:
"; print_r($strCount);
简单发布订阅实战
//以下是 pub.php 文件的内容 cli下运行
ini_set("default_socket_timeout", -1);
$redis->connect("127.0.0.1", 6379);
$strChannel = "Test_bihu_channel";

//发布
$redis->publish($strChannel, "来自{$strChannel}频道的推送");
echo "---- {$strChannel} ---- 频道消息推送成功~ 
"; $redis->close();
//以下是 sub.php 文件内容 cli下运行
ini_set("default_socket_timeout", -1);
$redis->connect("127.0.0.1", 6379);
$strChannel = "Test_bihu_channel";

//订阅
echo "---- 订阅{$strChannel}这个频道,等待消息推送...----  

"; $redis->subscribe([$strChannel], "callBackFun"); function callBackFun($redis, $channel, $msg) { print_r([ "redis" => $redis, "channel" => $channel, "msg" => $msg ]); }
简单计数器实战
$redis->connect("127.0.0.1", 6379);
$strKey = "Test_bihu_comments";

//设置初始值
$redis->set($strKey, 0);

$redis->INCR($strKey);  //+1
$redis->INCR($strKey);  //+1
$redis->INCR($strKey);  //+1

$strNowCount = $redis->get($strKey);

echo "---- 当前数量为{$strNowCount}。 ---- ";
排行榜实战
$redis->connect("127.0.0.1", 6379);
$strKey = "Test_bihu_score";

//存储数据
$redis->zadd($strKey, "50", json_encode(["name" => "Tom"]));
$redis->zadd($strKey, "70", json_encode(["name" => "John"]));
$redis->zadd($strKey, "90", json_encode(["name" => "Jerry"]));
$redis->zadd($strKey, "30", json_encode(["name" => "Job"]));
$redis->zadd($strKey, "100", json_encode(["name" => "LiMing"]));

$dataOne = $redis->ZREVRANGE($strKey, 0, -1, true);
echo "---- {$strKey}由大到小的排序 ---- 

"; print_r($dataOne); $dataTwo = $redis->ZRANGE($strKey, 0, -1, true); echo "

---- {$strKey}由小到大的排序 ----

"; print_r($dataTwo);
简单字符串悲观锁实战

解释:悲观锁(Pessimistic Lock), 顾名思义,就是很悲观。

每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁。

场景:如果项目中使用了缓存且对缓存设置了超时时间。

当并发量比较大的时候,如果没有锁机制,那么缓存过期的瞬间,

大量并发请求会穿透缓存直接查询数据库,造成雪崩效应。

/**
 * 获取锁
 * @param  String  $key    锁标识
 * @param  Int     $expire 锁过期时间
 * @return Boolean
 */
public function lock($key = "", $expire = 5) {
    $is_lock = $this->_redis->setnx($key, time()+$expire);
    //不能获取锁
    if(!$is_lock){
        //判断锁是否过期
        $lock_time = $this->_redis->get($key);
        //锁已过期,删除锁,重新获取
        if (time() > $lock_time) {
            unlock($key);
            $is_lock = $this->_redis->setnx($key, time() + $expire);
        }
    }

    return $is_lock? true : false;
}

/**
 * 释放锁
 * @param  String  $key 锁标识
 * @return Boolean
 */
public function unlock($key = ""){
    return $this->_redis->del($key);
}

// 定义锁标识
$key = "Test_bihu_lock";

// 获取锁
$is_lock = lock($key, 10);
if ($is_lock) {
    echo "get lock success
"; echo "do sth..
"; sleep(5); echo "success
"; unlock($key); } else { //获取锁失败 echo "request too frequently
"; }
简单事务的乐观锁实战

解释:乐观锁(Optimistic Lock), 顾名思义,就是很乐观。

每次去拿数据的时候都认为别人不会修改,所以不会上锁。

watch命令会监视给定的key,当exec时候如果监视的key从调用watch后发生过变化,则整个事务会失败。

也可以调用watch多次监视多个key。这样就可以对指定的key加乐观锁了。

注意watch的key是对整个连接有效的,事务也一样。

如果连接断开,监视和事务都会被自动清除。

当然了exec,discard,unwatch命令都会清除连接中的所有监视。

$strKey = "Test_bihu_age";

$redis->set($strKey,10);

$age = $redis->get($strKey);

echo "---- Current Age:{$age} ---- 

"; $redis->watch($strKey); // 开启事务 $redis->multi(); //在这个时候新开了一个新会话执行 $redis->set($strKey,30); //新会话 echo "---- Current Age:{$age} ----

"; //30 $redis->set($strKey,20); $redis->exec(); $age = $redis->get($strKey); echo "---- Current Age:{$age} ----

"; //30 //当exec时候如果监视的key从调用watch后发生过变化,则整个事务会失败
推荐阅读

系统的讲解 - SSO 单点登录

系统的讲解 - PHP WEB 安全防御

系统的讲解 - PHP 缓存技术

系统的讲解 - PHP 接口签名验证

系统的讲解 - PHP 浮点数高精度运算

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/22428.html

相关文章

  • php资料集

    摘要:简单字符串缓存实战完整实战种设计模式设计模式是面向对象的最佳实践成为专业程序员路上用到的各种优秀资料神器及框架成为一名专业程序员的道路上,需要坚持练习学习与积累,技术方面既要有一定的广度,更要有自己的深度。 微型新闻系统的开发(PHP 5.4 + MySQL 5.5) 微型新闻系统的开发(PHP 5.4 + MySQL 5.5) 九个很有用的 PHP 代码 php 代码 国内值得关注的...

    RobinQu 评论0 收藏0
  • 杂货 - 收藏集 - 掘金

    摘要:消息队列技术介绍后端掘金一消息队列概述消息队列中间件是分布式系统中重要的组件,主要解决应用耦合异步消息流量削锋等问题。的内存优化后端掘金声明本文内容来自开发与运维一书第八章,如转载请声明。 消息队列技术介绍 - 后端 - 掘金一、 消息队列概述 消息队列中间件是分布式系统中重要的组件,主要解决应用耦合、异步消息、流量削锋等问题。实现高性能、高可用、可伸缩和最终一致性架构。是大型分布式系...

    loostudy 评论0 收藏0
  • PHP基础

    摘要:分别为适配器模式,装饰器模式,代理模式,外观模式,桥接模式,组合模式,享元模式。设计模式五适配器模式适配器模式将某个对象的接生成器和协程的实现在这篇文章中,作者针对那些比较难以理解的概念,以一个更为通俗的方式去讲明白。。 PHP 源码注解 PHP 的详细源码注解 PHP 字符串操作整理 一些有关字符串的常用操作。 Redis 常见七种使用场景 (PHP 实战) 这篇文章主要介绍利用 R...

    HtmlCssJs 评论0 收藏0
  • 数据库收集 - 收藏集 - 掘金

    摘要:前言在使用加载数据数据库常见的优化操作后端掘金一索引将放第一位,不用说,这种优化方式我们一直都在悄悄使用,那便是主键索引。 Redis 内存压缩实战 - 后端 - 掘金在讨论Redis内存压缩的时候,我们需要了解一下几个Redis的相关知识。 压缩列表 ziplist Redis的ziplist是用一段连续的内存来存储列表数据的一个数据结构,它的结构示例如下图 zlbytes: 记录整...

    Little_XM 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<