redis延迟队列php,php redis延迟队列,redis延迟队列

简介: redis延迟队列php,php redis延迟队列,redis延迟队列

记得在上一家公司时公司没有延迟队列,直接使用redis list进行使用,如果不到执行时间则继续丢回去,这样的方式太浪费IO,而且没办法保证执行顺序。本文没有使用有赞的redis延迟队列设计,使用的是redis有序集合的特性来完成。大致思路如下:

(1).下单成功通过zadd key score value命令把订单信息写入到集合中,例如

key:order

score:指定要执行的时间戳(单位秒)

value:订单id

集合的最终元素成员如下

score          value

1603620459     202010250100

1603620460     202010250101

(2).通过zrangebyscore命令取需要执行的元素,例如

ZRANGEBYSCORE order (0 1603620500

例如查询score大于0,并且score小于当前时间戳的数据

(3).查询到数据我们应该从集合中删除此元素,使用zrem命令即可,如果删除的失败,说明已经被其他进程消费,可以丢弃。

我编写了一个PHP的实现。

<?php


class DelayQueue

{

   /**

    * name

    * @var string|null

    */

   public static $name = null;


   /**

    * Redis_Handler

    * @var Redis|null

    */

   public static $handler = null;


   /**

    * add

    * @param int $score

    * @param string $value

    * @return int

    */

   public static function add($score, $value)

   {

       return static::$handler->zAdd(static::$name, $score, $value);

   }


   /**

    * get

    * @param int $e_score

    * @param int $s_score

    * @param int $limit

    * @param bool $remove

    * @return array

    */

   public static function get($e_score, $s_score = 0, $limit = 10, $remove = true)

   {

       $list = static::$handler->zRangeByScore(static::$name, $s_score, $e_score, ['limit' => [0, $limit]]);

       if ($remove)

       {

           foreach ($list as $key => $value)

           {

               if (!static::del($value)) unset($list[$key]);

           }

       }


       return $list;

   }


   /**

    * del

    * @param $value

    * @return int

    */

   public static function del($value)

   {

       return static::$handler->zRem(static::$name, $value);

   }

}

(4).生成者的代码:

//1.加载Redis

$redis = new Redis();

$redis->connect('127.0.0.1', 6379);


//2.设置延迟队列

DelayQueue::$name = 'order';

DelayQueue::$handler = $redis;


//3.投递队列

$time = time() + 30; //下单成功30秒需要处理

$orderId = uniqid();

DelayQueue::add($time, $orderId);

(5).消费者代码:

//1.加载Redis

$redis = new Redis();

$redis->connect('127.0.0.1', 6379);


//2.设置延迟队列

DelayQueue::$name = 'order';

DelayQueue::$handler = $redis;


//3.查询时间小于当前时间的队列数据,默认输出10条

$time = time();

$list = DelayQueue::get($time);

foreach ($list as $value)

{

   //输出信息

   echo "订单Id:" . $value . PHP_EOL;


   //发送消息给订单关联的用户(伪代码)

   //sendMsgToUserByOrderId($value);

}

(6).其他从队列取值的写法说明:

(1).在队列中查询time<=1603597141 and time>=0 的元素(同时队列中会自动删除符合条件的元素)

$time = 1603597141;

$list = DelayQueue::get($time);


(2).在队列中查询time<=1603597141 and time>=1603597132 的元素(同时队列中会自动删除符合条件的元素)

$time1 = 1603597413;

$time2 = 1603597132;

$list = DelayQueue::get($time1, $time2);


(3).在队列中查询time<=1603597141 and time>=1603597132 的元素,只返回1条(同时队列中会自动删除这条元素)

$time1 = 1603597555;

$time2 = 1603597132;

$list = DelayQueue::get($time1, $time2,1);


(4).在队列中查询time<=1603597141 and time>=1603597132 的元素返回10条即可,不删除队列数据,仅查看数据

$time1 = 1603597693;

$time2 = 1603597132;

$list = DelayQueue::get($time1, $time2, 10, false);

(7).解决有序集合元素值不得重复的问题:

Redis有序集合中元素内容不得重复,上面实例中都是传递的订单Id,如果我们想投递多次相同订单Id,何如?

(1).Value中传递唯一Id,同订单Id组合的Json形式,例如

$data = [

   'order_id'=>1,

   'order_uniqid'=>uniqid()

];

$res =  DelayQueue::add(time() + 30, json_encode($data));

(2).Value中前X位存储订单Id,后X位存储唯一Id(推荐)

有序集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。 集合中最大的成员数为 232 - 1 (4294967295, 每个集合可存储40多亿个成员)。

目录
相关文章
|
12月前
|
存储 监控 NoSQL
使用Redis实现延迟消息发送功能
使用 Redis 的密码认证功能,为实例设置密码以防止未授权访问。为消息提供适当加密,确保消息内容在网络传输过程中不被窃取或篡改。
431 16
|
缓存 监控 算法
内网监控管理软件:PHP 语言队列算法揭秘
在数字化办公环境中,内网监控管理软件对企业的稳定运行和信息安全至关重要。本文深入介绍PHP中的队列算法及其在内网监控软件中的应用,包括监控数据收集、任务调度和日志记录等场景,通过代码示例展示其实现方法。队列算法可提高性能、保证数据顺序并实现异步处理,为企业提供高效的安全保障。
249 1
|
缓存 NoSQL PHP
Redis作为PHP缓存解决方案的优势、实现方式及注意事项。Redis凭借其高性能、丰富的数据结构、数据持久化和分布式支持等特点,在提升应用响应速度和处理能力方面表现突出
本文深入探讨了Redis作为PHP缓存解决方案的优势、实现方式及注意事项。Redis凭借其高性能、丰富的数据结构、数据持久化和分布式支持等特点,在提升应用响应速度和处理能力方面表现突出。文章还介绍了Redis在页面缓存、数据缓存和会话缓存等应用场景中的使用,并强调了缓存数据一致性、过期时间设置、容量控制和安全问题的重要性。
337 5
|
设计模式 NoSQL Go
Redis 实现高效任务队列:异步队列与延迟队列详解
本文介绍了如何使用 Redis 实现异步队列和延迟队列。通过 Go 语言的 `github.com/go-redis/redis` 客户端,详细讲解了 Redis 客户端的初始化、异步队列的实现和测试、以及延迟队列的实现和测试。文章从基础连接开始,逐步构建了完整的队列系统,帮助读者更好地理解和应用这些概念,提升系统的响应速度和性能。
395 6
|
存储 NoSQL 关系型数据库
PHP 使用 Redis
10月更文挑战第22天
294 6
|
存储 NoSQL PHP
PHP与Redis结合使用,提升数据存储性能
随着互联网应用的发展,PHP与Redis的结合成为提升数据存储性能的重要手段。PHP作为流行的服务器端语言,常用于网站开发;Redis作为高性能内存数据库,以其快速读写能力,有效优化数据访问速度,减轻数据库压力。两者结合通过缓存机制显著提升应用响应速度,支持高并发场景下的稳定性和可扩展性。
|
消息中间件 存储 NoSQL
如何用Redis实现延迟队列?
综上所述,通过Redis的有序集合和一些基本命令,我们可以轻松地构建出功能完善的延迟队列系统。根据具体需求,可以进一步优化和扩展,以满足高性能和高可靠性的业务需求。
572 1
|
缓存 NoSQL 数据处理
原生php实现redis缓存配置和使用方法
通过上述步骤,你可以在PHP项目中配置并使用Redis作为高性能的缓存解决方案。合理利用Redis的各种数据结构和特性,可以有效提升应用的响应速度和数据处理效率。记得在实际应用中根据具体需求选择合适的缓存策略,如设置合理的过期时间,以避免内存过度消耗。
482 0
|
12月前
|
缓存 NoSQL 关系型数据库
美团面试:MySQL有1000w数据,redis只存20w的数据,如何做 缓存 设计?
美团面试:MySQL有1000w数据,redis只存20w的数据,如何做 缓存 设计?
美团面试:MySQL有1000w数据,redis只存20w的数据,如何做 缓存 设计?
|
7月前
|
缓存 负载均衡 监控
135_负载均衡:Redis缓存 - 提高缓存命中率的配置与最佳实践
在现代大型语言模型(LLM)部署架构中,缓存系统扮演着至关重要的角色。随着LLM应用规模的不断扩大和用户需求的持续增长,如何构建高效、可靠的缓存架构成为系统性能优化的核心挑战。Redis作为业界领先的内存数据库,因其高性能、丰富的数据结构和灵活的配置选项,已成为LLM部署中首选的缓存解决方案。
759 25