Redis进阶

Redis进阶

慢查询分析

慢查询日志:系统在命令执行前后计算每条命令的执行时间,当超过预设阀值时记录命令相关信息。

配置参数

slowlog-log-slower-than 预设阀值,单位微秒,默认10000 即10ms,为0则记录所有命令,<0不记录

slowlog-max-len 慢查询列表的最大长度,超过则先入先出

修改配置:

  1. 修改配置文件

  2. config set 动态修改

    config set slowlog-log-slower-than 20000

    config set slowlog-max-len 1000

    config rewrite 持久化到本地配置文件

慢查询日志存放在list中,但redis没有暴露key,通过一组命令来查询和管理

  1. 获取慢查询日志

    slowlog get [n]

    返回日志包含4个属性:id, timestamp, duration, command, params

  2. h获取慢查询日志列表当前长度

    slowlog len

  3. 重置

    slowlog reset

实践

  • slowlog-log-slower-than建议10ms,高OPS(operation per second )建议1ms
  • slowlog-max-len 线上如1000
  • 可以定义slow get持久化到其他存储中(CacheCloud)

Redis Shell

redis-cli

  1. -r : repeat, 重复执行多次

    redis-cli -r 3 ping

  2. -i : interval, 执行间隔,单位秒,毫秒可以用0.01,须与-r一起使用

    redis-cli -r 5 -i 1 ping

  3. -x : 从标准输入stdin读取数据作为redis-cli的最后一个参数

    echo “word” | redis-cli -x set hello

  4. -c : cluster, 连接redis cluster结点使用,防止moved和ask异常

  5. -a : auth, 如果配置了密码可以使用该选项

  6. --scan--pattern : 扫描指定模式的key,相当于使用scan命令

  7. --slave : 把当前客户端模拟为当前redis结点的从节点,可以获取当前redis结点的更新操作

  8. --rdb : 请求redis生成并发送RDB文件存于本地,可用于持久化备份

  9. --pipe : 用于将命令封装为redis通信协议定义的数据格式,批量发送给redis执行

  10. --bigkeys : 使用scan命令对redis的key进行采样,找到内存占用比较大的value,可能是系统瓶颈

  11. --eval : 执行指定Lua脚本

  12. --latency : 用于检测网络延迟

    • --latency : 测试客户端到目标redis的网络延迟 redis-cli -h {host} –latency
    • --latency-history : 每15s输出一次,可以-i控制间隔 redis-cli -h {host} –latency-history
    • --latency-dist : 使用统计图表的形式从控制台输出延迟统计信息
  13. --stat : 实时获取redis重要统计信息

  14. --raw--no-raw : 返回格式化后的结果还是返回原始结果

redis-server

--test-memory 选项,用来检测当前操作系统能否稳定地分配指定容量的内存给redis

避免因内存问题造成redis崩溃。

redis-server –test-memory 1024 检测OS能否提供1G的内存给redis

检测时间较长,输出passed this test说明检测完毕

redis-benchmark

  1. -c : clients , 客户端并发数量,默认50
  2. -n<requests> : 客户端请求总量,默认100000
  3. -q : 仅显示redis-benchmark的requests per second信息
  4. -r : random, 插入更多的随机key,会在key、counter键上加一个12位的后缀 -r10000代表只对value后四位做随机处理
  5. -P : 每个请求pipeline的数据量,默认为1
  6. -k<boolean> : keepalive,客户端是否使用keepalive,1为使用,0为不使用,默认为1
  7. -t : 对指定命令进行基准测试 redis-benchmark -t get,set -q
  8. -csv : 将结果按csv格式输出

Pipeline

客户端执行一条命令有如下过程:

graph LR
    a(发送命令) --> b(命令排队)
    b --> c(命令执行)
    c --> d(返回结果)

合起来成为Round Trip Time,即RTT,往返时间

pipeline指将一组redis命令进行组装,通过一次RTT传输给redis,结果按顺序返回

对比原生批量命令

  • 原生批量命令是原子的,Pipeline是非原子的
  • 原生批量命令是一个命令对应多个key,Pipeline支持多个命令
  • 原生批量命令时服务端支持实现,Pipeline需要服务端和客户端共同实现

可以将包含大量命令的Pipeine拆分为多次较小的Pipeline来完成

事务与Lua

事务与Lua用来保证多条命令组合的原子性

事务

事务表示一组动作,要么全部执行,要么全部不执行

multi
cmd1
cmd2
...
exec

multi 代表事务开始

exec 代表事务结束

discard 停止事务的执行

错误处理:

  • 命令错误:事务无法执行
  • 运行时错误:redis不支持回滚,需要自己修复

watch命令:类似乐观锁,确保事务中的key没被其他客户端修改过,才执行事务,否则不执行

Lua简述

数据类型

booleans, numbers, strings, tables

local val = "world"
local myarray = {"redis", "jedis", true, 88.0} 数组下标从1开始
--comment

循环

local int sum = 0
for i = 1, 100
do
    sum = sum + i
end
print(sum)

while i <= 100
do
    ...
end

去数组长度#array

遍历数组

for index, value in ipairs(myarray)
do
    ...
end

条件判断

if xxx
then
    ...
else
    ...
end

使用table

local  user = {age=28, name="tome"}
for key,value in pairs(user)
do
    print(key .. value)
end

函数

function funcName()
    ...
end

Redis与Lua

