zoukankan      html  css  js  c++  java
  • Redis自学笔记:4.4进阶-消息通知

    4.4消息通知

    4.4.1任务队列

    传递任务的队列.与任务队列进行交互的实体有两类,一类是生产者,一类是消费者.
    生产者将需要处理的任务放入任务队列中,二消费者不断从任务队列中读入任务
    信息并执行.

    优点:

    1. 松耦合
      生产者和消费者无需知道彼此实现的细节
    2. 易于扩展
      消费者可以有多个,而且可以分布在不同服务器

    4.4.2使用redis实现任务队列

    3.4.2节中的lpush和rpop|lpop命令可以实现队列概念,伪代码:

    # 无线循环读取任务队列的内容
    loop
        $task = rpop queue
        if $task
            # 如果任务队列中有任务则执行
            execute
        else
            # 如果没有则等待1秒避免频繁请求数据
            wait 1 second
    

    缺点:当任务队列中没有任务时,消费者美妙都会调用一次rpop

    brpop|blpop命令和rpop|lpop命令相似,唯一区别是当列表没有元素时
    brpop|blpop命令会一直阻塞住连接,直到新元素加入.伪代码如下:

    loop
        # 如果队列中没有新任务,brpop命令会一直阻塞
        $task = brpop queue,0
        #返回值是一个数组,数组第二个元素使我们需要的任务
        execute($task[1])
    

    brpop|blpop命令接收两个参数,第一个是键名,第二个是超时间,单位是秒.
    当超时了没有获得新元素就会返回nil.当获得第一个元素后brpop|blpop
    命令就会返回两个值,分别是键名和元素值.
    客户端1:

    127.0.0.1:6379> lpush lfoo 1 2
    2
    127.0.0.1:6379> brpop lfoo 0
    lfoo
    1
    127.0.0.1:6379> brpop lfoo 0
    lfoo
    2
    127.0.0.1:6379> brpop lfoo 0
    lfoo
    新开客户的0
    (61.54s)
    

    客户端2:

    127.0.0.1:6379> lpush lfoo 新开客户的0
    1
    

    4.4.3优先级队列

    brpop|blpop命令可以同时接收多个键,其完整的命令格式为
    blpop|blpop key [key ...] timeout
    blpop queue:1 queue:2 0
    意义是同时检测多个键.如果所有键都没有元素则阻塞.如果其中一个键有元素则会
    从该键中弹出元素.
    如果多个键都有元素则从左到右的顺序取键中的第一个元素.

    127.0.0.1:6379> lpush lfoo lfoo_1 lfoo_2
    2
    127.0.0.1:6379> lpush lbar lbar_1 lbar_2
    2
    127.0.0.1:6379> brpop lfoo lbar 0
    lfoo
    lfoo_1
    127.0.0.1:6379> brpop lfoo lbar 0
    lfoo
    lfoo_2
    127.0.0.1:6379> brpop lfoo lbar 0
    lbar
    lbar_1
    127.0.0.1:6379> brpop lfoo lbar 0
    lbar
    lbar_2
    

    借此特性可以实现区分优先级的任务队列.我们分别使用queue:confirmation.email
    和queue:notification.email两个键存储发送确认邮件和通知邮件两种任务,
    然后消费者的代码为:

    loop
        $task = 
            brpop queue:confirmation.email,
                    queue:notification.email,
                    0
        execute($task[1])
    

    这样一旦发送邮件的任务被加入到que:confirmation.email队列中,无论
    queue:notification.email还有多少任务,消费者都会优先完成发送确认邮件
    的任务

    4.4.4"发布/订阅"模式

    该模式中包含两种角色,分别是发布者和订阅者.订阅者可以订阅一个或多个频道,而发
    步者可以向指定的频道发送消息,所有订阅此频道的订阅者都会收到此消息.
    发布者发布消息的命令是 publish,用法是
    publish channel message

    • 返回值是接收这条消息的订阅者数量.
      订阅频道的命令是 subscribe,可以同时订阅多个频道,用法是
      subscribe channel [channel ...]

    客户端1:

    127.0.0.1:6379> subscribe channel_1 channel_2
    subscribe
    channel_1
    1
    subscribe
    channel_2
    2
    message
    channel_1
    早上好
    message
    channel_2
    中午好
    

    客户端2:

    127.0.0.1:6379> publish channel_1 早上好
    1
    127.0.0.1:6379> publish channel_2 中午好
    1
    

    进入订阅状态后客户端可能收到3中类型回复:

    1. subscriba.表示订阅成功的反馈信息.第二个值是订阅成功的频道名称,
      第三个值是当前客户端订阅频道数量.
    2. message.表示接收到道的消息.第二个值表示产生消息的频道名称.第三
      个值是消息内容.
    3. unsubscriba.表示成功取消订阅某个频道.第二个值是对应的频道名称,
      第三个值是当前客户端订阅的频道数量,当此值为0时客户端会退出订阅
      状态,之后就可以执行其他非"发布/订阅"模式的命令了.

    4.4.5按照规则订阅

    psubscribe命令订阅指定的规则.规则支持glob风格通配符格式(3.1节).
    客户端1:

    127.0.0.1:6379> psubscribe channel_?*
    psubscribe
    channel_?*
    1
    pmessage
    channel_?*
    channel_1
    早上好
    pmessage
    channel_?*
    channel_2
    中午好
    pmessage
    channel_?*
    channel_3
    下午好
    

    客户端2:

    127.0.0.1:6379> publish channel_1 早上好
    1
    127.0.0.1:6379> publish channel_2 中午好
    1
    127.0.0.1:6379> publish channel_3 下午好
    1
    
    • 使用psubscribe命令可以重复订阅一个频道.但是收到的消息类型可能不同.
      punsubscribe命令可以退订指定规则.

    4.5管道

    远程客户端和redis服务端使用TCP协议连接.

    redis的底层通信协议对管道提供了支持.通过管道可以一次性发送多条命令并在执行
    完后一次性将结果返回,当一组命令中每条命令都不依赖于之前命令的执行结果时,
    就可以将这组命令一起通过管道发出.管道通过减少客户端与redis的通信次数来
    实现降低往返时延累计值的目的.

    4.6节省空间

    4.6.1精简键名和键值

    精简键名和键值是最直观的减少内存占用的方式.

    • 不能单纯为了节约空间使用不易理解的键名.这样不易维护,还容易造成命名冲突.

    4.6.2内部编码优化

    redis为每种数据提供了两种内部编码方式.
    查看一个键的内部编码方式: object encoding key

    127.0.0.1:6379> object encoding book
    ziplist
    

    表4-2每个数据类型可能采用两种内部编码方式之一来存储

    数据类型 内部编码方式 object encoding命令结果
    字符串 REDIS_ENCODING_RAW raw
    • |    REDIS_ENCODING_INT     |     int
      
    • |    REDIS_ENCODING_EMBSTR   |    embstr
      

    散列类型 | REDIS_ENCODING_HT | hashtable

    • |    REDIS_ENCODING_ZIPLIST |     ziplist
      

    列表类型 | REDIS_ENCODING_LINKEDLIST | linkedlist

    • |    REDIS_ENCODING_ZIPLIST |     ziplist
      

    集合类型 | REDIS_ENCODING_HT | hashtable

    • | REDIS_ENCODING_INTSET | intset
      有序集合类型| REDIS_ENCODING_SKIPLIST | skiplist
      •   | REDIS_ENCODING_ZIPLIST  |    ziplist
  • 相关阅读:
    DAY7-面向对象之封装
    Java遇到的问题、错误——持续更新
    008单例、继承、final
    java一些使用
    2.1端口扫描器
    PyCharm设置
    常用算法
    PyCharm最新2018激活码,最新方法
    004数组
    042多进程
  • 原文地址:https://www.cnblogs.com/wangbaby/p/10207193.html
Copyright © 2011-2022 走看看