zoukankan      html  css  js  c++  java
  • 04: redis 消费模式 和 事务

    Redis发布消息模式

    生产消费模型

     

    Redis发布消息通常有两种模式:

    1:队列模式(queuing

    2:发布-订阅模式(publish-subscribe)

    任务队列:顾名思义,就是“传递消息的队列”。与任务队列进行交互的实体有两类,一类是生产者(producer),另一类则是消费者(consumer)。生产者将需要处理的任务放入任务队列中,而消费者则不断地从任务独立中读入任务信息并执行。

    任务队列的好处:

    松耦合。

    生产者和消费者只需按照约定的任务描述格式,进行编写代码。

    易于扩展。

    多消费者模式下,消费者可以分布在多个不同的服务器中,由此降低单台服务器的负载。

     

     

    其实从publish-subscribe的机制来看,它更像是一个广播系统,多个Subscriber可以订阅多个Channel,多个Publisher可以往多个Channel中发布消息。可以这么简单的理解:

    Subscriber:收音机,可以收到多个频道,并以队列方式显示

    Publisher:电台,可以往不同的FM频道中发消息

    Channel:不同频率的FM频道

    --------------------------------------------------------------------------------------------------------------------------------

    (1) 一个Publisher,多个Subscriber模型

    如下图所示,可以作为消息队列或者消息管道。

    主要应用:通知、公告

     

    (2) 多个Publisher,一个Subscriber模型

    可以将PubSub做成独立的HTTP接口,各应用程序作为PublisherChannel中发送消息,Subscriber端收到消息后执行相应的业务逻辑,比如写数据库,显示等等。

    主要应用:排行榜、投票、计数。

     

    (3) 多个Publisher,多个Subscriber模型

    故名思议,就是可以向不同的Channel中发送消息,由不同的Subscriber接收。

    主要应用:群聊、聊天。

     

    发布订阅实践:

    PUBLISH channel msg

    将信息 message 发送到指定的频道 channel 

    SUBSCRIBE channel [channel ...]

    订阅频道,可以同时订阅多个频道

    UNSUBSCRIBE [channel ...]

    取消订阅指定的频道, 如果不指定频道,则会取消订阅所有频道

    PSUBSCRIBE pattern [pattern ...]

    订阅一个或多个符合给定模式的频道,每个模式以 * 作为匹配符,比如 it* 匹配所 有以 it 开头的频道( it.news it.blog it.tweets 等等)news.* 匹配所有 news. 开头的频道( news.it news.global.today 等等),诸如此类

    PUNSUBSCRIBE [pattern [pattern ...]]

    退订指定的规则, 如果没有参数则会退订所有规则

    PUBSUB subcommand [argument [argument ...]]

    查看订阅与发布系统状态

    注意:使用发布订阅模式实现的消息队列,当有客户端订阅channel后只能收到后续发布到该频道的消息,之前发送的不会缓存,必须ProviderConsumer同时在线。

     

    发布订阅例子:

    窗口1:                                   订阅zhangsan频道

    127.0.0.1:6379> SUBSCRIBE  zhangsan 

    窗口2:                                   给zhangsan频道发送消息,此时窗口1会实时显示出消息出来

    127.0.0.1:6379> PUBLISH zhangsan  "jin tian zhen kaixin!"

    订阅多频道:

    窗口1:                                   订阅多个zhangsan* 频道,比如zhangsan01  zhangsan02

    127.0.0.1:6379> PSUBSCRIBE  zhangsan*

    窗口2:                                   给zhangsan*频道发送消息,此时窗口1会实时显示出消息出来

    127.0.0.1:6379> PUBLISH  zhangsan01 "jintian zhennanshou "

     127.0.0.1:6379> PUBLISH zhangsan02 "jintian zhennanshou "

    客户端在执行订阅命令之后进入了订阅状态,只能接收 SUBSCRIBE PSUBSCRIBEUNSUBSCRIBE PUNSUBSCRIBE 四个命令。 开启的订阅客户端,无法收到该频道之前的消息,因为 Redis 不会对发布的消息进行持久化。 和很多专业的消息队列系统(例如KafkaRocketMQ)相比,Redis的发布订阅略显粗糙,例如无法实现消息堆积和回溯。但胜在足够简单,如果当前场景可以容忍的这些缺点,也不失为一个不错的选择。

     

    ------redis 事务--------

    redis中的事务跟关系型数据库中的事务是一个相似的概念,但是有不同之处。关系型数据库事务执行失败后面的sql语句不在执行,而redis中的一条命令执行失败,其余的命令照常执行。

    redis中开启一个事务是使用multi,相当于beginstart transactionexec提交事务,discard取消队列命令(非回滚操作)。

     

    开启事务功能时(multi

    multi

    command1      

    command2

    command3

    command4

    4条语句作为一个组,并没有真正执行,而是被放入同一队列中。

    如果,这时候执行discard,会直接丢弃队列中所有的命令,而不是做回滚。

    exec

    当执行exec时,对列中所有操作,要么全成功要么全失败

    ----------

    127.0.0.1:6379> set a b

    OK

    127.0.0.1:6379> MULTI

    OK

    127.0.0.1:6379> set a b

    QUEUED

    127.0.0.1:6379> set c d

    QUEUED

    127.0.0.1:6379> exec

    1) OK

    2) OK

     

    Redis中事务中的锁机制:

    举例:我正在买票

    Ticket -1 , money -100

    而票只有1, 如果在我multi之后,exec之前, 票被别人买了---ticket变成0.

    我该如何观察这种情景,并不再提交

    悲观的想法:

    世界充满危险,肯定有人和我抢, ticket上锁, 只有我能操作. [悲观锁]

    乐观的想法:

    没有那么人和我抢,因此,我只需要注意,

    --有没有人更改ticket的值就可以了 [乐观锁]

    Redis的事务中,启用的是乐观锁,只负责监测key没有被改动.

     

    发布一张票

    set ticket 1

     

    窗口1:先观察ticket的值,然后正常购买,如果此时ticket0了,就会提示失败,否则成功

    watch ticket

    multi

    set ticket 0       1---->0

     

    窗口2:直接提交把票买了。

    multi

    set ticket 0

    exec

     

    窗口1

    Exec

    --------------------------------

    Redis 常用管理命令

    Info

    Clinet list

    Client kill ip:port

    config get *

    CONFIG RESETSTAT 重置统计

    CONFIG GET/SET 动态修改

    Dbsize

    FLUSHALL 清空所有数据

    select 1

    FLUSHDB 清空当前库

     

    MONITOR 监控实时指令

    SHUTDOWN 关闭服务器

     

    关闭数据库:

    redis-cli -a root shutdown

     

    ------- ---扩展 slow慢日志查询---------------------------

    慢日志查询

     

    Slow log Redis 用来记录查询执行时间的日志系统。

    slow log 保存在内存里面,读写速度非常快

    可以通过改写 redis.conf 文件或者用 CONFIG GET CONFIG SET 命令对它们动态地进行修改

    slowlog-log-slower-than 10000 超过多少微秒

    CONFIG SET slowlog-log-slower-than 100

    CONFIG SET slowlog-max-len 1000 保存多少条慢日志

    CONFIG GET slow*

    SLOWLOG GET

    SLOWLOG RESET

     

     

  • 相关阅读:
    Pretty girl,你一定要去旅行
    难受就哭,开心就笑
    你对你的大学生活满意吧
    [leetCode]575. 分糖果
    [leetCode]383.赎金信
    242. 有效的字母异位词
    [leetCode]538. 把二叉搜索树转换为累加树
    [leetCode]面试题 02.07. 链表相交
    [leetCode]206. 反转链表
    [leetCode]707. 设计链表
  • 原文地址:https://www.cnblogs.com/jim-xu/p/11617298.html
Copyright © 2011-2022 走看看