【Redis 开发与运维】小功能大用处


慢查询分析

所谓慢查询日志就是系统在命令执行前后计算每条命令的执行时间,当超过预设阈值,就将这条命令的相关信息(例如:发生时间、耗时、命令的详细信息)记录下来。

  1. 生命周期:发送命令 -> 命令排队 -> 执行命令 -> 返回结果
  • 慢查询发生在第 3 阶段
  • 客户端超时不一定是慢查询,但慢查询是客户端超时的一个可能因素
  1. 两个配置参数
  • slowlog-max-len:保存慢查询的队列最大长度,默认值128
  • slowlog-log-slower-than:慢查询阈值(单位:微秒),表示执行时间大于多少时被记录为慢查询,设为 0 表示记录所有命令,小于 0 表示不记录任何命令,默认值10000(10毫秒)
  • 修改配置方式
    • 一种是修改配置文件
    • 另一种是使用 config set 命令动态修改,例如:
    config set slowlog-max-len 256
    config set slowlog-log-slower-than 1000 
    
  1. 慢查询命令
  • 虽然慢查询日志是存放在 Redis 内存列表中的,但是 Redis 并没有暴露这个列表的键,而是通过一组命令来实现对慢查询日志的访问和管理。
  • slowlog get [n]:获取慢查询队列
  • slowlog len:获取慢查询队列当前长度
  • slowlog reset:清空慢查询队列
  • 慢查询日志结构:
    慢查询日志结构
  1. 运维经验
  • slowlog-log-slower-than 不要设置过大,默认 10ms,通常设置 1ms
  • slowlog-max-len 不要设置过小,通常设置 1000 左右
  • 理解命令的生命周期,慢查询只记录命令执行时间,并不包括命令排队或网络传输时间
  • 定期持久化慢查询日志,由于慢查询日志是一个先进先出的队列,也就是说如果慢查询比较多的情况下,可能会丢失部分慢查询命令。

pipeline(流水线)

Redis 提供了批量操作命令(例如 mget、mset 等),有效地节约 RTT(Round Trip Time,往返时间)。但大部分命令是不支持批量操作的,例如要执行 n 次 hgetall 命令,并没有 mhgetall 命令存在,需要消耗 n 次 RTT。

Pipeline(流水线)机制能改善上面这类问题,它能将一组 Redis 命令进行组装,通过一次 RTT 传输给 Redis,再将这组 Redis 命令的执行结果按顺序返回给客户端

  1. 注意
  • pipeline 每次条数要控制(网络请求)
  • pipeline 批量执行命令,目的是节省多次 IO 往返的时间
  • pipeline 每次只能作用在一个 Redis 节点上
  1. pipeline的使用
  • 没有 pipeline,大概需要 50s
Jedis jedis = new Jedis("127.0.0.1", 6379);
for(int i = 0; i < 10000; i++){
	jedis.hset("hashkey:" + i, "field" + i, "value" + i);
}
  • 使用pipeline:大概需要0.7s
Jedis jedis = new Jedis("127.0.0.1", 6379);
for(int i = 0; i < 100; i++){
	Pipeline pipeline = jedis.pipelined();
	for(int j = 0; j < 100; j++){
		pipeline.hset("hashkey:" + j, "field" + j, "value" + j);
	}
	pipeline.syncAndReturnAll();
}
  1. 原生批量命令与 Pipeline 对比
  • 原生批量命令是原子操作,Pipeline 是非原子操作
  • 原生批量命令是一个命令对应多个 key,Pipeline 支持多个命令
  • 原生批量命令是 Redis 服务端支持实现的,而 Pipeline 需要服务端和客户端的共同实现

事务与 Lua

