广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >Redis如何批量设置过期时间(PIPLINE的使用)
  • 365
分享到

Redis如何批量设置过期时间(PIPLINE的使用)

2024-04-02 19:04:59 365人浏览 薄情痞子
摘要

合理的使用缓存策略对开发同学来讲,就好像孙悟空习得自在极意功一般~ Redis如何批量设置过期时间呢? 不要说在foreach中通过set()函数批量设置过期时间 我们引入redis

合理的使用缓存策略对开发同学来讲,就好像孙悟空习得自在极意功一般~

Redis如何批量设置过期时间呢?

不要说在foreach中通过set()函数批量设置过期时间

我们引入redis的PIPLINE,来解决批量设置过期时间的问题。

PIPLINE的原理是什么?

未使用pipline执行N条命令

使用pipline执行N条命令

通过图例可以很明显的看出来PIPLINE的原理:

客户端通过PIPLINE拼接子命令,只需要发送一次请求,在redis收到PIPLINE命令后,处理PIPLINE组成的命令块,减少了网络请求响应次数。

网络延迟越大PIPLINE的优势越能体现出来

拼接的子命令条数越多使用PIPLINE的优势越能体现出来

注意:并不是拼接的子命令越多越好,N值也有是上限的,当拼接命令过长时会导致客户端等待很长时间,造成网络堵塞;我们可以根据实际情况,把大批量命令拆分成几个PIPLINE执行。

代码封装


//批量设置过期时间
public static function myPut(array $data, $ttl = 0)
{
    if (empty($data)) {
        return false;
    }

    $pipeline = Redis::connection('cache')
        ->multi(\Redis::PIPELINE);
    foreach ($data as $key => $value) {
        if (empty($value)) {
            continue;
        }
        if ($ttl == 0) {
            $pipeline->set(trim($key), $value);
        } else {
            $pipeline->set(trim($key), $value, $ttl);
        }
    }
    $pipeline->exec();
}

项目实战

需求描述

  • 打开APP,给喜欢我的人发送我的上线通知(为了避免打扰,8小时内重复登录不触发通知)
  • 每个人每半小时只会收到一次这类上线通知(即半小时内就算我喜欢的1万人都上线了,我也只收到一次喜欢的人上线通知)

要点分析

  • 合理使用缓存,减少DB读写次数
  • 不仅要减少DB读写次数,也要减少Redis的读写次数,使用PIPLINE

代码实现解析

  • canRecall() 写的比较优雅,先判断是否已发送的标记,再判断HouseOpen::getCurrentOpen(),因为HouseOpen::getCurrentOpen()是要查询DB计算的,这种代码要尽可能少的被执行到,减少DB查询。
  • array_diff() 取差集的思路,获得需要推送的人

封装工具


<?PHP
namespace App\Model\House;
.
.
.
class HouseLikeRecallUser
{
    protected $_userid = '';
    protected $_availableUser = [];
    protected $_recallFlagKey = '';

    const TYPE_TTL_HOUSE_LIKE_RECALL = 60 * 30; //半小时后可以再次接收到喜欢的xxx进入通知
    const TYPE_TTL_HOUSE_LIKE_RECALL_FLAG = 60 * 60 * 8; //8小时重复登录不触发

    //初始化 传入setRecalled 的过期时间
    public function __construct($userid)
    {
        $this->_userid = $userid;
        //登录后给喜欢我的人推送校验:同一场次重复登录不重复发送
        $this->_recallFlagKey = CacheKey::getCacheKey(CacheKey::TYPE_HOUSE_LIKE_RECALL_FLAG, $this->_userid);
    }

    //设置当前用户推送标示
    public function setRecalled()
    {
        Cache::put($this->_recallFlagKey, 1, self::TYPE_TTL_HOUSE_LIKE_RECALL_FLAG);
    }

