Redis 发布订阅

  Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息。

  Redis 客户端可以订阅任意数量的频道。

  下图展示了频道 channel1 , 以及订阅这个频道的三个客户端 —— client2 、 client5 和 client1 之间的关系:

  当有新消息通过 PUBLISH 命令发送给频道 channel1 时, 这个消息就会被发送给订阅它的三个客户端:

实例

以下实例演示了发布订阅是如何工作的。在实例中创建了订阅频道名为 redisChat:

redis 127.0.0.1:6379> SUBSCRIBE redisChat

Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "redisChat"
3) (integer) 1

现在,重新开启个 redis 客户端,然后在同一个频道 redisChat 发布两次消息,订阅者就能接收到消息。

redis 127.0.0.1:6379> PUBLISH redisChat "Redis is a great caching technique"

(integer) 1

redis 127.0.0.1:6379> PUBLISH redisChat "Learn redis by runoob.com"

(integer) 1

# 订阅者的客户端会显示如下消息
1) "message"
2) "redisChat"
3) "Redis is a great caching technique"
1) "message"
2) "redisChat"
3) "Learn redis by runoob.com"
# 1. 订阅一个或多个符合给定模式的频道。
PSUBSCRIBE pattern [pattern ...]
'''
返回值:接收到的信息。
redis 127.0.0.1:6379> PSUBSCRIBE mychannel
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "mychannel"
3) (integer) 1
''' # 2.查看订阅与发布系统状态。
PUBSUB subcommand [argument [argument ...]]
'''
返回值:由活跃频道组成的列表。
redis 127.0.0.1:6379> PUBSUB CHANNELS
(empty list or set)
''' # 3.将信息发送到指定的频道。
PUBLISH channel message
'''
返回值:接收到信息的订阅者数量。
redis 127.0.0.1:6379> PUBLISH mychannel "hello, i m here"
(integer) 1
''' # 4.退订所有给定模式的频道。
PUNSUBSCRIBE [pattern [pattern ...]]
'''
返回值:这个命令在不同的客户端中有不同的表现。
redis 127.0.0.1:6379> PUNSUBSCRIBE mychannel
1) "punsubscribe"
2) "a"
3) (integer) 1
''' # 5.订阅给定的一个或多个频道的信息。
SUBSCRIBE channel [channel ...]
'''
返回值:接收到的信息
redis 127.0.0.1:6379> SUBSCRIBE mychannel
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "mychannel"
3) (integer) 1
1) "message"
2) "mychannel"
3) "a"
''' # 6.指退订给定的频道。
UNSUBSCRIBE [channel [channel ...]]
'''
返回值:这个命令在不同的客户端中有不同的表现。
redis 127.0.0.1:6379> UNSUBSCRIBE mychannel
1) "unsubscribe"
2) "a"
3) (integer) 0
'''

redis 发布订阅命令

Redis 事务

Redis 事务可以一次执行多个命令, 并且带有以下两个重要的保证:

  • 批量操作在发送 EXEC 命令前被放入队列缓存。
  • 收到 EXEC 命令后进入事务执行,事务中任意命令执行失败,其余的命令依然被执行。
  • 在事务执行过程,其他客户端提交的命令请求不会插入到事务执行命令序列中。

一个事务从开始到执行会经历以下三个阶段:

  • 开始事务。
  • 命令入队。
  • 执行事务。

实例

  以下是一个事务的例子, 它先以 MULTI 开始一个事务, 然后将多个命令入队到事务中, 最后由 EXEC 命令触发事务, 一并执行事务中的所有命令:

redis 127.0.0.1:6379> MULTI
OK redis 127.0.0.1:6379> SET book-name "Mastering C++ in 21 days"
QUEUED redis 127.0.0.1:6379> GET book-name
QUEUED redis 127.0.0.1:6379> SADD tag "C++" "Programming" "Mastering Series"
QUEUED redis 127.0.0.1:6379> SMEMBERS tag
QUEUED redis 127.0.0.1:6379> EXEC
1) OK
2) "Mastering C++ in 21 days"
3) (integer) 3
4) 1) "Mastering Series"
2) "C++"
3) "Programming"

  单个 Redis 命令的执行是原子性的,但 Redis 没有在事务上增加任何维持原子性的机制,所以 Redis 事务的执行并不是原子性的。

  事务可以理解为一个打包的批量执行脚本,但批量指令并非原子化的操作,中间某条指令的失败不会导致前面已做指令的回滚,也不会造成后续的指令不做。

