1.慢查询

1.1 慢查询的生命周期

  1. 步骤一:client通过网络向Redis发送一条命令
  2. 步骤二:由于Redis是单线程应用,可以把Redis想像成一个队列,client执行的所有命令都在排队等着server端执行
  3. 步骤三:Redis服务端按顺序执行命令
  4. 步骤四:server端把命令结果通过网络返回给client

说明:

  1. 慢查询发生在命令执行过程中,不包含网络延迟时间及排除等待执行的时间
  2. 客户端超时不一定慢查询,但慢查询是客户端超时的一个可能因素

1.2 慢查询的配置项

  1. slowlog-max-len 慢查询队列的长度
  2. slowlog-log-slower-than 慢查询阈值(单位:微秒),执行时间超过阀值的命令会被加入慢查询命令
  3. 如果设置为0,则会记录所有命令,通常在需要记录每条命令的执行时间时使用
  4. 如果设置为小于0,则不记录任何命令
  5. slowlog list 慢查询记录

说明:

  1. 慢查询是一个先进先出的队列,如果一条命令在执行过程中被列入慢查询范围内,就会被放入一个队列,这个队列是基于Redis的列表来实现
  2. ,而且这个队列是固定长度的,当队列的长度达到固定长度时,最先被放入队列就会被pop出去
  3. 慢查询队列保存在内存之中,不会做持久化,当Redis重启之后就会消失

1.3 慢查询配置方法

1.3.1 修改配置文件重启

  1. 修改/etc/redis.conf配置文件,配置慢查询
  2. 修改配置方式应该在第一次配置Redis中时配置完成,生产后不建议修改配置文件

1.3.2 动态配置

  1. 127.0.0.1:6379> config get slowlog-max-len
  2. 1) "slowlog-max-len"
  3. 2) "128"
  4. 127.0.0.1:6379> config get slowlog-log-slower-than
  5. 1) "slowlog-log-slower-than"
  6. 2) "10000"
  7. 127.0.0.1:6379> config set slowlog-max-len 1000
  8. OK
  9. 127.0.0.1:6379> config get slowlog-max-len
  10. 1) "slowlog-max-len"
  11. 2) "1000"
  12. 127.0.0.1:6379> config set slowlog-log-slower-than 1000
  13. OK
  14. 127.0.0.1:6379> config get slowlog-log-slower-than
  15. 1) "slowlog-log-slower-than"
  16. 2) "1000"

1.4 慢查询命令

  1. slowlog get [n] 获取慢查询队列
  2. slowlog len 获取慢查询队列长度
  3. slowlog reset 清空慢查询队列

1.5 Redis慢查询运维经验

  1. slowlog-max-len不要设置过小,通常设置1000左右
  2. slowlog-log-slower-than不要设置过大,默认10ms,通常设置1ms
  3. 理解命令生命周期
  4. 可以通过slowlog get等命令定期将慢查询命令持久化到其他数据源,这样就可以查到很多历史的慢查询操作命令
  5. 在生产环境中,不管slowlog-max-len设置多大,当慢查询命令逐步增多时,最开始的慢查询命令会被丢掉
  6. 当需要查询历史数据时,这些慢查询命令都是非常关键的
  7. 可以使用开源软件来实现这些功能,对于分析解决Redis问题是非常有帮助的

2.Pipeline

2.1 Pipeline的概念

一次网络命令通信模型:

  1. client通过网络传输命令到server
  2. server端通过计算得到命令执行结果
  3. server端把命令执行结果给client

此时:

  1. 一次网络命令通信时间=1次网络时间 + 1次命令时间

此时如果有多条命令呢,那就只能一条一条的输入命令执行了

  1. n次时间 n次网络时间 + n次命令时间

Redis执行命令的时间很快,但是网络传输却可能有很大延迟,

pipeline就是把一批命令进行打包,然后传输给server端进行批量计算,然后按顺序将执行结果返回给client端

使用Pipeline模型进行n次网络通信需要的时间

  1. 1pipeline(n条命令) 1次网络时间 + n次命令时间

2.2 例子

  1. import redis
  2. import time
  3. client = redis.StrictRedis(host='192.168.81.100',port=6379)
  4. start_time = time.time()
  5. for i in range(10000):
  6. client.hset('hashkey','field%d' % i,'value%d' % i)
  7. ctime = time.time()
  8. print(client.hlen('hashkey'))
  9. print(ctime - start_time)

程序执行结果:

  1. 10000
  2. 2.0011684894561768

在上面的例子里,直接向Redis中写入10000条hash记录,需要的时间为2.00秒

