Python中的 redis keyspace 通知
介绍
Redis是内存中的数据结构存储,用于缓存、高速数据摄取、处理消息队列、分布式锁定等等。
与其他内存存储相比,使用Redis的优势在于它提供了持久性和数据结构,比如列表、集合、排序集合和散列。
在这篇文章中,介绍一个Redis keyspace通知的简短概述。并演示如何配置Redis来接收它们。并展示如何在python中订阅Redis通知
在开始之前,请安装并启动Redis服务器,如下所述:https://redis.io/topics/quickstart
启用通知
默认情况下,redis的通知事件是关闭的,在终端执行以下命令开启:
- $ redis-cli config set notify-keyspace-events KEA
- OK
KEA字符串表示启用了所有可能的事件。要查看每个字符的含义,请查看文档
CLI 可以在特殊模式下工作,允许您订阅一个通道以接收消息。
现在检查事件是否起作用:
- # 用于检查事件
- # psubscribe '*'表示我们想订阅所有带有模式*的事件
- $ redis-cli --csv psubscribe '*'
- Reading messages... (press Ctrl-C to quit)
- "psubscribe","*",1
开启一个新的终端,设置一个值
- 127.0.0.1:6379> set key1 value1
- OK
在上一个终端,会看到:
- $ redis-cli --csv psubscribe '*'
- Reading messages... (press Ctrl-C to quit)
- "psubscribe","*",1
- "pmessage","*","__keyspace@0__:key1","set"
- "pmessage","*","__keyevent@0__:set","key1
发现通知是工作中的
复述
Redis的键盘空间通知从2.8.0版起就可以使用了。对于更改任何Redis键的每个操作,可以配置Redis将消息发布到发布/订阅。然后可以订阅这些通知。值得一提的是,事件仅在确实修改了键的情况下才生成。例如,删除不存在的键将不会生成事件。
以上收到三个事件:
- "psubscribe","*",1
- "pmessage","*","__keyspace@0__:key1","set"
- "pmessage","*","__keyevent@0__:set","key1
- 第一个事件意味着已经成功订阅了reply中作为第二个元素给出的通道。1 表示目前订阅的频道数量。
- 第二个事件是键空间通知。在keyspace通道中,接收事件集的名称作为消息。
- 第三个事件是键-事件通知。在keyevent通道中,接收到key key1的名称作为消息。
Redis Pub/Sub
事件是通过Redis的Pub/Sub层交付的。
为了订阅channel channel1和channel2,客户端发出带有通道名称的subscribe命令
在Python中订阅通知
第一步,需要python操作redis的包
- $ pip install redis
事件循环,请看以下代码:
- import time
- from redis import StrictRedis
- redis = StrictRedis(host='localhost', port=6379)
- # redis 发布订阅
- pubsub = redis.pubsub()
- # 监听通知
- pubsub.psubscribe('__keyspace@0__:*')
- # 开始消息循环
- print('Starting message loop')
- while True:
- # 获取消息
- message = pubsub.get_message()
- if message:
- print(message)
- else:
- time.sleep(0.01)
分析:
这是创建 `redis` 连接的代码
- redis = StrictRedis(host='localhost', port=6379)
默认情况下,所有响应都以字节的形式返回。用户负责解码。如果客户机的所有字符串响应都应该被解码,那么用户可以指定decode_responses=True to StrictRedis。在这种情况下,任何返回字符串类型的Redis命令都将用指定的编码进行解码。
接下来,创建一个订阅频道并侦听新消息的pubsub对象:
- pubsub = redis.pubsub()
- pubsub.psubscribe('__keyspace@0__:*')
继而通过一个无限循环来等待事件
- while True:
- message = pubsub.get_message()
- ...
如果有数据,get_message()将读取并返回它。如果没有数据,该方法将不返回任何数据。
从pubsub实例中读取的每条消息都是一个字典,其中包含以下键:
- type 以下之一:订阅,取消订阅,psubscribe, punsubscribe, message, pmessage
- channel 订阅消息的通道或消息发布到的通道
- pattern 与已发布消息的通道匹配的模式(除pmessage类型外,在所有情况下都不匹配)
- data 消息数据
现在启动 `python` 脚本,在终端中设置一个key值
- 127.0.0.1:6379> set mykey myvalue
- OK
将看到脚本以下输出
- $ python subscribe.py
- Starting message loop
- {'type': 'psubscribe', 'data': 1, 'channel': b'__keyspace@0__:*', 'pattern': None}
- {'type': 'pmessage', 'data': b'set', 'channel': b'__keyspace@0__:mykey', 'pattern': b'__keyspace@0__:*'}
回调注册
注册回调函数来处理已发布的消息。消息处理程序接受一个参数,即消息。要使用消息处理程序订阅通道或模式,请将通道或模式名称作为关键字参数传递,其值为回调函数。当使用消息处理程序在通道或模式上读取消息时,将创建消息字典并将其传递给消息处理程序。在这种情况下,get_message()返回一个None值,因为消息已经被处理
- import time
- from redis import StrictRedis
- redis = StrictRedis(host='localhost', port=6379)
- pubsub = redis.pubsub()
- def event_handler(msg):
- print('Handler', msg)
- pubsub.psubscribe(**{'__keyspace@0__:*': event_handler})
- print('Starting message loop')
- while True:
- message = pubsub.get_message()
- if message:
- print(message)
- else:
- time.sleep(0.01)
事件循环在单独的线程中
选择是在单独的线程中运行事件循环
- import time
- from redis import StrictRedis
- redis = StrictRedis(host='localhost', port=6379)
- def event_handler(msg):
- print(msg)
- thread.stop()
- pubsub = redis.pubsub()
- pubsub.psubscribe(**{'__keyevent@0__:expired': event_handler})
- thread = pubsub.run_in_thread(sleep_time=0.01)
总结
Redis的一个常见用例是,应用程序需要能够响应存储在特定键或键中的值可能发生的更改。由于有了键盘空间通知和发布/订阅,可以对Redis数据中的变化做出响应。通知很容易使用,而事件处理器可能在地理位置上分布。
最大的缺点是,Pub/Sub的实现要求发布者和订阅方始终处于启动状态。用户在停止或连接丢失时丢失数据。
参考文献
- https://redis.io/topics/notifications - Redis keyspace notifications documentation
- https://redis.io/topics/pubsub - Redis Pub/Sub documentation
- https://github.com/andymccurdy/redis-py - Python client for Redis
- https://www.infoworld.com/article/3212768/database/how-to-use-redis-for-real-time-stream-processing.html - How to use Redis for real-time stream processing
- https://matt.sh/advanced-redis-pubsub-scripts - Subscribe script to Pub/Sub channel
Python中的 redis keyspace 通知的更多相关文章
- python中的Redis键空间通知(过期回调)
介绍 Redis是一个内存数据结构存储库,用于缓存,高速数据摄取,处理消息队列,分布式锁定等等. 使用Redis优于其他内存存储的优点是Redis提供持久性和数据结构,如列表,集合,有序集和散列. 在 ...
- redis的安装使用以及在python中操作redis
一.Redis介绍: Redis可以看作是一个key-value的存储系统,它为我们提供了丰富的数据结构,包括lists,sets,ordered sets和hashes.还包括了对这些数据结构的丰富 ...
- 在Python中使用Redis
在Python中要使用Redis数据库,首先要安装redis 之前的博客中有写到在命令行模式下操作Redis数据库. 要在项目中使用的话可以这么做: 通过初始化 redis.Redis,得到返回的对象 ...
- $Django python中使用redis, django中使用(封装了),redis开启事务(管道)
一 Python操作Redis之普通连接 #先安装 pip3 install redis import redis r = redis.Redis(host='127.0.0.1', port=637 ...
- python中使用redis
准备 安装redis服务 点击查看Ubuntu中安装Redis. 安装依赖包 pip install redis 使用 import redis 创建连接 1.普通连接: conn = redis.R ...
- python中利用redis构建任务队列(queue)
Python中的使用标准queue模块就可以建立多进程使用的队列,但是使用redis和redis-queue(rq)模块使这一操作更加简单. Part 1. 比如首先我们使用队列来简单的储存数据:我们 ...
- 有关在python中使用Redis(二)
这里简单介绍下在python中使用如何使用hashset,set和list: 从list开始: 一般我们使用lpush对一个list进行初始化添加,但是如果需要不断往这个list里面加值,就要用rpu ...
- 有关在python中使用Redis(一)
python作为一种处理数据的脚本语言本身有许多方法函数供大家使用,有时候为了提升数据处理速度(如海量数据的访问或者海量数据的读取),涉及分布式管理架构,可能需要用到Redis,Redis是一个开源的 ...
- Python中的redis学习笔记
redis是一个key-value结构的数据库,value的格式可以使string,set,list,map(即python里面的dict),sorted set(有序集合) 1.初始化 1)直接连接 ...
随机推荐
- Maven_2 本地资源库 中央存储库
CONF window7 本地资源库: 一般默认的地址:C:\Users\Administrator\.m2 也可以修改地址:在路径{M2_HOME}\conf\setting.xml,更新 loca ...
- 深度学习论文翻译解析(二):An End-to-End Trainable Neural Network for Image-based Sequence Recognition and Its Application to Scene Text Recognition
论文标题:An End-to-End Trainable Neural Network for Image-based Sequence Recognition and Its Application ...
- SpringMVC入门学习(二)
SpringMVC入门学习(二) ssm框架 springMVC 在上一篇博客中,我简单介绍了一下SpringMVC的环境配置,和简单的使用,今天我们将进一步的学习下Springmvc的操作. mo ...
- .Net Core缓存组件(Redis)源码解析
上一篇文章已经介绍了MemoryCache,MemoryCache存储的数据类型是Object,也说了Redis支持五中数据类型的存储,但是微软的Redis缓存组件只实现了Hash类型的存储.在分析源 ...
- Python和Java分别实现冒泡排序
1.基本思想 冒泡排序的基本思想是对比相邻的元素值.相邻元素值比较,如果满足条件两者就交换,把较小的移动到前面,把较大的移动到后面,这样较小的元素就像气泡一样浮上来了.可以看出,冒泡排序的每一次循环都 ...
- Apollo 1 融合 Spring 的三个入口
前言 Spring 作为 Java 世界非官方标准框架,任何一个中间件想要得到良好的发展,必须完美支持 Spring 的各种特性,即:无缝融入 Spring. Apollo 作为分布式配置中心,服务于 ...
- Mysql常用函数总结(二)
有的时候们需要了解当前的时间,这时候我们就可以调用时间函数了.下面就是一些常用的时间函数下面来说一下DATE_FORMAT(date,format):format可以有以下格式符:举个例子吧! mys ...
- (4)Jquery1.8.3快速入门_基本选择器
一.Jquery选择器: 基本选择器: 1.id #id 根据元素的id获取的唯一元素. 2.class ...
- Android基础系列合集
四大组件 1.Service Android四大组件-Service Android-远程Service Service 动态更新 UI 2.Activity Android四大组件-Activity ...
- Android ThreadPoolExecutor线程池
引言 Android的线程池概念来自于Java的Executor,真正的线程池实现为ThreadPoolExecutor.在Android中,提供了4类不同的线程池,具体下面会说到.为什么使用线程池呢 ...