这是官网上的说明 From redis docs on transactions:

It's important to note that even when a command fails, all the other commands in the queue are processed – Redis will not stop the processing of commands.

比如:

redis 127.0.0.1:7000> multi
OK
redis 127.0.0.1:7000> set a aaa
QUEUED
redis 127.0.0.1:7000> set b bbb
QUEUED
redis 127.0.0.1:7000> set c ccc
QUEUED
redis 127.0.0.1:7000> exec
1) OK
2) OK
3) OK

如果在 set b bbb 处失败,set a 已成功不会回滚,set c 还会继续执行。

# 1.取消事务,放弃执行事务块内的所有命令。
DISCARD
'''
返回值
总是返回 OK 。
redis 127.0.0.1:6379> MULTI
OK
redis 127.0.0.1:6379> PING
QUEUED
redis 127.0.0.1:6379> SET greeting "hello"
QUEUED
redis 127.0.0.1:6379> DISCARD
OK
''' # 2.执行所有事务块内的命令。
EXEC
'''
返回值:事务块内所有命令的返回值,按命令执行的先后顺序排列。 当操作被打断时,返回空值 nil 。
# 事务被成功执行
redis 127.0.0.1:6379> MULTI
OK
redis 127.0.0.1:6379> INCR user_id
QUEUED
redis 127.0.0.1:6379> INCR user_id
QUEUED
redis 127.0.0.1:6379> INCR user_id
QUEUED
redis 127.0.0.1:6379> PING
QUEUED
redis 127.0.0.1:6379> EXEC
1) (integer) 1
2) (integer) 2
3) (integer) 3
4) PONG # 监视 key ,且事务成功执行
redis 127.0.0.1:6379> WATCH lock lock_times
OK
redis 127.0.0.1:6379> MULTI
OK
redis 127.0.0.1:6379> SET lock "huangz"
QUEUED
redis 127.0.0.1:6379> INCR lock_times
QUEUED
redis 127.0.0.1:6379> EXEC
1) OK
2) (integer) 1 # 监视 key ,且事务被打断
redis 127.0.0.1:6379> WATCH lock lock_times
OK
redis 127.0.0.1:6379> MULTI
OK
redis 127.0.0.1:6379> SET lock "joe" # 就在这时,另一个客户端修改了 lock_times 的值
QUEUED
redis 127.0.0.1:6379> INCR lock_times
QUEUED
redis 127.0.0.1:6379> EXEC # 因为 lock_times 被修改, joe 的事务执行失败
(nil)
''' # 3.标记一个事务块的开始。
MULTI
'''
返回值:总是返回 OK 。
redis 127.0.0.1:6379> MULTI # 标记事务开始
OK
redis 127.0.0.1:6379> INCR user_id # 多条命令按顺序入队
QUEUED
redis 127.0.0.1:6379> INCR user_id
QUEUED
redis 127.0.0.1:6379> INCR user_id
QUEUED
redis 127.0.0.1:6379> PING
QUEUED
redis 127.0.0.1:6379> EXEC # 执行
1) (integer) 1
2) (integer) 2
3) (integer) 3
4) PONG
''' # 4.取消 WATCH 命令对所有 key 的监视。
UNWATCH
'''
返回值: 总是返回 OK 。
redis 127.0.0.1:6379> WATCH lock lock_times
OK
redis 127.0.0.1:6379> UNWATCH
OK
''' # 5.监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。
WATCH key [key ...]
'''
返回值:总是返回 OK 。
redis> WATCH lock lock_times
OK
'''

redis 事务基本操作

Redis 脚本

  Redis 脚本使用 Lua 解释器来执行脚本。 Redis 2.6 版本通过内嵌支持 Lua 环境。执行脚本的常用命令为 EVAL

Eval 命令的基本语法如下:

redis 127.0.0.1:6379> EVAL script numkeys key [key ...] arg [arg ...]

实例

以下实例演示了 redis 脚本工作过程