    //获取当前用户是否触发推送
    public function canRecall()
    {
        $res = false;
        if (empty(Cache::get($this->_recallFlagKey))) {
            $houseOpen = HouseOpen::getCurrentOpen();
            if ($houseOpen['status'] == HouseOpen::HOUSE_STATUS_OPEN) {
                $res = true;
            }
        }
        return $res;
    }

    //获取需要推送用户
    public function getAvailableUser()
    {
        //获得最近喜欢我的用户
        $recentLikeMeUser = UserRelationSingle::getLikeMeUserIds($this->_userid, 100, Utility::getBeforeNDayTimestamp(7));

        //获得最近喜欢我的用户的 RECALL缓存标记
        foreach ($recentLikeMeUser as $userid) {
            $batchKey[] = CacheKey::getCacheKey(CacheKey::TYPE_HOUSE_LIKE_RECALL, $userid);
        }

        //获得最近喜欢我的且已经推送过的用户
        $cacheData = [];
        if (!empty($batchKey)) {
            $cacheData = Redis::connection('cache')->mget($batchKey);
        }

        //计算最近喜欢我的用户 和 已经推送过的用户 的差集:就是需要推送的用户
        $this->_availableUser = array_diff($recentLikeMeUser, $cacheData);
        return $this->_availableUser;
    }

    //更新已经推送的用户
    public function updateRecalledUser()
    {
        //批量更新差集用户
        $recalledUser = [];
        foreach ($this->_availableUser as $userid) {
            $cacheKey = CacheKey::getCacheKey(CacheKey::TYPE_HOUSE_LIKE_RECALL, $userid);
            $recalledUser[$cacheKey] = $userid;
        }
        //批量更新 设置过期时间
        self::myPut($recalledUser, self::TYPE_TTL_HOUSE_LIKE_RECALL);
    }

    //批量设置过期时间
    public static function myPut(array $data, $ttl = 0)
    {
        if (empty($data)) {
            return false;
        }

        $pipeline = Redis::connection('cache')
            ->multi(\Redis::PIPELINE);
        foreach ($data as $key => $value) {
            if (empty($value)) {
                continue;
            }
            if ($ttl == 0) {
                $pipeline->set(trim($key), $value);
            } else {
                $pipeline->set(trim($key), $value, $ttl);
            }
        }
        $pipeline->exec();
    }
}

调用工具类


public function handle()
{
    $userid = $this->_userid;
    $houseLikeRecallUser = new HouseLikeRecallUser($userid);
    if ($houseLikeRecallUser->canRecall()) {
        $recallUserIds = $houseLikeRecallUser->getAvailableUser();
        $houseLikeRecallUser->setRecalled();
        $houseLikeRecallUser->updateRecalledUser();
        //群发推送消息
        .
        .
        .
    }
}

总结

不同量级的数据需要不同的处理办法,减少网络请求次数,合理使用缓存,是性能优化的必经之路。

进一步思考

如果我喜欢的1万人同时上线(秒级并发),我只收到一个消息推送,要避免被通知轰炸,怎么解决这类并发问题呢?

到此这篇关于Redis 如何批量设置过期时间(PIPLINE的使用)的文章就介绍到这了,更多相关Redis 批量设置过期时间内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Redis如何批量设置过期时间(PIPLINE的使用)

