【三】redis特点功能

发布时间:2022-09-13 00:30

系列其他文章

  1. redis简介
  2. redis基础命令与使用场景
  3. redis特点功能

redis特点功能

慢查询分析

慢查询日志就是系统在命令执行前后计算每条命令的执行时间,当超过预设阈值,就将这条命令的相关信息(例如:发生时间,耗时,命令的详细信息)记录下来,Redis 也提供了类似的功能

slowlog-log-slower-than: 慢查询时间阈值设置

单位是微妙(1 秒 = 1000 毫秒 = 1000000 微秒),默认是 10000 微秒,如果把 slowlog-log-slower-than 设置为 0,将会记录所有命令到日志中。如果把 slowlog-log-slower-than 设置小于 0,将会不记录任何命令到日志中。

slowlog-max-len: 慢查询存储条数

当慢查询日志列表已经达到最大长度时,最早插入的那条命令将被从列表中移出

建议将慢查询日志的长度调整的大一些。比如可以设置为 1000 以上

除了去配置文件中修改,也可以通过 config set 命令动态修改配置

\> config set slowlog-log-slower-than 1000
OK
\> config set slowlog-max-len 1200
OK
\> config rewrite
OK

slowlog get: 获取慢查询日志. 后面加数字,用于指定获取慢查询日志的条数

> slowlog get 3
1) 1) (integer) 6107        //唯一标识id
   2) (integer) 1616398930  //命令执行的时间戳
   3) (integer) 3109        //命令执行时长
   4) 1) "config"           //执行的命令和参数
      2) "rewrite"
2) 1) (integer) 6106
   2) (integer) 1613701788
   3) (integer) 36004
   4) 1) "flushall"

Pipeline(流水线)机制

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 命令的执行结果按顺序返回给客户端

当你要执行很多的命令并返回结果的时候,需要考虑 List 对象的大小,因为它会“吃掉”服务器上许多的内存空间,严重时会导致内存不足,引发 JVM 溢出异常,所以在工作环境中,是需要自己去评估的,可以考虑使用迭代的方式去处理。

事务与 Lua

multi 和 exec 命令

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

使用案例:

127.0.0.1:6379> multi
OK
127.0.0.1:6379> SET msg "hello chrootliu"
QUEUED
127.0.0.1:6379> GET msg
QUEUED
127.0.0.1:6379> EXEC
1) OK
1) hello chrootliu

redis简单事务不支持事务中的回滚特性,同时无法实现命令之间的逻辑关系计算,主要有以下几点:

  1. 不够满足原子性。一个事务执行过程中,其他事务或 client 是可以对相应的 key 进行修改的(并发情况下,例如电商常见的超卖问题),想要避免这样的并发性问题就需要使用 WATCH 命令,但是通常来说,必须经过仔细考虑才能决定究竟需要对哪些 key 进行 WATCH 加锁。然而,额外的 WATCH 会增加事务失败的可能,而缺少必要的 WATCH 又会让我们的程序产生竞争条件。
  2. 后执行的命令无法依赖先执行命令的结果。由于事务中的所有命令都是互相独立的,在遇到 exec 命令之前并没有真正的执行,所以我们无法在事务中的命令中使用前面命令的查询结果。我们唯一可以做的就是通过 watch 保证在我们进行修改时,如果其它事务刚好进行了修改,则我们的修改停止,然后应用层做相应的处理。
  3. 事务中的每条命令都会与 Redis 服务器进行网络交互。Redis 事务开启之后,每执行一个操作返回的都是 queued,这里就涉及到客户端与服务器端的多次交互,明明是需要一次批量执行的 n 条命令,还需要通过多次网络交互,显然非常浪费(这个就是为什么会有 pipeline 的原因,减少 RTT 的时间)。

Redis 事务缺陷的解决 – Lua

Lua 是一个小巧的脚本语言,用标准 C 编写,几乎在所有操作系统和平台上都可以编译运行。一个完整的 Lua 解释器不过 200k,在目前所有脚本引擎中,Lua 的速度是最快的,这一切都决定了 Lua 是作为嵌入式脚本的最佳选择。

Redis 2.6 版本之后内嵌了一个 Lua 解释器,可以用于一些简单的事务与逻辑运算,也可帮助开发者定制自己的 Redis 命令(例如:一次性的执行复杂的操作,和带有逻辑判断的操作),在这之前,必须修改源码。

在 Redis 中执行 Lua 脚本有两种方法:eval 和 evalsha,这里以 eval 做为案例介绍:

eval 语法:

eval script numkeys key [key ...] arg [arg ...]

其中:

  • script 一段 Lua 脚本或 Lua 脚本文件所在路径及文件名
  • numkeys Lua 脚本对应参数数量
  • key [key …] Lua 中通过全局变量 KEYS 数组存储的传入参数
  • arg [arg …] Lua 中通过全局变量 ARGV 数组存储的传入附加参数

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号