redis学习笔记——第三章 小功能大用处

第三章 小功能大用处

3.1 慢查询分析

Redis客户端执行一条命令分为如下4个部分
1)发送命令
2)命令排队
3)命令执行
4)返回结果
[外链图片转存失败(img-3bLan4Ls-1562315155115)(C:\Users\yx20180503\AppData\Roaming\Typora\typora-user-images\1561618971151.png)]

3.1.1 慢查询的两个配置参数

对于慢查询功能,需要明确两件事:
·预设阀值怎么设置?
·慢查询记录存放在哪?
Redis提供了slowlog-log-slower-than和slowlog-max-len配置来解决这两个问题。从字面意思就可以看出,slowlog-log-slower-than就是那个预设阀值,它的单位是微秒(1秒=1000毫秒=1000000微秒),默认值10000,假如执行了一条“很慢”的命令(例如keys*),如果它的执行时间超过了10000微秒,那么它将被记录在慢查询日志中.

**如果slowlog-log-slower-than=0会记录所有的命令,slowlog-log-slowerthan<0对于任何命令都不会进行记录。**

在Redis中有两种修改配置的方法:

1. 一种是修改配置文件,
2.   另一种是使用config set命令动态修改。例如下面使用config set命令将slowlog-log-slowerthan设置为20000微秒,slowlog-max-len设置为1000
3. 如果要Redis将配置持久化到本地配置文件,需要执行config rewrite命令

(1)获取慢查询日志 slowlog get [n]
(2)获取慢查询日志列表当前的长度slowlog len

(3)慢查询日志重置 slowlog reset 实际是对列表做清理操作

3.1.2 最佳实践
慢查询功能可以有效地帮助我们找到Redis可能存在的瓶颈,但在实际使用过程中要注意以下几点:
  1. slowlog-max-len配置建议:线上建议调大慢查询列表,记录慢查询时Redis会对长命令做截断操作,并不会占用大量内存。增大慢查询列表可以减缓慢查询被剔除的可能,例如线上可设置为1000以上。
  2. slowlog-log-slower-than配置建议:默认值超过10毫秒判定为慢查询,需要根据Redis并发量调整该值。由于Redis采用单线程响应命令,对于高流量的场景,如果命令执行时间在1毫秒以上,那么Redis最多可支撑OPS不到1000。因此对于高OPS场景的Redis建议设置为1毫秒。
  3. 慢查询只记录命令执行时间,并不包括命令排队和网络传输时间。因此客户端执行命令的时间会大于命令实际执行时间。因为命令执行排队机制,慢查询会导致其他命令级联阻塞,因此当客户端出现请求超时,需要检查该时间点是否有对应的慢查询,从而分析出是否为慢查询导致的命令级联阻塞。
  4. 由于慢查询日志是一个先进先出的队列,也就是说如果慢查询比较多的情况下,可能会丢失部分慢查询命令,为了防止这种情况发生,可以定期执行slow get命令将慢查询日志持久化到其他存储中(例如MySQL),然后
    可以制作可视化界面进行查询

3.2 Redis Shell

	Redis提供了redis-cli、redis-server、redis-benchmark等Shell工具。

Pipeline概念

Redis客户端执行一条命令分为如下四个过程:
1)发送命令
2)命令排队
3)命令执行
4)返回结果
Redis提供了批量操作命令(例如mget、mset等),有效地节约RTT。但大部分命令是不支持批量操作的,例如要执行n次hgetall命令,并没有mhgetall命令存在,需要消耗n次RTT。Redis的客户端和服务端可能部署在不同的机器上。例如客户端在北京,Redis服务端在上海,两地直线距离约为1300公里,那么1次RTT时间=1300×2/(300000×2/3)=13毫秒(光在真空中传输速度为每秒30万公里,这里假设光纤为光速的2/3),那么客户端在1秒内大约只能执行80次左右的命令,这个和Redis的高并发高吞吐特性背道而驰。

Pipeline(流水线)机制能改善上面这类问题,它能将一组Redis命令进行组装,通过一次RTT传输给Redis,再将这组Redis命令的执行结果按顺序返回给客户端,图3-5为没有使用Pipeline执行了n条命令,整个过程需要n次
RTT。

在这里插入图片描述
[外链图片转存失败(img-lbKErCFM-1562315155117)(C:\Users\yx20180503\AppData\Roaming\Typora\typora-user-images\1561619938655.png)]

3.2.1 原生批量命令与Pipeline对比
可以使用Pipeline模拟出批量操作的效果,但是在使用时要注意它与原生批量命令的区别,具体包含以下几点:
  1. 原生批量命令是原子的,Pipeline是非原子的。
  2. ·原生批量命令是一个命令对应多个key,Pipeline支持多个命令。
  3. ·原生批量命令是Redis服务端支持实现的,而Pipeline需要服务端和客户端的共同实现。

3.3 事务

3.3.1 事务
命令:
  1. multi 代表事务开始

  2. exec 令代表事务结束

  3. discard 停止事务的执行

  4. watch 确保事务中的key没有被其他客户端修改过,才执行事务,否则不执行(类似乐观锁)

    Redis提供了简单的事务功能,将一组需要一起执行的命令放到multiexec两个命令之间。multi命令代表事务开始,exec命令代表事务结束,它们之间的命令是原子顺序执行的 .

    如果要停止事务的执行,可以使用discard命令代替exec命令即可

