《Redis开发与运维》第三章笔记

364 阅读3分钟
原文链接: idealv.github.io

第三章 小功能大用处

本章讲了很多redis的附加功能,这里只列出个人认为比较实用的功能

  • 慢查询优化
  • redis shell
  • Pipeline
  • 事务与Lua
  • Bitmaps
  • 发布订阅

3.1.慢查询优化

慢查询日志:

系统计算命令执行所耗费的时间,当这个时间超过了预设阈值,就将这条命令的信息写入慢查询日志中

一条客户端命令的生命周期为:

  1. 发送命令
  2. 命令排队
  3. 命令执行
  4. 返回结果

redis的慢查询机制只查询第三步前后耗费的时间,所以没有慢查询问题不代表没有超时问题

3.1.1.慢查询的两个参数配置

  1. 预设阈值:slowlog-log-slower-than(slowlog-max-len:说明了慢查询日志能存储多少条)
  2. 慢查询日志存放位置:存放在redis的一个列表里,如果日志条数超过slowlog-max-len则队头出队,队尾入队

修改参数配置

config set slowlog-log-slower-than xx
config set slowlog-max-len xx
config rewrite

获取慢查询日志

slowlog get [n] //虽然慢查询日志存放在redis中的一个列表中,但redis并没有暴露这个列表的key(n指定条数)
slowlog len //获取slowlog当前长度
slowlog reset //重置

慢查询日志 日志项属性

//伪代码标识
slowlog [
    {
        "标识id":"",
        "发生时间戳":tiemstamp,
        "命令耗时":timestamp,
        "执行命令和参数":""
    },
    {
        ...
    }
]

最佳实践

  • slowlog-max-len:建议配置为1000以上
  • slowlog-log-slower-than:默认值为10ms,对于高流量场景建议设置为1ms

3.2.reids shell

了解redis cli的一些重要参数

  1. -r:重复命令,知道到达指定次数

    $ redis-cli -r 3 ping
    PONG
    PONG
    PONG
    
  2. -i:每隔几秒执行一次命令,必须要和-r一起使用

    redis-cli -r 5 -i 1 ping //每隔1秒执行一次,一共执行5次
    PONG
    PONG
    PONG
    PONG
    PONG
    
  3. -x:从stdin读取数据作为redis-cli最后的参数

    echo "world" | redis-cli -x set hello
    

3.3.Pipeline

RTT:往返时间

批量操作可以减少RTT,但并不是所有的数据结构都支持批量操作的,所以通过Pipeline技术将多条redis命令转换为一条命令,
将这条命令发给redis server,然后再将返回的结果依次返回给客户端,一般来说通过客户端来使用Pipeline.

3.4.事务与Lua

3.4.1.Redis中的事务

事务的概念不再重复,直接来看redis中的事务

multi //事务开始
exec //事务结束
discard //停止事务执行

在两条命令间执行的命令都不会真正的执行(返回QUEUED),而是保存在redis中,只有提交事务后才会真正得到执行

Redis事务的局限性:

  1. 命令错误:如果命令产生了语法错误,整个事务都无法执行
  2. 运行时错误:如果写错了命令(例如把sadd写成了zadd),提交事务时会发生错误,但redis不支持回滚,需要手动修改错误

3.4.2.Lua基本用法

数据类型:

booleans,numbers,strings,tables(表格)

local strings val="worlds"
local tables myArr={"redis",1,true}

local int sum=0;

for i=1,100
do 
    sum+=i
end

---数组长度
for i=1,#myArr
do 
    print(myArr[i])
end

---ipairs
for index,value in ipairs(myArr)
do 
    print(index)
    print(value)
end

---while循环
while ...
do 
    ...
end

---if else结构
if ...
then
   ...
else
   ...
end

---hash
local tables user_1={age=28,name="xiaoming"}

---function 
fucntion funcName()
    ...
end

3.4.3.在Redis中使用Lua

  1. eval

    eval 'return "hello " .. KEYS[1] .. ARGV[1]' 1(key的个数) redis world
    

    如果脚本较长可以用redi-cli –eval直接执行文件

  2. evalsha:将Lua脚本加载到redis server中,返回该脚本的sha校验和,通过校验和可以直接执行对于脚本,增加复用性

    redis-cli script load "${cat lua_get.lua}" //加载脚本
    evalsha {sha校验和} 1 redis world
    

Redis Api

redis.call("set","hello","world")
redis.call("get","hello")

3.4.3.案例

Lua脚本在redis中提供的好处:

  1. Lua脚本原子执行
  2. 定制命令
  3. 可以将多条命令打包,节省网络开支
lrange_and_incr.lua

local tables mylist=redis.call("lrange",KEYS[1],0,-1)
local int count=0
for index,value in ipairs(mylist)
do 
    redis.call("incr",key)
    count++
end
return count

redis-cli --eval lrange_and_incr.lua hot:user:list
(integer) 5

3.4.4.Redis管理Lua脚本

  1. script load

    script load script
    
  2. script exists

    script exists {sha1}
    
  3. script flush 清理Redis内存以及加载的Lua脚本

  4. script kill 杀死当前执行的Lua脚本

3.5.Bitmaps

Bitmaps给予了开发者操作位的能力,可以简单理解为以位为单位的一个数组,数组每一项只能为0和1

  1. 设置值

    setbit key offset value
    
  2. 获取值

    getbit key offset
    
  3. 获取指定范围值为1的个数

    bitcount key [start] [end]
    
  4. BitMaps间的运算

    bitop op destkey key [key ...] //op:and or not xor
    

    实际案例

    //计算出两天都访问过网站的用户数量
    bit op and unique:users:and:{date1_date2} unique:users:and:{date1} unique:users:and:{date2}
    bitcount unique:users:and:{date1_datet2}
    
  5. 计算BitMaps中第一个值为targetBit的偏移量

    bitpos key targetBit [start] [end]
    
    bitops unique:users:{date} 1 //计算某一天访问网站的最小用户id(偏移量标识用户id,0和1表示是否登录)
    

3.7.发布订阅

  1. 发布消息

    publish channel message
    
    publish channel:sports "XXXXXX"
    
  2. 订阅消息

    subscribe channel [channel ...]
    
  3. 取消订阅

    ubsubscribe [channel [channel ...]]
    punsubscribe [channel [channel ...]] //按照模式匹配取消订阅频道
    
  4. 查看订阅

    pubsub channels [pattern] //查看活跃的频道,也就是当前频道至少有一个订阅者
    pubsub numsub [channel ...] //查看频道订阅数
    pubsub numpat //查看模式订阅数
    

发布订阅模式用于进行服务的解耦,比如某个数据发生了变化能及时的反馈给订阅该频道(该时间)的订阅者,然后做出对于响应