使用pipeline的方式向Redis中写入1万条hash记录

  1. import redis
  2. import time
  3. client = redis.StrictRedis(host='192.168.81.100',port=6379)
  4. start_time = time.time()
  5. for i in range(100):
  6. pipeline = client.pipeline()
  7. j = i * 100
  8. while j < (i+ 1) * 100:
  9. pipeline.hset('hashkey1','field%d' % j * 100,'value%d' % i)
  10. j += 1
  11. pipeline.execute()
  12. ctime = time.time()
  13. print(client.hlen('hashkey1'))
  14. print(ctime - start_time)

程序执行结果:

  1. 10000
  2. 0.3175079822540283

可以看到使用Pipeline方式每次向Redis服务端发送100条命令,发送100次所需要的时间仅为0.31秒,可以看到使用Pipeline可以节省网络传输时间

2.3 Pipeline使用建议

  1. 首先要注意每次pipeline携带数据量不能太大
  2. pipeline可以提高Redis批量处理的并发的能力,但是并不能无节制的使用
  3. 如果批量执行的命令数量过大,则很容易对网络及客户端造成很大影响,此时可以把命令分割,每次发送少量的命令到服务端执行
  4. pipeline每次只能作用在一个Redis节点上

3.发布订阅

3.1 发布订阅中的角色

  1. 发布者(publisher)
  2. 订阅者(subscriber)
  3. 频道(channel)

3.2 发布订阅的模型

  1. Redis server就相当于频道
  2. 发布者是一个redis-cli,通过redis server发布消息
  3. 订阅者也是于一个redis-cli,如果订阅了这个频道,就可以通过redis server获取消息

说明:

  1. 发布订阅就是一个生产者消费者模型
  2. 每个订阅者可以订阅多个频道
  3. 发布者发布消息后,订阅者就可以收到不同频道的消息
  4. 订阅者不可以接收未订阅频道的消息
  5. 订阅者订阅某个频道后,Redis无法做消息的堆积,不能接收频道被订阅之前发布的消息

3.3 发布订阅的命令

  1. publish channel message 发布消息
  2. subscribe [channel] 订阅频道
  3. unsubscribe [channel] 取消订阅
  4. psubscribe [pattern...] 订阅指定模式的频道
  5. punsubscribe [pattern...] 退订指定模式的频道
  6. pubsub channels 列出至少有一个订阅者的频道
  7. pubsub numsub [channel...] 列表给定频道的订阅者数量
  8. pubsub numpat 列表被订阅模式的数量

例子:

打开一个终端1

  1. 127.0.0.1:6379> subscribe sohu_tv # 订阅sohu_tv频道
  2. Reading messages... (press Ctrl-C to quit)
  3. 1) "subscribe"
  4. 2) "sohu_tv"
  5. 3) (integer) 1

再次打开一个终端2

  1. 127.0.0.1:6379> publish sohu_tv 'hello python' # sohu_tv频道发布消息
  2. (integer) 1
  3. 127.0.0.1:6379> publish sohu_tv 'hello world' # sohu_tv频道发布消息
  4. (integer) 3

可以看到终端1中已经接收到sohu_tv发布的消息

  1. 127.0.0.1:6379> subscribe sohu_tv
  2. Reading messages... (press Ctrl-C to quit)
  3. 1) "subscribe"
  4. 2) "sohu_tv"
  5. 3) (integer) 1
  6. 1) "message"
  7. 2) "sohu_tv"
  8. 3) "hello python"
  9. 1) "message"
  10. 2) "sohu_tv"
  11. 3) "hello world"

打开终端3,取消订阅sohu_tc频道

  1. 127.0.0.1:6379> unsubscribe sohu_tv
  2. 1) "unsubscribe"
  3. 2) "sohu_tv"
  4. 3) (integer) 0

3.4 发布订阅与消息队列

  1. redis server维护一个队列
  2. 消息发布者,相当于一个redis-cli,通过redis server发布消息
  3. 消息订阅者就相当于一个redis-cli,所有的消息订阅者通过redis server抢消息发布者发布的消息

