redis消息通知系统的实现_redis 实现站内信通知-csdn博客


本站和网页 https://blog.csdn.net/csdn265/article/details/70146198 的作者无关,不对其内容负责。快照谨为网络故障时之索引,不代表被搜索网站的即时页面。

Redis消息通知系统的实现_redis 实现站内信通知-CSDN博客
Redis消息通知系统的实现
最新推荐文章于 2023-11-03 21:52:24 发布
csdn265 阅读量703 收藏 点赞数 分类专栏:
Redis Memcache
专栏收录该内容
12 篇文章
0 订阅
订阅专栏
最近忙着用Redis实现一个消息通知系统,今天大概总结了一下技术细节,其中演示代码如果没有特殊说明,使用的都是
PhpRedis
扩展来实现的。
内存
比如要推送一条全局消息,如果真的给所有用户都推送一遍的话,那么会占用很大的内存,实际上不管粘性有多高的产品,活跃用户同全部用户比起来,都会小很多,所以如果只处理登录用户的话,那么至少在内存消耗上是相当划算的,至于未登录用户,可以推迟到用户下次登录时再处理,如果用户一直不登录,就一了百了了。
队列
当大量用户同时登录的时候,如果全部都即时处理,那么很容易就崩溃了,此时可以使用一个队列来保存待处理的登录用户,如此一来顶多是反应慢点,但不会崩溃。
Redis的
LIST
数据类型可以很自然的创建一个队列,代码如下:
<?php
$redis = new Redis;
$redis->connect('/tmp/redis.sock');
$redis->lPush('usr', <USRID>);
while ($usr = $redis->rPop('usr')) {
var_dump($usr);
?>
出于类似的原因,我们还需要一个队列来保存待处理的消息。当然也可以使用LIST来实现,但LIST只能按照插入的先后顺序实现类似FIFO或LIFO形式的队列,然而消息实际上是有优先级的:比如说个人消息优先级高,全局消息优先级低。此时可以使用
ZSET
来实现,它里面分数的概念很自然的实现了优先级。
不过ZSET没有原生的POP操作,所以我们需要模拟实现,代码如下:
class RedisClient extends Redis
const POSITION_FIRST = 0;
const POSITION_LAST = -1;
public function zPop($zset)
return $this->zsetPop($zset, self::POSITION_FIRST);
public function zRevPop($zset)
return $this->zsetPop($zset, self::POSITION_LAST);
private function zsetPop($zset, $position)
$this->watch($zset);
$element = $this->zRange($zset, $position, $position);
if (!isset($element[0])) {
return false;
if ($this->multi()->zRem($zset, $element[0])->exec()) {
return $element[0];
return $this->zsetPop($zset, $position);
模拟实现了POP操作后,我们就可以使用ZSET实现队列了,代码如下:
$redis = new RedisClient;
$redis->zAdd('msg', <PRIORITY>, <MSGID>);
while ($msg = $redis->zRevPop('msg')) {
var_dump($msg);
推拉
以前微博架构中推拉选择的问题已经被大家讨论过很多次了。实际上消息通知系统和微博差不多,也存在推拉选择的问题,同样答案也是类似的,那就是应该推拉结合。具体点说:在登陆用户获取消息的时候,就是一个拉消息的过程;在把消息发送给登陆用户的时候,就是一个推消息的过程。
速度
假设要推送一百万条消息的话,那么最直白的实现就是不断的插入,代码如下:
for ($msgid = 1; $msgid <= 1000000; $msgid++) {
$redis->sAdd('usr:<USRID>:msg', $msgid);
说明:这里我使用了SET数据类型,当然你也可以视需求换成LIST或者ZSET。
Redis的速度是很快的,但是借助
PIPELINE
,会更快,代码如下:
for ($i = 1; $i <= 100; $i++) {
$redis->multi(Redis::PIPELINE);
for ($j = 1; $j <= 10000; $j++) {
$msgid = ($i - 1) * 10000 + $j;
$redis->exec();
说明:所谓PIPELINE,就是省略了无谓的折返跑,把命令打包给服务端统一处理。
前后两段代码在我的测试里,使用PIPELINE的速度大概是不使用PIPELINE的十倍。
查询
我们用Redis命令行来演示一下用户是如何查询消息的。
先插入三条消息,其<MSGID>分别是1,2,3:
redis> HMSET msg:1 title title1 content content1
redis> HMSET msg:2 title title2 content content2
redis> HMSET msg:3 title title3 content content3
再把这三条消息发送给某个用户,其<USRID>是123:
redis> SADD usr:123:msg 1
redis> SADD usr:123:msg 2
redis> SADD usr:123:msg 3
此时如果简单查询用户有哪些消息的话,无疑只能查到一些<MSGID>:
redis> SMEMBERS usr:123:msg
1) "1"
2) "2"
3) "3"
如果还需要用程序根据<MSGID>再来一次查询无疑有点低效,好在Redis内置的
SORT
命令可以达到事半功倍的效果,实际上它类似于SQL中的JOIN:
redis> SORT usr:123:msg GET msg:*->title
1) "title1"
2) "title2"
3) "title3"
redis> SORT usr:123:msg GET msg:*->content
1) "content1"
2) "content2"
3) "content3"
SORT的缺点是它只能GET出字符串类型的数据,如果你想要多个数据,就要多次GET:
redis> SORT usr:123:msg GET msg:*->title GET msg:*->content
2) "content1"
3) "title2"
4) "content2"
5) "title3"
6) "content3"
很多情况下这显得不够灵活,好在我们可以采用其他一些方法平衡一下利弊,比如说新加一个字段,冗余保存完整消息的序列化,接着只GET这个字段就OK了。
实际暴露查询接口的时候,不会使用PHP等程序来封装,因为那会成倍降低RPS,推荐使用
Webdis
,它是一个Redis的Web代理,效率没得说。
最近
Tumblr
发表了一篇类似的文章:
Staircar: Redis-powered notifications
,介绍了他们使用Redis实现消息通知系统的一些情况,有兴趣的不妨一起看看。
https://huoding.com/2012/02/29/146
优惠劵
关注
点赞
觉得还不错?
一键收藏
知道了
评论
最近忙着用Redis实现一个消息通知系统,今天大概总结了一下技术细节,其中演示代码如果没有特殊说明,使用的都是PhpRedis扩展来实现的。内存比如要推送一条全局消息,如果真的给所有用户都推送一遍的话,那么会占用很大的内存,实际上不管粘性有多高的产品,活跃用户同全部用户比起来,都会小很多,所以如果只处理登录用户的话,那么至少在内存消耗上是相当划算的,至于未登录用户,可以推迟
复制链接
扫一扫
专栏目录
redis
数据变化
通知
_深入学习
Redis
:哨兵
weixin_42468562的博客
01-12
602
前言在 深入学习
(3):主从复制 中曾提到,
主从复制的作用有数据热备、负载均衡、故障恢复等;但主从复制存在的一个问题是故障恢复无法自动化。本文将要介绍的哨兵,它基于
主从复制,主要作用便是解决主节点故障恢复的自动化问题,进一步提高
系统
的高可用性。文章主要内容如下:首先介绍哨兵的作用和架构;然后讲述哨兵
的部署方法,以及通过客户端访问哨兵
的方法;然后简要说明哨兵
实现
...
使用
的pubsub技术构建实时
消息
06-23
参与评论
您还未登录,请先
登录
后发表或查看评论
springboot 整合
订阅发布
brighthuacon的专栏
03-29
965
[转]
yuanlanjun
03-17
356
作者:老王
链接:http://huoding.com/2012/02/29/146
最近忙着用
一个
,今天大概总结了一下技术细节,其中演示代码如果没有特殊说明,使用的都是Php
扩展来
的。
比如要推送一条全局
,如果真的给所有用户都推送一遍的话,那么会占用很大的内存,实际上不管粘性有多高的产品,活跃用户同全部用户...
定时
weixin_48903815的博客
03-06
546
小事
(14):
water Wang
02-18
455
如何在博客中
邮件订阅功能。
邮件订阅功能太好
了,无非是在博客首页放一个文本框供访客输入自己的邮箱地址,提交后博客会将该地址存入
的一个集合类型键中(使用集合类型是为了保证同一 邮箱地址不会存储多个)。每当发布新文章时,就向收集到的邮箱地址发送
邮件。
想的简单,可是做出来后却发现了一个问题:输入邮箱地址提交后,页面需要很久时间才能载入完。
原来为了确保用户没有输入他人的邮箱,在提交之后程序会向用户输入的邮箱发送 一封包含确认链接的邮件,只有用户单击这个链接后对应的邮箱地址才会.
入门04-
Elaine2391的博客
11-03
371
中的
tianmo2010的专栏
09-02
1755
,如果真的给所有用户都推送一遍的话,那么会占用很大的内存,实际上不管粘性有多高的产品,活跃用户同全部用户比起来,都会小很多,所以如果只处理登录用户的话,那么至少在内存消耗上是相当划算的,至于未登录用户,可以推迟到用户
Java分布式中间件大汇聚实战第一季 (SpringBoot2.0+应用案例+点赞
+面试突击)
03-19
概要介绍:本门课程属于“Java分布式中间件大汇聚实战”系列课程,主要介绍了企业级项目中真实的应用场景的
及主流的Java核心技术栈(
、RabbitMQ、Spring AOP、
son、ZooKeeper…)的实战等等。除此之外,还介绍了如何基于
设计并实战一款点赞
(点赞、取消点赞、排行榜、用户中心、文章点赞用户列表…)可以说技术干货甚多,不仅可以巩固企业级应用
的开发实战能力,相信在面试、跳槽涨薪方面也能带来相应的帮助!课程内容:传说中的金三银四、面试跳槽涨薪季已经来临,Debug特地为大家准备了一系列跟面试、跳槽、巩固核心技术栈相关的课程,本门课程属于第一季,其中的内容包括企业级项目中真实的应用场景实战、面试相关的技术点分享、主流的Java技术栈(Undertow、
son、ZooKeeper…)实战等等。除此之外,我们还基于
设计并实战了一款点赞
,可以说技术干货甚多。在课程的最后,Debug给大家整理了一份最新的面向BAT大厂招聘 ~ 2020年程序猿最新的Java面试题(附带目录和答案),希望对各位小伙伴的成长有所帮助!值得一提的是,本季课程实战的应用场景包括“日志记录”、“邮件发送”、“通告
”、“短信验证码失效验证”、“会员到期自动提醒/到期前N天自动提醒”以及“点赞
”的设计与实战,其大纲如下所示:其中,涉及到的技术栈包括Spring Boot2.0、Mybatis、Undertow、
、RabbitMQ、
son、Spring AOP、 Java8…下面罗列出本门课程重点介绍的价格应用案例以及业务场景的
流程图!(1)基于Spring的
驱动模型
日志的异步记录:(2)基于
中间件RabbitMQ的
日志的异步记录:(3)基于缓存中间件
的订阅发布机制
商户公告
:(4)基于
的Key失效与定时任务
短信验证码的过期失效验证:其他核心、典型的应用案例和业务场景的实战可以详细参考“课程目录”!除此之外,我们还基于缓存中间件
设计并实战
了点赞
中的点赞功能模块,下面罗列出其中涉及到的相关功能模块的实战流程图:其课程收益如下所示:
数据结构--知识点16--搜索算法(二叉树)
ANingL的博客
09-06
2806
文章目录一、树的概念1、特点2、树的术语3、树的种类4、树的存储与表示5、常见的树的应用场景二、二叉树1、概念2、性质
一、树的概念
树是一种抽象数据类型(ADT)或是视作这种抽象数据类型的数据结构
1、特点
每个节点有零个或多个子节点
没有父节点的节点称为根节点
每一个非根节点有且只有一个父节点
除了根节点外,每个子节点可以分为**多个不相交(因为都只有一个父节点)**的子树
2、树的术语
节点的度:一个节点含有的子树的个数称为该节点的度
树的度:一棵树中,最大的节点的度称为树的度
叶节点或终端节点
springboot中使用
异步
cdy1996的博客
11-10
4072
为什么我要用
来完成异步
,而不是
队列mq之类的?
因为很多的单体项目可能只需要需要一个略微简单的
,而不需要如kafka那种完善的
队列,
而且
在正常的项目中基本都会引入而mq可能较少会引入,所以使用
可以减少不必要的中间件引入和维护.
 
