到点提醒功能如何实现简单,不如试试Redis

如题所述

第1个回答  2022-07-05

我们经常在网上看到某个活动,如果活动还没开始 ,我们经常可以到点提醒我,那么,到点提醒这个功能,该如何实现呢?

如果我们使用多台机器,又有可能存在并发问题,例如A机器跟B机器同时读到用户甲需要发送提醒,用户就有可能同时收到两条提醒。为了避免这个问题,我们可能需要使用Redis实现一个分布式锁。那么我们有没有其他方案呢?

今天我们来分享一个使用Redis实现的延迟队列,在此之前,我们分享过Redis的基本数据结构,我们都知道,Redis有5种基本数据结构,字符串、队列、哈希、集合与有序集合。今天我们就要用有序集合,来实现一个延迟队列的功能。

我们都知道,有序集合的内部是一个跳表+哈希,跳表的一个特点是能够保证数据的有消息,所以我们就能把任务的执行时间按照从小到大的时间排序,队首的元素就是需要最早执行的任务。这里我们简单地学习几个Redis的命令,分别是添加ZADD,移除ZREM,与查询ZRANGEBYSCORE。

#ZADD 集合名 分数 关键字

#ZRANGEBYSCORE 集合名 最小值 最大值

每一秒钟,我们都可以用这个去查询当前需要执行的任务有哪一些,例如当前的时间戳为1558193281,那么我们只要执行命令 ZRANGEBYSCORE 集合名 0 1558193281, 就能查询到在此之前有多少任务满足条件。

#ZREM 集合名 内容

当我们查询到有哪些任务需要执行的时候,我们需要将他们移除,这样子才不会被其他任务所执行。这个命令就是用来移除对应的任务。

这里,可能有同学就会想到,如果多台机器获取到同一个任务,那岂不是会冲突么?好在我们可以使用lua script帮我们把查询跟删除的命令变成再服务端的一次原子操作。只要简单的几个命令,我们就能够实现一个延迟队列。剩下的时间,我们可以用来研究怎么找对象了。

如果细心的同学机会发现,用Redis实现的延迟队列,并不能保证可用性100%,有可能会丢消息。这里的有如下这些原因:

1.redis主备之间可能存在一致性问题,如果部署redis的主机挂了可能会丢数据。

2.在机器取到任务的时候,就把任务删除了,如果这个时候死机或者发送失败,也会丢消息

相似回答