为了保证多条命令组合的原子性,Redis 提供了简单的事务功能以及集成 Lua 脚本来解决这个问题。

  1. 事务
  • Redis 提供了简单的事务功能,将一组需要一起执行的命令放到 multi 和 exec 两个命令之间。
  • multi 命令代表事务开始,exec 命令代表事务结束,他们之间的命令是原子顺序执行的。
  • 注意,Redis 并不支持回滚功能。
  1. Lua
  • Redis 将 Lua 作为脚本语言可帮助开发者定制自己的 Redis 命令。
  • 在 Redis 中执行 Lua 脚本有两种方法:eval 和 evalsha
  • Lua 脚本功能为 Redis 开发和运维人员带来三个好处:
    • Lua 脚本在 Redis 中是原子执行的,执行过程中间不会插入其他命令
    • Lua 脚本可以帮助开发和运维人员创造出自己定制的命令,并可以将这些命令常驻在 Redis 内存中,实现复用的效果
    • Lua 脚本可以将多条命令一次性打包,有效地减少网络开销
  • Redis 提供了 4 个命令实现对 Lua 脚本的管理
    • script load:用于将 Lua 脚本加载到 Redis 内存中
    • script exists:判断 Lua 脚本是否已经加载到内存中
    • script flush:用于清除 Redis 内存已经加载的所有 Lua 脚本
    • script kill:用于杀掉正在执行的 Lua 脚本

BitMaps(位图)

Redis 提供了 Bitmaps 这个“数据结构”可以实现对位的操作。

  1. 数据结构模型
  • 本身不是一种数据结构,实际上它就是字符串,但是它可以对字符串的位进行操作
  • BitMaps 单独提供了一套命令,所以在 Redis 中使用 BitMaps 和使用字符串的方法不太相同。
  1. API
  • setbit key offset value:给位图指定索引设置值,第 offset 位设置成 value,value 只能是 0 或 1
  • getbit key offset:获取某一位的值
  • bitcount key [start end]:获取位图指定范围(start 到 end,单位为字节,不指定表示获取所有)位值为1的个数
  • bitop op destkey key [key...]:做多个 Bitmap 的 and(交集),or(并集),not(非),xor(异或)操作,并将结果保存到 destkey 中
  • bitops key targetBit [start] [end]:计算位图指定范围(start 到 end,单位为字节,如果不指定就是获取全部)第一个偏移量对应的值等于 targetBit 的位置。
  1. 使用经验
  • 位图实际类型就是 string,最大 512MB
  • 注意 setbit 时的偏移量,可能有较大耗时

Hyperloglog

  1. 数据结构模型
  • 并不是一种新的数据结构,实际类型也是字符串类型,而是一种基数算法,通过 Hyperloglog 可以利用极小的内存空间完成独立总数的统计,数据集可以是 IP、Email、ID 等。
  1. API
  • pfadd key element [element ...]:向 Hyperloglog 添加元素
  • pfcount key [key ...]:计算 Hyperloglog 的独立总数
  • pfmerge destkey sourcekey [sourcekey ...]:合并多个 Hyperloglog
  1. 使用经验
  • 是否能够容忍错误?Redis 官方给出的数字是 0.81% 的失误率
  • 是否需要单条语句?这里是无法取出单条语句
  • 使用场景可以是统计一些用户数,而且可以接受一个很小的误差

发布订阅

Redis 提供了基于“发布/订阅”模式的消息机制,此种模式下,消息发布者和订阅者不进行直接通信,发布者客户端向指定的频道(channel)发布消息,订阅该频道的每个客户端都可以收到该消息。

  1. API
  • publish channel message:向 channel 频道发布 message 消息,返回结果是订阅者数
  • subscribe [channel]:可订阅一个或多个频道
  • unsubscribe [channel]:取消订阅
  • psubscribe [pattern...]:订阅模式
  • punsubscribe [pattern...]:退订指定的模式
  • pubsub channels:列出至少有一个订阅者的频道
  • pubsub numsub [channel...]:列出给定频道的订阅者数量
  • pubsub numpat:列出被订阅模式的数量
  1. 使用场景
  • 聊天室、公告牌、服务之间利用消息解耦都可以使用发布订阅模式。

GEO(地理信息定位)

Redis 提供的 GEO 功能,支持存储地理位置信息用来实现诸如附近位置、摇一摇这类依赖于地理位置信息的功能。

  1. API
  • geoadd key lng lat member [lng lat member ...]:增加地理位置信息
  • geopos key member [member ...]:获取地理位置信息
  • geodist key member1 member2 [unit]:获取两个地理位置的距离,unit:m(米),km(千米),mi(英里),ft(尺)
  • georadius:获取地理位置信息
  1. 说明
  • GEO 数据类型是 zset,Redis 间所有地理位置信息的 geohash 存放在 zset 中。
  • GEO 没有提供删除命令,直接使用 zset 命令就行:zrem key member

来源:《Redis 开发与运维》第 3 章 小功能大用处

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

✦昨夜星辰✦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值