设计思路的来源
主要借鉴了spring对jms的封装,比如使用注解@JmsListener来完...
php基于
推送的方法
10-17
主要介绍了php基于
推送的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
延迟
需求背景
最近在做一个排队取号的
在用户预约时间到达前XX分钟发短信
在用户预约时间结束时要判断用户是否去取号了,不然就记录为爽约 在用户取号后开始,等待XX分钟后要发短信...
发布订阅和
.NET客户端详解
12-16
前言 发布订阅在设计模式中也可以说是观察者模式,针对这个模式是处理对象间一对多的依赖关系的,当一个对象发生变化,其它依赖...那么如此一来,升级到
项目级别,他别给我们又带来啦,莫大的好处,便是:剥离
SpringBoot+MySQL+
+MyBatis
的校园论坛项目源代码+详细使用说明文档
06-16
用户点赞关注后,使用kafka
异步的发送
开发环境 构建工具:Apache Maven 集成开发工具: IntelliJ IDEA 2021 数据库:MySQL、
应用服务器:Apache Tomcat 框架:Spring、SpringMVC、Mybatis、...
前后端分离vue前端项目---员工管理
(vue+springboot+
06-28
的功能更具体的包括有:员工管理、部门管理、岗位管理、菜单管理、角色管理、字典管理、参数管理、
公告、操作日志、登录日志、在线用户、定时任务、代码生成、
接口、服务监控、缓存监控、在线构建器、...
最详细
学习资料(源码)
11-16
发布/订阅:
提供了发布/订阅功能,能够
的异步发布和订阅,适用于实时
、事件驱动等场景。
分布式支持:
提供了分布式部署和数据分片功能,能够构建高可用性、可扩展性的分布式
高性能:...
C#,数值计算,解微分方程的龙格-库塔二阶方法与源代码
04-25
微分方程
含有导数或微分的方程称为微分方程,未知函数为一元函数的微分方程称为常微分方程。
微分方程的阶数
微分方程中导数或微分的最高阶数称为微分方程的阶数。
微分方程的解
使得微分方程成立的函数称为微分方程的解。
微分方程的特解
微分方程的不含任意常数的解称为微分方程的特解。
微分方程的通解
所含相互独立的任意常数的个数与微分方程的阶数相等的微分方程的解称为微分方程的通解。
桌面聊天室
最新发布
该毕业设计采用了c/s架构,通过javase中的知识编写完成,
功能包括:用户注册,用户登录,聊天功能。
对于刚学完java基础的同学来说可以通过该毕业设计加深对所学知识的理解。该
使用socket进行数据的发送,用户注册登录之后,可以进行多人聊天,功能类似qq群聊。
交易数据实时监控
实战
06-10
是一个高性能的键值存储数据库,通过使用
的发布/订阅功能,可以
首先,我们需要将交易数据存储到
中。可以使用
的数据结构,如List或Hash,来存储交易数据。每当有新的交易数据到达时,我们可以将其推送到
中。这可以通过使用
的PUBLISH命令来
然后,我们需要一个订阅者来订阅
中的交易数据。可以使用
的SUBSCRIBE命令来订阅一个或多个频道。当新的交易数据到达时,订阅者将自动收到
最后,我们可以将交易数据实时显示在前端界面上。可以使用WebSockets来
实时通信。每当有新的交易数据到达时,后端将数据发送到前端,前端将自动将数据显示在界面上。
总结一下,
的步骤如下:
1. 将交易数据存储到
中。
2. 使用
的发布/订阅功能来
实时监控。
3. 使用WebSockets来
实时通信。
4. 将交易数据实时显示在前端界面上。
“相关推荐”对你有帮助么?
非常没帮助
没帮助
一般
有帮助
非常有帮助
提交
CSDN认证博客专家
CSDN认证企业博客
码龄8年
暂无认证
10
原创
13万+
周排名
207万+
总排名
62万+
访问
等级
4680
积分
109
粉丝
79
获赞
25
263
私信
热门文章
cron和crontab命令详解 crontab 每分钟、每小时、每天、每周、每月、每年定时执行 crontab每5分钟执行一次
176181
linux打开80端口及80端口占用解决办法
34369
五种利用strace查故障的简单方法
17314
电商后台系统:管理后台篇之库存管理
14961
京东高并发抢购系统的核心逻辑与架构实现
13227
分类专栏
Mysql
48篇
Linux
33篇
PHP
28篇
Note
1篇
Architecture
29篇
Golang
13篇
Nginx Apache
12篇
ActiveMQ RabbitMQ
8篇
Javascript
14篇
Python
ES Sphinx Solr
17篇
Other
4篇
Zookeeper
socket网络编程
6篇
数据分析
3篇
测试工具
最新评论
linux下php调用unoconv命令将doc,ppt转pdf,pdf在转图片
qq_43789643:
你好,word转pdf后样式乱了怎么处理的
注意使用 BTREE 复合索引各字段的 ASC/DESC 以优化 order by 查询效率
悠然的路人丙:
智商被摩擦,最后写回来了
ssh访问控制,多次失败登录即封掉IP,防止暴力破解
大家一起学编程(python):
nginx/tengine限制流量如何配置
Tisfy:
这篇帖子,就好比黑暗中刺裂夜空的闪电
鱼缸前的猫吖:
您好。请问有源码吗?
您愿意向朋友推荐“博客详情页”吗?
强烈不推荐
不推荐
一般般
推荐
强烈推荐
最新文章
nginx 跳转www的方式
Linux-CentOS 安装Unoconv
2021年
2019年
7篇
2018年
18篇
2017年
141篇
2016年
75篇
目录
被折叠的 
 条评论
为什么被折叠?
到【灌水乐园】发言
查看更多评论
添加红包
祝福语
请填写红包祝福语或标题
红包数量
红包个数最小为10个
红包总金额
红包金额最低5元
余额支付
当前余额
3.43
前往充值 >
需支付:
10.00
取消
确定
下一步
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝
规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额
抵扣说明:
1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。
余额充值