redis 127.0.0.1:6379> EVAL "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 first second

1) "key1"
2) "key2"
3) "first"
4) "second"
# 1.执行 Lua 脚本。
EVAL script numkeys key [key ...] arg [arg ...]
'''
参数说明:
script: 参数是一段 Lua 5.1 脚本程序。脚本不必(也不应该)定义为一个 Lua 函数。
numkeys: 用于指定键名参数的个数。
key [key ...]: 从 EVAL 的第三个参数开始算起,表示在脚本中所用到的那些 Redis 键(key),这些键名参数可以在 Lua 中通过全局变量 KEYS 数组,用 1 为基址的形式访问( KEYS[1] , KEYS[2] ,以此类推)。
arg [arg ...]: 附加参数,在 Lua 中通过全局变量 ARGV 数组访问,访问的形式和 KEYS 变量类似( ARGV[1] 、 ARGV[2] ,诸如此类)。
redis 127.0.0.1:6379> eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 first second
1) "key1"
2) "key2"
3) "first"
4) "second"
''' # 2.执行 Lua 脚本。
EVALSHA sha1 numkeys key [key ...] arg [arg ...]
'''
参数说明:
sha1 : 通过 SCRIPT LOAD 生成的 sha1 校验码。
numkeys: 用于指定键名参数的个数。
key [key ...]: 从 EVAL 的第三个参数开始算起,表示在脚本中所用到的那些 Redis 键(key),这些键名参数可以在 Lua 中通过全局变量 KEYS 数组,用 1 为基址的形式访问( KEYS[1] , KEYS[2] ,以此类推)。
arg [arg ...]: 附加参数,在 Lua 中通过全局变量 ARGV 数组访问,访问的形式和 KEYS 变量类似( ARGV[1] 、 ARGV[2] ,诸如此类)。 redis 127.0.0.1:6379> SCRIPT LOAD "return 'hello moto'"
"232fd51614574cf0867b83d384a5e898cfd24e5a"
redis 127.0.0.1:6379> EVALSHA "232fd51614574cf0867b83d384a5e898cfd24e5a" 0
"hello moto"
''' # 3.查看指定的脚本是否已经被保存在缓存当中。
SCRIPT EXISTS script [script ...]
'''
返回值:一个列表,包含 0 和 1 ,前者表示脚本不存在于缓存,后者表示脚本已经在缓存里面了。
列表中的元素和给定的 SHA1 校验和保持对应关系,比如列表的第三个元素的值就表示第三个 SHA1 校验和所指定的脚本在缓存中的状态。
redis 127.0.0.1:6379> SCRIPT LOAD "return 'hello moto'" # 载入一个脚本
"232fd51614574cf0867b83d384a5e898cfd24e5a"
redis 127.0.0.1:6379> SCRIPT EXISTS 232fd51614574cf0867b83d384a5e898cfd24e5a
1) (integer) 1
redis 127.0.0.1:6379> SCRIPT FLUSH # 清空缓存
OK
redis 127.0.0.1:6379> SCRIPT EXISTS 232fd51614574cf0867b83d384a5e898cfd24e5a
1) (integer) 0
''' # 4.从脚本缓存中移除所有脚本。
SCRIPT FLUSH
'''
返回值:OK
redis 127.0.0.1:6379> SCRIPT FLUSH
OK
''' # 5.杀死当前正在运行的 Lua 脚本。
SCRIPT KILL
'''
返回值:OK
redis 127.0.0.1:6379> SCRIPT KILL
OK
''' # 6.将脚本 script 添加到脚本缓存中,但并不立即执行这个脚本。
SCRIPT LOAD script
'''
返回值:给定脚本的 SHA1 校验和
redis 127.0.0.1:6379> SCRIPT LOAD "return 1"
"e0e1f9fabfc9d4800c877a703b823ac0578ff8db"
'''

redis 脚本基本操作

