瑞士军刀Redis

作者: 若兮缘 | 来源:发表于2019-02-28 22:47 被阅读11次

    主要内容

    慢查询

    生命周期

    如图所示为客户端请求到Redis的完整生命周期:发送命令、排队、执行命令、返回结果

    1. 慢查询发生在第三阶段(也就是说其他阶段像排队耗时都不算)
    2. 客户端超时不一定慢查询,但慢查询是客户端超时的一个可能因素
    两个配置
    • slowlog-max-len
      1.配置慢查询队列最大长度
      2.筛选出的慢查询会进入一个先进先出队列
      3.该队列是固定长度的
      4.该队列是保存在内存中
    • slowlog-log-slower-than
      1.慢查询阈值(单位:微秒),也就是说超过多少时间的查询是慢查询
      2.slowlog-log-slower-than=0; 记录所有命令
      3.slowlog-log-slower-than<0; 不记录任何命令
    配置方法
    1. 默认值
      config get slowlog-max-len = 128
      config get slowlog-log-slower-than = 10000
    2. 修改配置文件重启(不建议,因为生产环境要尽量避免重启,在第一次启动redis前可以这么做)
    3. 动态配置
      config set slowlog-max-len 1000
      config set slowlog-log-slower-than 1000
    三个命令
    • slowlog get [n]: 获取慢查询队列(n为可选参数,指定慢查询条数)
    • slowlog len: 获取慢查询队列长度
    • slowlog reset: 清空慢查询队列
    运维经验
    1. slowlog-log-slower-than不要设置过大,默认10ms,通常设置1ms
    2. slowlog-max-len不要设置过小,通常设置1000左右
    3. 理解命令生命周期
    4. 定期持久化慢查询(方便查到历史慢查询操作)

    pipeline

    什么是流水线

    对比: 1次网络命令通信模型 vs 批量网络命令通信模型

    执行redis命令时间通常是非常快的,而网络则存在很多不稳定因素。另外redis虽然提供了mget、mset和hmget、hmset等这样的命令,但是如果我们需要同时执行get和hget命令需要怎么做呢,其实这就是流水线帮助我们实现的功能。

    流水线就是将一批命令进行一个打包,而在服务端进行批量的计算,然后按顺序将结果返回给客户端,使用流水线可以大大节省网络的开销。

    流水线的作用

    两点说明:
    1.redis的命令时间是微秒级别
    2.pipeline每次条数要控制(网络)

    分析一个极端例子,假设客户端和服务端相距1300公里,粗略计算命令传输时间为13毫秒,而命令执行时间只有微秒级,所以如果想要做批量操作而没有使用pipeline这样的功能,那redis的使用效率就不会很高。

    客户端实现(jedis)

    假设需要执行hset命令1万次,key也有1万个,这样的操作是无法使用hmset来完成的,因为hmset是只针对一个key。
    我们先使用for循环进行批量命令操作,最终执行时间为50s,显然对于这样的时间是没办法接受的。

    我们换成使用pipeline实现,每次执行100个命令,执行100次pipeline操作,最终时间只需要0.7秒,速度大大提升。

    与原生M操作

    与原生M操作对比,M操作是一个原子操作,只需要执行和计算一次,而pipeline是将命令进行打包,传送到redis时,则会拆分成子命令,结果会按顺序返回。

    使用建议
    1. 注意每次pipeline携带数据量(数据量过大需合理拆分次数)
    2. pipeline每次只能作用在一个Redis节点上
    3. 明确M操作与pipeline区别

    发布订阅

    角色

    角色主要有发布者(publisher)、订阅者(subscriber)、频道(channel)
    发布者会发布消息到频道上,订阅者通过订阅频道来获取消息。
    类似一些新闻APP(微信公众号),只要订阅了某些频道,这些频道有新消息发布订阅者就能收到消息。

    模型

    模型如图所示(类似生产者与消费者模型),对于订阅者而言其实也是个客户端,订阅者是可以订阅多个频道的,有个问题就是假如发布者已经发布了一条消息到频道中,但是一个新的订阅者是收不到之前已经发送过的消息的,使用时一定要注意这种场景,就是说redis并没有提供消息堆积的功能,所以无法获取历史消息。

    相关API

    发布消息:publish channel message

    订阅频道:subscribe [channel]
    返回信息:订阅了哪个频道,收到消息详细信息

    取消订阅:unsubscribe [channel]

    其他API,例如第一个命令根据pattern去匹配订阅,如: v*,匹配v开头的频道

    消息队列

    发布订阅是频道发送一条消息,订阅该频道的订阅者都能收到消息。而消息队列是抢模式,最终只有一个订阅者能抢到消息进行消费。
    当然redis本身没有提供消息队列这样的功能,我们可以使用list实现,使用阻塞去拉取...
    具体根据场景选择相应的模式,就是要搞清楚你的消费者是都需要收到还是只有一个收到。

    Bitmap

    位图

    每个字符串有对应的二进制,二进制每个数字代表位,即bit
    bitmap就是可以用来对位进行操作

    例如获取hello对应的value即big,我们可以获取每一位二进制数

    HyperLogLog

    GEO

    相关文章

      网友评论

        本文标题:瑞士军刀Redis

        本文链接:https://www.haomeiwen.com/subject/noshuqtx.html