本文链接: https://www.lsjlt.com/news/158194.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Redis如何批量设置过期时间(PIPLINE的使用)
    合理的使用缓存策略对开发同学来讲,就好像孙悟空习得自在极意功一般~ Redis如何批量设置过期时间呢? 不要说在foreach中通过set()函数批量设置过期时间 我们引入redis...
    99+
    2022-11-12
  • Redis怎么批量设置过期时间
    这篇文章将为大家详细讲解有关Redis怎么批量设置过期时间,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。Redis如何批量设置过期时间呢?不要说在foreach中通过set()函数批量设置过期时间我们引入...
    99+
    2023-06-21
  • redis如何设置过期时间
    redis如何设置过期时间?相信很多新手小白还没学会这个技能,通过这篇文章的总结,希望你能学会这个技能。以下资料是实现的步骤。1、Redis中key的过期时间通过EXPIRE key seconds命令来设...
    99+
    2022-10-18
  • php redis如何设置过期时间
    本文将为大家详细介绍“php redis如何设置过期时间”,内容步骤清晰详细,细节处理妥当,而小编每天都会更新不同的知识点,希望这篇“php redis如何设置过期时间”能够给你意想不到的收获,请大家跟着小编的思路慢慢深入,具体内容如下,一...
    99+
    2023-06-06
  • redis如何设置不过期时间
    在 Redis 中设置键不过期的方法有两种:1. 不设置过期时间:在设置键时,不指定过期时间参数即可。例如使用 `SET key v...
    99+
    2023-09-05
    redis
  • redis缓存过期时间如何设置
    在Redis中,可以通过使用EXPIRE命令来设置缓存的过期时间。语法如下:```EXPIRE key seconds```其中,k...
    99+
    2023-08-30
    redis
  • 如何设置合适的redis过期时间
    这篇文章运用简单易懂的例子给大家介绍如何设置合适的redis过期时间,代码非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。          ...
    99+
    2022-10-18
  • 如何为redis设置缓存过期时间
    你可以使用EXPIRE命令来为Redis设置缓存过期时间。下面是设置缓存过期时间的步骤:1. 使用EXPIRE命令设置缓存的过期时间...
    99+
    2023-09-11
    redis
  • 如何使用localStorage 设置过期时间
    这篇文章将为大家详细讲解有关如何使用localStorage 设置过期时间,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。localStorage除非人为手动清除,否则会一直存放在浏览器中,但...
    99+
    2023-06-09
  • 如何设置localStorage的过期时间
    这期内容当中小编将会给大家带来有关如何设置localStorage的过期时间,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。<script type="text/javascrip...
    99+
    2023-06-09
  • Springsecurity Oauth2如何设置token的过期时间
    1.设置token的过期时间 如果我们是从数据库来读取客户端信息的话 我们只需要在数据库设置token的过期时间 1.1 oauth_client_details表每个列的作...
    99+
    2022-11-12
  • springboot项目如何设置session的过期时间
    目录这里我们只介绍springboot2.0的session时间设置下面这种方式是设置24小时的或者使用第二种方式springboot设置session失效的几种方式如果是1.5.6...
    99+
    2022-11-13
  • PHP如何将cookie的过期时间设置为过去
    这篇文章主要介绍了PHP如何将cookie的过期时间设置为过去,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。将cookie的过期时间设置为过去<phpsetcookie...
    99+
    2023-06-17
  • SpringBoot使用@Cacheable时设置部分缓存的过期时间方式
    目录使用@Cacheable时设置部分缓存的过期时间业务场景添加Redis配置类RedisConfig.java@Cacheable自定义缓存过期时间pomymlRedisConfi...
    99+
    2022-11-12
  • Java如何设置过期时间的map的几种方法
    目录一、技术背景二、技术效果三、ExpiringMap3.1功能简介3.2源码3.3示例四、LoadingCache4.1功能简介4.2示例4.3移除机制4.4其他五、HashMap...
    99+
    2022-11-13
  • Vue.js中如何使用iView日期选择器并设置开始时间结束时间校验功能
    这篇文章将为大家详细讲解有关Vue.js中如何使用iView日期选择器并设置开始时间结束时间校验功能,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。具体代码如下所述:<...
    99+
    2022-10-19
  • JavaScript中Cookie的使用之如何设置失效时间
    目录1.什么是Cookie?1.1简介1.2特点2.JavaScript操作Cookie2.1基础操作2.2设置失效时间总结1.什么是Cookie? 1.1简介 主要用于存储访问过的...
    99+
    2022-12-08
    JavaScript Cookie Cookie的使用 Cookie设置失效时间
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作