Redis执行Lua

  1. eval

    eval 脚本内容 key个数 key列表 参数列表

    eval ‘return “hello ” .. KEYS[1] .. ARGV[1] ’ 1 redis word

    返回 “hello redisworld”

    如果Lua脚本较长,可以使用redis-cli –eval file执行文件

  2. evalsha

    首先将Lua脚本加载到redis服务端,得到脚本的SHA1校验和

    该命令使用SHA1作为参数执行对应Lua脚本,避免每次发送

    加载脚本:

    redis-cli script load “$(cat lua_get.lua)”

    执行脚本:

    evalsha 脚本SHA1 key个数 key列表 参数列表

Lua的Redis API

使用redis.call函数访问redis,如果执行失败,直接返回错误

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

redis.pcall 则忽略错误继续执行脚本

redis.log 将Lua脚本的日志输出到redis日志文件,注意控制日志级别

redis 3.2提供了Lua Script Debugger来调试复杂的Lua脚本

Redis管理Lua脚本

  1. script load script
  2. script exists sha1
  3. script flush 清除内存加载的所有Lua脚本
  4. script kill 杀掉正在执行的Lua脚本,如果Lua正在执行写操作,则kill不生效,只能等或者shutdown save

Bitmaps

Bitmaps实际就是字符串,提供了一组api可以对字符串的bit进行操作

命令

  1. 设置

    setbit key offset value 设置第offset个bit的值

    第一次初始化Bitmaps时,如果偏移量非常大,可能造成redis阻塞

  2. 获取

    gitbit key offset

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

    bitcount [start] [end] start end代表字节数

  4. Bitmaps间运算

    bitop op destkey key [key …] 运算结果保存在destkey中

    op可以是and, or, not, xor,分别为 交集,并集,非,异或

  5. 计算Bitmaps中第一个值为targetBit的offset

    bitpos key targetBit [start] [end]

HyperLogLog

HyperLogLog实际类型为字符串类型,是一种基数算法,可以利用极小的内存完成独立总数的统计。

命令

  1. 添加

    pfadd key element [element … ] 向HyperLogLog添加元素,成功返回1

  2. 计算独立总数

    pfcount key [key … ]

    存在一定的误差率,redis官方数据位0.81%的失误率

  3. 合并

    pfmerge destkey sourcekey [sourcekey … ]

    求多个HyperLogLog的并集赋值给destkey

选型:

  1. 只为计算独立总数,不需要获取单条数据
  2. 可以容忍一定误差率

发布订阅

消息发布者和订阅者不直接通信,发布者客户端向指定channel发布消息,订阅该channel的每个客户端可以收到该消息。

redis提供了发布、订阅、取消订阅、按模式订阅和取消等命令

命令

  1. 发布消息

    publish channel message 返回订阅的客户端数

  2. 订阅消息

    subscribe channel [channel … ] 订阅一个或多个频道

    客户端执行订阅命令后,进入订阅状态,只能接收subscribe, psubscribe, unsubscribe, punsubscribe

    新开启的订阅客户端无法收到频道之前的消息,redis不会做持久化

  3. 取消订阅

    unsubscribe [channel [channel … ] ]

  4. 按模式订阅和取消订阅

    psubscribe pattern [pattern … ]

    punsubscribe [pattern [pattern … ] ]

    glob风格

  5. 查询订阅

    查看活跃频道

    pubsub channels [pattern] 至少有一个订阅者

    查看频道订阅数

    pubsub numsub [channel … ]

    查看模式订阅数

    pubsub numpat

使用场景

聊天室、公告牌、服务之间利用消息解耦

GEO

redis 3.2提供了GEO(地理信息定位),存储地理位置信息来实现附近位置、摇一摇等功能

GEO由Matt Stancliff借鉴NoSQL数据库Ardb(中国)实现。

命令

  1. 增加

    geoadd key longitude latitude member [longitude latitude member … ]

    对应地理位置的经度、纬度、成员

    返回添加成功数,已存在返回0

    更新同样使用geoadd

  2. 获取

    geopos key member [member … ]

    例如:geopos cities:locations beijing

  3. 获取两个地理位置的距离

    geodist key member1 member2 [unit]

    unit表示结果单位:

    • m:meters,米
    • km:kilometers,千米
    • mi:miles,英里
    • ft:feet,尺
  4. 获取指定位置范围内的地理信息位置集合

    georadius key longtitude latitude radius m|km|ft|mi [withcoord] [withdist] [withhash] [COUNT count] [asc|desc] [store key] [storedist key]

    georadiusbymember key member radius m|km|ft|mi [withcoord] [withdist] [withhash] [COUNT count] [asc|desc] [store key] [storedist key]

    • radius m|km|ft|mi用于指定半径
    • withcoord 结果包含经纬度
    • withdist 结果包含离中心节点位置的距离
    • withhash 结果包含geohash
    • COUNT count 指定返回结果数量
    • asc|desc 结果按离中心节点距离做升序或降序
    • store key 将返回结果的地理位置信息保存到指定key
    • storedist key 将返回结果离中心节点的距离保存到指定key
  5. 获取geohash

    geohash key member [member …]

    将二维经纬度转换为一维字符串

    • GEO的数据类型为zset,redis将所有地理位置的geohash存放在zset中
    • 字符串越长,表示的位置更精确,geohash长度为9时,精度在2米左右
    • 字符串越相似,距离越近,redis用字符串前缀匹配算法实现相关命令
    • geohash编码和经纬度是可以相互转换的
  6. 删除

    zrem key member

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值