高可用Redis(五):瑞士军刀之慢查询,Pipeline和发布订阅的更多相关文章

  1. 高可用Redis服务架构分析与搭建

    基于内存的Redis应该是目前各种web开发业务中最为常用的key-value数据库了,我们经常在业务中用其存储用户登陆态(Session存储),加速一些热数据的查询(相比较mysql而言,速度有数量 ...

  2. 如何搭建高可用redis架构?

    如何搭建高可用redis架构? 温国兵 架构师小秘圈 昨天 作者:温国兵,曾任职于酷狗音乐,现为三七互娱 DBA.目前主要关注领域:数据库自动化运维.高可用架构设计.数据库安全.海量数据解决方案.以及 ...

  3. 使用Docker Compose部署基于Sentinel的高可用Redis集群

    使用Docker Compose部署基于Sentinel的高可用Redis集群 https://yq.aliyun.com/articles/57953 Docker系列之(五):使用Docker C ...

  4. centos下搭建高可用redis

    Linux下搭建高可用Redis缓存 Redis是一个高性能的key-value数据库,现时越来越多企业与应用使用Redis作为缓存服务器.楼主是一枚JAVA后端程序员,也算是半个运维工程师了.在Li ...

  5. 高可用Redis服务架构分析与搭建(单redis实例)

    原文地址:https://www.cnblogs.com/xuning/p/8464625.html 基于内存的Redis应该是目前各种web开发业务中最为常用的key-value数据库了,我们经常在 ...

  6. Redis从出门到高可用--Redis复制原理与优化

    Redis从出门到高可用–Redis复制原理与优化 单机有什么问题? 1.单机故障; 2.单机容量有瓶颈 3.单机有QPS瓶颈 主从复制:主机数据更新后根据配置和策略,自动同步到备机的master/s ...

  7. 高可用Redis(八):Redis主从复制

    1.Redis复制的原理和优化 1.1 Redis单机的问题 1.1.1 机器故障 在一台服务器上部署一个Redis节点,如果机器发生主板损坏,硬盘损坏等问题,不能在短时间修复完成,就不能处理Redi ...

  8. 高可用Redis(十三):Redis缓存的使用和设计

    1.缓存的受益和成本 1.1 受益 1.可以加速读写:Redis是基于内存的数据源,通过缓存加速数据读取速度 2.降低后端负载:后端服务器通过前端缓存降低负载,业务端使用Redis降低后端数据源的负载 ...

  9. 使用glusterfs 作为 kubernetes PersistentVolume PersistentVolumeClaim 持久化仓库,高可用Rabbitmq,高可用mysql,高可用redis

    glusterfs 怎么集群,网上一搜铺天盖地的 可利用这个特点做单节点高可用,因为K8S 哪怕节点宕机了 master 会在随意一台节点把挂掉的复活 当然我是在自己的环境下跑,经过网络的gluste ...

随机推荐

  1. h5手机查看

    1.装个node:2.全局装个anywhere的npm包.(npm i -g anywhere)3.大功告成,现在到任意目录下用命令行执行anywhere就可以:(-p 参数可以设置启动端口) 补充: ...

  2. element 给table的个别表格框添加样式 ---重构里面的组件

    <el-table ref="singleTable" :show-header='false' :data="tableData" align='cen ...

  3. Linux下find命令用法详解

    Linux下find命令用法详解   学神VIP烟火 学神IT教育:XueGod-IT   最负责任的线上直播教育平台   本文作者为VIP学员 烟火   第一部分:根据文件名查找   1.在当前目录 ...

  4. form组件+cookie+session总结

    1.forms 组件 -数据校验功能 1.定义 -新建一个py文件 -导入from django import forms -写一个类继承 forms.Form -把你需要校验的(字段的条件)属性写到 ...

  5. Flask框架(1)--基础

    Flask是一个基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架,对于Werkzeug本质是Socket服务端,其用于接收http请求并对请求进行预处理,然后 ...

  6. linux device drivers ch03

    ch03.字符设备驱动程序 编写驱动程序的第一步就是定义驱动程序为用户程序提供的能力(机制).接下来以scull(“Simple Character Utility for Loading Local ...

  7. scws安装

    mkdir scws cd scws wget http://www.xunsearch.com/scws/down/scws-1.2.3.tar.bz2 tar xvjf scws-.tar.bz2 ...

  8. Python的优势及应用领域

    Python的优势 Python是一门解释型语言,是比较容易入门. Python的程序代码更接近英语,更好好理解. Python的扩展库非常丰富. Python与C的粘合性非常好. Python的缺点 ...

  9. 快速掌握Nginx(三) —— Nginx+Systemd托管netcore应用

    以前dotnet web应用程序开发完成后,我们都是使用IIS部署在Windows Server上,如今netcore技术发展迅速,因为其跨平台的特性,将dotnet web应用程序部署在更方便部署和 ...

  10. 0426JavaSE01day02.txt=========正则、Object、包装类详解

    正则表达式 基本正则表达式:正则表达式简介.分组(). "^"和"$" String正则API:matches方法.split方法.replaceAll方法 O ...