redis发布订阅、事务、脚本的更多相关文章

  1. Redis发布订阅机制

    1. 什么是Redis Redis是一个开源的内存数据库,它以键值对的形式存储数据.由于数据存储在内存中,因此Redis的速度很快,但是每次重启Redis服务时,其中的数据也会丢失,因此,Redis也 ...

  2. Redis发布订阅和事物笔记

    Redis 发布订阅 Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息. Redis 客户端可以订阅任意数量的频道. 下图展示了频道 cha ...

  3. Linux(6)- redis发布订阅/持久化/主从复制/redis-sentinel/redis-cluster、nginx入门

    一.redis发布订阅 Redis 通过 PUBLISH .SUBSCRIBE 等命令实现了订阅与发布模式. 其实从Pub/Sub的机制来看,它更像是一个广播系统,多个Subscriber可以订阅多个 ...

  4. RedisRepository封装—Redis发布订阅以及StackExchange.Redis中的使用

    本文版权归博客园和作者本人吴双共同所有,转载请注明本Redis系列分享地址.http://www.cnblogs.com/tdws/tag/NoSql/ Redis Pub/Sub模式 基本介绍 Re ...

  5. python中使用redis发布订阅者模型

    redis发布订阅者模型: Redis提供了发布订阅功能,可以用于消息的传输,Redis的发布订阅机制包括三个部分,发布者,订阅者和Channel.发布者和订阅者都是Redis客户端,Channel则 ...

  6. redis发布/订阅

    发布订阅简介 Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息,消息之间通过channel传递. 准备工作 两台安装了redis的机器(虚拟 ...

  7. MariaDB主从复制,redis发布订阅,持久化,以及主从同步

      一. MariaDB主从复制 mysql基本操作 1 连接数据库 mysql -u root -p -h 127.0.0.1 mysql -u root -p -h 192.168.12.60 2 ...

  8. 利用Redis发布订阅完成tomcat集群下的消息通知

    以下为个人想法,如果有说的不对的地方请各位大佬见谅! 这是博主的第一篇博客,可能排版以及一些描述有不合理的地方还请勿喷,希望大家尽可能的多给我这样的新人一些鼓励让我能在写博客的道路上走下去. 进入正题 ...

  9. Linux 安装redis,redis发布订阅,持久化

    安装redis 1.安装redis的方式 -yum (删除这个yum安装的redis,我们只用源码编译安装的) -rpm -源码编译 2.删除原本的redis yum remove redis -y ...

随机推荐

  1. C#中[WebMethod]的用法,aspx、ashx、asmx

    在.net 3.5的情况下 前台JQuery做Ajax的时候,服务器端 (1)可以调用aspx.cs 中声明带有[WebMehtod]的public static 的方法(不需要自己手动添加web.c ...

  2. kubernetes 学习资料

    谷歌大神详解 Kubernetes 配置管理最佳方法 https://www.kubernetes.org.cn/3031.html all in on kubernetes https://gith ...

  3. Mongodb常用增删改查语法

    1,新增 新增有两种方式 var Tank = mongoose.model('Tank', yourSchema); var small = new Tank({ size: 'small' }); ...

  4. ie11开发者模式打开空白

    Internet选项——高级——取消  禁用脚本调试(Internet explorpr)

  5. python class和class(object)用法区别

    # -*- coding: utf-8 -*- # 经典类或者旧试类 class A: pass a = A() # 新式类 class B(object): pass b = B() # pytho ...

  6. 力导向图Demo

    <html> <head> <meta charset="utf-8"> <title>力导向图</title> < ...

  7. CAS单点登陆,URL多出个参数jsessionid导致登陆失败问题

    目录: 1.定位问题 2.问题产生的原因 3.解决问题 一 定位问题 首先,如下图所示:输入到地址栏的地址被302重定向到单点登录地址,地址由Response Headers中的参数Location所 ...

  8. Android Bluetooth hci 命令分析

    Android在连接BLE设备的时候,遇到连接没多久就自动断开的情况.通过HCI来分析一下. BLE设备发送连接参数更新请求 3909 15:53:01.224737 TexasIns_f0:d3:4 ...

  9. springboot-thymeleaf

    Thymeleaf 是一个跟 Velocity.FreeMarker 类似的模板引擎,它可以完全替代 JSP .相较与其他的模板引擎,它有如下三个极吸引人的特点: Thymeleaf 在有网络和无网络 ...

  10. there was an error running the selected code generator unable to retrieve metadata for

    there was an error running the selected code generator unable to retrieve metadata for PROBLEM: I ha ...