Redis实用附加功能功能回顾:从慢查询到发布订阅

本文深入解析Redis的慢查询分析、Shell命令、Pipeline、事务与Lua脚本、Bitmaps、HyperLogLog、发布订阅及GEO等功能,提供最佳实践与性能对比。

目录

一、慢查询分析

慢查询的两个配置参数

慢查询的预设阀值  slowlog-log-slower-than

慢查询日志的长度slowlog-max-len

基本命令

最佳实践

二、Redis Shell

redis-cli讲解

redis-server讲解

redis-benchmark讲解

三、PiPline

原理展示

比较结果

四、事务与Lua脚本

事务的基本命令

Redis与Lua脚本的使用

Redis管理Lua脚本

五、Bitmaps

基本命令:

bitmaps的分析

六、HyperLogLog

基本命令:

性能对比(百万级用户量占用空间比)

七、发布订阅

基本命令

使用场景

八、GEO

九、总结


干货分享,感谢您的阅读!

Redis作为一款高效的内存数据库,被广泛应用于缓存、消息队列、实时数据处理等场景。本篇文章旨在深入探讨Redis的一些实用技巧和高级功能,涵盖了从慢查询分析到发布订阅、从事务与Lua脚本到位图(Bitmaps)和HyperLogLog等多个重要模块。无论是优化Redis性能、提升开发效率,还是掌握Redis的底层原理,本文都将为您提供宝贵的参考和实践指导。

一、慢查询分析

慢查询日志帮助开发和运维人员定位系统存在的慢操作。慢查询日志就是系统在命令执行前后计算每条命令的执行时间,当超过预设阀值,就将这条命令的相关信息(慢查询ID,发生时间戳,耗时,命令的详细信息)记录下来。

慢查询的两个配置参数

慢查询的预设阀值  slowlog-log-slower-than

  • ①单位是微秒,默认值是1000;
  • ②如果slowlog-log-slower-than的值是0,则会记录所有命令;
  • ③如果slowlog-log-slower-than的值小于0,则任何命令都不会记录日志。

慢查询日志的长度slowlog-max-len

  • slowlog-max-len只是说明了慢查询日志最多存储多少条。Redis使用一个列表来存储慢查询日志,showlog-max-len就是列表的最大长度。
  • --通过修改配置文件或命令修改;
  • 基本命令

获取慢查询日志slowlog get [n]
获取慢查询日志列表当前长度  slowlog len
慢查询日志重置slowlog reset

最佳实践

①slowlog-max-len的设置建议:线上环境建议调大慢查询日志的列表,记录慢查询日志时Redis会对长命令做截断操作,并不会占用大量内存。增大慢查询列表可以减缓慢查询被剔除出列表的可能性。例如线上可以设置为1000以上。

②slowlog-log-lower-than的设置建议:需要根据redis的并发量调整该值。由于redis采用单线程响应名利,对于高流量的场景,如果执行命令的时间在1毫秒以上,那么redis最多可支撑OPS(每秒操作次数)不到1000,因此高OPS场景的REDIS建议设置为1毫秒。

③慢查询只记录命令执行时间,并不包括命令排队时间和网络传输时间。

因此客户端命令的执行时间要大于redis服务器实际执行命令的时间。

因为命令执行排队极致,慢查询会导致命令级联阻塞,因此当客户端出现请求超时,需要检查该时间点是否有对应的慢查询,从而分析是否因为慢查询导致的命令级联阻塞

④慢查询日志是一个先进先出队列,慢查询较多的情况下,可能会丢失部分慢查询命令,可以定期执行slow get命令将慢查询日志持久化到其他存储中。然后制作可视化界面查询。

二、Redis Shell

redis-cli讲解

查看redis-cli命令帮助redis-cli help
按指定的次数重复执行命令redis-cli –r count commond
几秒钟执行一次命令redis-cli –i seconds command
从标准输入读取数据做为redis-cli的最后一个参数echo ‘’ | redis-cli –x command
连接集群防止moved和ask异常redis-cli –c
配置密码redis-cli –a
扫描指定模式键redis-cli –scan和-pattern
模拟Redis从节点 redis-cli –slave
生成并发送RDB持久化文件redis-cli –rdb
批量命令封装redis-cli --pipe
找到内存占用较大的键值redis-cli –bigkeys

检测网络延迟