如果事务中的命令出现错误,Redis的处理机制也不尽相同。

  1. 命令错误
    例如下面操作错将set写成了sett,属于语法错误,会造成整个事务无法执行,key和counter的值未发生变化127.0.0.1:6388> mget key counter

    1. “hello”
    2. “100”
      127.0.0.1:6388> multi
      OK
      127.0.0.1:6388> sett key world
      (error) ERR unknown command ‘sett’
      127.0.0.1:6388> incr counter
      QUEUED
      127.0.0.1:6388> exec
      (error) EXECABORT Transaction discarded because of previous errors.
      127.0.0.1:6388> mget key counter
    3. “hello”
    4. “100”
  2. 运行时错误
    例如用户B在添加粉丝列表时,误把sadd命令写成了zadd命令,这种就
    是运行时命令,因为语法是正确的:
    127.0.0.1:6379> multi
    OK
    127.0.0.1:6379> sadd user?️follow user:b
    QUEUED

    127.0.0.1:6379> zadd user?️fans 1 user:a
    QUEUED
    127.0.0.1:6379> exec

    1. (integer) 1
    2. (error) WRONGTYPE Operation against a key holding the wrong kind of value
      127.0.0.1:6379> sismember user?️follow user:b
      (integer) 1

    可以看到Redis并不支持回滚功能,sadd user:a:follow user:b命令已

经执行成功,开发人员需要自己修复这类问题

  1. 有些应用场景需要在事务之前,确保事务中的key没有被其他客户端修
    改过,才执行事务,否则不执行(类似乐观锁)。Redis提供了watch命令来
    解决这类问题

3.4 Bitmaps

3.4.1数据结构模型

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

  1. Bitmaps本身不是一种数据结构,实际上它就是字符串,但是它可以对字符串的位进行操作。
  2. Bitmaps单独提供了一套命令,所以在Redis中使用Bitmaps和使用字符串的方法不太相同。可以把Bitmaps想象成一个以位为单位的数组,数组的每个单元只能存储0和1,数组的下标在Bitmaps中叫做偏移量。
3.4.2 命令

1.设置值 setbit key offset value

127.0.0.1:6379> setbit unique:users:2016-04-05 0 1
(integer) 0

2.获取值 gitbit key offset 返回0说明没有访问过

127.0.0.1:6379> getbit unique:users:2016-04-05 8
(integer) 0

3.获取Bitmaps指定范围值为1的个数

bitcount [start]  [end]
下面操作计算2016-04-05这天的独立访问用户数量:
	127.0.0.1:6379> bitcount unique:users:2016-04-05
	(integer) 5

[start]和[end]代表起始和结束字节数,下面操作计算用户id在第1个字节
到第3个字节之间的独立访问用户数

127.0.0.1:6379> bitcount unique:users:2016-04-05 1 3
(integer) 3

4.itmaps间的运算 bitop op destkey key[key…]

	bitop是一个复合操作,它可以做多个Bitmaps的and(交集)、or(并

集)、not(非)、xor(异或)操作并将结果保存在destkey中。

127.0.0.1:6379> bitop or unique:users:or:2016-04-04_03 unique:users:2016-04-03 unique:users:2016-04-03

(integer) 2
127.0.0.1:6379> bitcount unique:users:or:2016-04-04_03
(integer) 6

5.计算Bitmaps中第一个值为targetBit的偏移量

bitpos key targetBit [start] [end]

 127.0.0.1:6379> bitpos unique:users:2016-04-04 1

(integer) 1

	除此之外,bitops有两个选项[start]和[end],分别代表起始字节和结束字

节,例如计算第0个字节到第1个字节之间,第一个值为0的偏移量,从图3-
13可以得知结果是id=0的用户

	127.0.0.1:6379> bitpos unique:users:2016-04-04 0 0 1

(integer) 0

3.4.3 Bitmaps分析

3.5HyperLogLog

		HyperLogLog并不是一种新的数据结构(实际类型为字符串类型),而是一种基数算法,通过HyperLogLog可以利用极小的内存空间完成独立总数的统计,数据集可以是IP、Email、ID等。HyperLogLog提供了3个命令:pfadd、pfcount、pfmerge

1 .添加

pfadd key element [element …]
pfadd用于向HyperLogLog添加元素,如果添加成功返回1:
127.0.0.1:6379> pfadd 2016_03_06:unique:ids "uuid-1" "uuid-2" "uuid-3" "uuid-4"
(integer) 1

本章重点回顾

  1. 慢查询中的两个重要参数slowlog-log-slower-than和slowlog-maxlen。
  2. 慢查询不包含命令网络传输和排队时间。
  3. 有必要将慢查询定期存放。
  4. redis-cli一些重要的选项,例如–latency、–-bigkeys、-i和-r组合。
  5. redis-benchmark的使用方法和重要参数。
  6. Pipeline可以有效减少RTT次数,但每次Pipeline的命令数量不能无节制。
  7. Redis可以使用Lua脚本创造出原子、高效、自定义命令组合。
  8. Redis执行Lua脚本有两种方法:eval和evalsha。
  9. Bitmaps可以用来做独立用户统计,有效节省内存。
  10. Bitmaps中setbit一个大的偏移量,由于申请大量内存会导致阻塞。
  11. HyperLogLog虽然在统计独立总量时存在一定的误差,但是节省的内存量十分惊人。
  12. Redis的发布订阅机制相比许多专业的消息队列系统功能较弱,不
    具备堆积和回溯消息的能力,但胜在足够简单。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值