---Latency有三个选型,分别是—latency,--latency-history、--latency-dist

redis-cli –latency
实时获取redis重要统计信息redis-cli –stat
命令的返回结果是否原始格式redis-cli –raw 和 --noraw 

redis-server讲解

默认配置启动redis-server
运行配置启动redis-server --port 6389 –timeout 3000
配置文件启动redis-server redis.conf
内存检测redis-server–test-memory 1024

redis-benchmark讲解

◎redis-benchmark  [-c 并发数] [-n 总请求数] [–q][-r count]

三、PiPline

Redis客户端与Redis之间使用TCP协议进行连接,一个客户端可以通过一个socket连接发起多个请求命令。每个请求命令发出后client通常会阻塞并等待redis服务处理,redis处理完后请求命令后会将结果通过响应报文返回给client,因此当执行多条命令的时候都需要等待上一条命令执行完毕才能执行,而管道(pipeline)可以一次性发送多条命令并在执行完后一次性将结果返回,pipeline通过减少客户端与redis的通信次数来实现降低往返延时时间。

原理展示

比较结果

/*
 * 测试普通模式与PipeLine模式的效率: 
 * 测试方法:向redis中插入10000组数据
 */
public static void testPipeLineAndNormal(Jedis jedis) throws InterruptedException
{
    long start = System.currentTimeMillis();
    for (int i = 0; i < 10000; i++) 
    {
        jedis.set(String.valueOf(i), String.valueOf(i));
    }
    long end = System.currentTimeMillis();
    System.out.println("the jedis total time is:" + (end - start));

    Pipeline pipe = jedis.pipelined();// 先创建一个pipeline的链接对象
    long start_pipe = System.currentTimeMillis();
    for (int i = 0; i < 10000; i++) 
    {
        pipe.set(String.valueOf(i), String.valueOf(i));
    }
    pipe.sync();// 获取所有的response
    long end_pipe = System.currentTimeMillis();
    System.out.println("the pipe total time is:" + (end_pipe - start_pipe));

    BlockingQueue<String> logQueue = new LinkedBlockingQueue<String>();
    long begin = System.currentTimeMillis();
    for (int i = 0; i < 10000; i++) 
    {
        logQueue.put("i=" + i);
    }
    long stop = System.currentTimeMillis();
    System.out.println("the BlockingQueue total time is:" + (stop - begin));
}

四、事务与Lua脚本

事务,一组动作,要么全部执行,要么就全部不执行。从而避免出现数据不一致的情况。

redis提供了简单的事务功能,将一组需要的命令放到multi和exec两个命令之间,multi代表事务开始,exec代码事务结束。

事务的基本命令

事务开始multi
事务结束exec
事务乐观锁watch
事务停止discard

---在事务中如果出现命令错误或运行时错误,针对命令错误将会造成整个事务无法进行,而运行时错误由于redis无回退功能,只能由开发人员自己解决。

Redis与Lua脚本的使用

在Redis中执行Lua脚本的方法主要有两种:eval和evalsha。

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

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

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

②evalsha

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

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

Redis管理Lua脚本

将Lua脚本加载到redis内存中script load script
是否将sha1加载到redis内存中scripts exists sh1 [sha1 ...]
清除加载到redis内存中的所有Lua脚本script flush
用于杀掉正在执行的Lua脚本script kill

五、Bitmaps

Bitmaps可以用来做独立用户统计,有效节省内存。

基本命令:

设置值  setbit key offset value     (offset从0开始)
获取值getbit key offset
获取指定范围内值为1的个数bitcount [start] [end]  start与end代表字节数
bitmaps间的运算

bitop op destkey key [key ...]

--op: and or not xor 交并非异运算

计算bitmaps中第一个值为targetbit的偏移量bitpos key targetbit [start] [end]

bitmaps的分析

假设网站有1亿用户,每天独立访问的用户有5千万,如果每天用集合类型和Bitmaps分别存储活跃用户,set和Bitmaps存储一天活跃用户的对比如下

数据类型 每个用户id占用空间需要存储的用户量全部内存量
集合类型64位50 000 00064位×50 000 000 = 400MB
Bitmaps1位100 000 0001位×100 000 000 = 12.5MB

很明显,这种情况下使用Bitmaps能节省很多的内存空间,尤其是随着时间推移节省的内存还是非常可观的,set和Bitmaps存储独立用户空间对比:

一天一个月一年
set400M12G144G
Bitmaps12.5M 375M4.5G

Bitmaps并不是万金油,假如该网站每天的独立访问用户很少,例如只有10万(大量的僵尸用户),那么两者的对比如下,set和Bitmaps存储一天活跃用户的对比(独立用户比较少):

数据类型每个userid占用空间需要存储的用户量全部内存量
集合类型64位100 00064位 × 100 000 = 800KB
Bitmaps1位100 000 000 1位 × 100 000 000 = 12.5MB

很显然,这时候使用Bitmaps就不太合适了,因为基本上大部分位都是0。

六、HyperLogLog

HyperLogLog虽然在统计独立总量时存在一定的误差0.81%,但是节省内存量是十分惊人的。

基本命令:

添加pfadd key element [element ...]
计算独立用户数pfcount key [key ...]
合并pfmerge destkey source [source ...]

性能对比(百万级用户量占用空间比)

一天一个月一年
set80M2.4G28G
HyperLogLog15k450k5M


七、发布订阅

Redis提供了发布订阅功能,可以用于消息的传输,Redis的发布订阅机制包括三个部分,发布者,订阅者和Channel。 、

基本命令

发布消息publish channel message
订阅消息subscribe channel [channel ...]
取消消息unsubscribe channel [channel ...]
按照模式订阅和取消订阅psubscribe pattern [pattern...]
punsubscribe pattern [pattern...]
查看活跃频道pubsub channels [pattern]
查看频道订阅数pubsub numsub [channel ...]
查看模式订阅数pubsub numspat

使用场景

视频服务订阅video:change频道

  subcribe video:change

视频管理系统发布消息到video:change频道

  publish video:change “video1, video3, video5”

当视频服务收到消息,对视频信息进行更新

  for video in video1, video3, video5

  update{video}

八、GEO

主要用于诸如附近位置、摇一摇这类依赖于地理位置信息的功能。

增加地理位置信息geoadd key longitude latitude member  [longitude latitude member ...]
获取地理位置信息 geopos key member [member ...]
获取两个地理位置的距离 

geodist key member1 member2 [unit]

---unit代表返回单位:m km mi ft

获取指定位置范围内地理信息位置信息georadius key longitude latitude radiusm|km|ft|mi [withcoord] [withdist] [withhash] [COUNT count] [asc|desc]  [store key] [storedist key]
georadiusbymember key memeber radiusm|km|ft|mi [withcoord] [withdist] [withhash] [COUNT count] [asc|desc] [store key] [storedist key]
获取geohashgeohash key member [member ...]
删除地理位置信息zrem key member

九、总结

本文介绍了Redis的一些核心附加功能,包括慢查询分析、Redis Shell、Pipeline、事务与Lua脚本、Bitmaps、HyperLogLog、发布订阅等模块。通过这些功能,开发人员可以更高效地使用Redis,提升性能和节省内存。以下是一些模块的总结对比:

功能模块主要用途优势注意事项
慢查询分析帮助定位和优化性能瓶颈提高系统响应速度,避免长时间阻塞慢查询只记录命令执行时间,不包含排队和传输时间
Redis Shell提供与Redis的交互方式支持批量命令、延时检测、性能分析等功能使用时需要注意连接的稳定性和配置的正确性
Pipeline多条命令批量发送,减少通信开销显著提升大量命令执行效率适用于命令独立的情况,避免事务中的依赖性问题
事务与Lua脚本保证命令的原子性,减少网络往返延迟通过Lua脚本执行原子操作,提升执行效率事务内命令出错会导致整个事务失败
Bitmaps位图存储减少内存使用,适合统计独立用户等场景节省大量内存,适合大规模独立性数据存储数据量过少时,Bitmaps的效果较差
HyperLogLog进行近似计数,显著减少内存占用对大规模数据计数有极高的内存压缩比存在0.81%的误差
发布订阅进行实时消息传递,解耦发布者与订阅者之间的关系简单实现实时消息推送和订阅,解耦服务组件发布的消息是广播形式,适合实时性需求较高的场景

总的来说,掌握并合理使用这些Redis功能,可以大大提高系统的性能与可扩展性,特别是在高并发和大数据场景中尤为重要。

评论 1590
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

张彦峰ZYF

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

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

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

打赏作者

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

抵扣说明:

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

余额充值