【AICon】探索RAG 技术在实际应用中遇到的挑战及应对策略!AICon精华内容已上线73%>>> 了解详情
写点什么

Redis 开发设计规范及案例分析

  • 2019-10-21
  • 本文字数:3290 字

    阅读完需:约 11 分钟

Redis开发设计规范及案例分析

redis 不是垃圾桶也不是 SUPER MAN,能力和资源都有限,不合理的使用会降低它的健康度,严重时甚至会引起 redis 抖动、阻塞等进而导致服务不可用,每一个使用 redis 的开发人员都应当掌握规范的开发和使用方法。本文整理出 redis 开发过程中七个较常出现的使用不合理的场景,并辅以案例进行分析说明。

01 合理使用集合类

案例

某活动需求,每天 10 点对昨天参加某活动的用户进行推送提醒。开发人员使用 redis 存储每天参加活动的用户,通过 ZRANGEBYSCORE 命令获取目标用户进行提醒,提醒完后使用 ZREMRANGEBYSCORE 命令从 redis 中清除这批用户。某一天 ZRANGEBYSCORE、ZREMRANGEBYSCORE 均出现了慢日志报警,排查发现这一天参加该活动的用户约有 5 万。

分析

案例中使用了 redis 的 sortedset 来储存用户信息,其中 value 是用户的账号、score 是用户参加活动的时间,由于 ZRANGEBYSCORE 和 ZREMRANGEBYSCORE 命令的时间复杂度是 O(log(N) + M),其中 M 是操作的元素个数,N 是集合元素总数,本例中当用户数量为 5 万时出现慢日志。可以通过缩小每次查询的集合数量,可以将一天分成多段,分批次查询,比如把查 24 小时范围的用户改为查 4 小时范围的用户,分别查 6 次处理即可。

Q

如果用户参加活动的时间很集中,在某一个时间段(比如晚 18 点到 22 点)查出来的数量还是特别多怎么办?

A

可以把粒度分得更细一些比如 1 小时或者 30 分钟,如果确定用户参加活动集中在某个时间点,可以考虑使用 ZSCAN 遍历操作并删除。另外,对于目标时间范围有确定的首尾元素时,还可以通过 ZRANK 命令查出元素的位置,通过 ZRANGE 以及 ZREMRANGEBYRANK 来进行查询和删除操作,这样每次操作可以控制操作数量,有效避免慢日志。

小结

使用 sortedset、set、list、hash 等集合类的 O(N)操作时要评估当前元素个数的规模以及将来的增长规模,对于短期就可能变为大集合的 key,要预估 O(N)操作的元素数量,避免全量操作,可以使用 HSCAN、SSCAN、ZSCAN 进行渐进操作。集合元素数量过大在使用过程中会影响 redis 的实际性能,元素个数建议尽量不要超过 5000,元素数量过大可考虑拆分成多个 key 进行处理。

02 合理设置过期时间

案例 1

某投票功能,用于统计今日环比昨日的增长数量,开发人员使用 redis 存储每天的投票数,key 设计为 vote_count_{date},其中{date}为当天的日期,由于没有设置过期时间,一年以后产生了 360 多个 key,实际在用的 key 始终只有 2 个。

分析

该案例中,每个生成的 key 在 2 天以后都不会再使用了,可将 key 加上过期时间。

案例 2

某统计功能,用户会不定期的导入一批数据进 redis,每一批数据需要在 30 分钟后、1 天后、3 天后、7 天后进行计算统计,统计结果发给用户。开发人员使用 redis 的同一个 sortedset 存储这些导入的数据,每天定时任务执行计算任务。由于没有清理,导致大量结束计算任务的废弃数据残留 redis。

分析

该案例中,每一批数据都有相应的生命周期,在导入的第 7 天执行完最后一次计算任务生命周期结束,由于集合里的元素不能单独设置过期时间,可在代码逻辑中对最后一次使用这批数据后进行清理操作。

小结

如果 key 没有设置超时时间,会导致一直占用内存。对于可以预估使用生命周期的 key 应当设置合理的过期时间或在最后一次操作时进行清理,避免垃圾数据残留 redis。

03 合理利用批操作命令

案例

某运营需求,需要给用户生成短链,短链由短链前缀+短码组成,根据短码找到用户对应的手机号,开发人员使用 redis hash 结构存储短码到手机号的映射。接口每次会导入 5 万个手机号。

分析

下面是开发人员的三种操作 redis 方案的伪代码


方案 1:直接使用 redis 的 HSET 逐个设置


for(50000;)HSET(key,短码,手机号)
复制代码


结果:失败。redis ops 飙升,同时接口响应超时


方案 2:改用 redis 的 HMSET 一次将所有元素设置到 hash 中


map<短码,手机号> 50000个元素HMSET(key,map)
复制代码


结果:失败。出现 redis 慢日志


方案 3:依然使用 HMSET,只是每次设置 500 个,循环 100 次


map<短码,手机号> 500个元素for(100;)HMSET(key,map)
复制代码


结果:成功


对于大量频繁的 hset 操作可以使用 HMSET 替代减少 redis 操作次数同时提升处理速度,但是要考虑单次请求操作的数量,避免慢日志。

小结

在 redis 使用过程中,要正视网络往返时间,合理利用批量操作命令,减少通讯时延和 redis 访问频次。redis 为了减少大量小数据 CMD 操作的网络通讯时间开销 RTT (Round Trip Time),支持多种批操作技术:


MSET/HMSET 等都支持一次输入多个 key,LPUSH/RPUSH/SADD 等命令都支持一次输入多个 value,也要注意每次操作数量不要过多,建议控制在 500 个以内;


PipeLining 模式 可以一次输入多个指令。redis 提供一个 pipeline 的管道操作模式,将多个指令汇总到队列中批量执行,可以减少 tcp 交互产生的时间,一般情况下能够有 10%~30%不等的性能提升;


更快的是 Lua Script 模式,还可以包含逻辑。redis 内嵌了 lua 解析器,可以执行 lua 脚本,脚本可以通过 eval 等命令直接执行,也可以使用 script load 等方式上传到服务器端的 script cache 中重复使用。

04 减少不必要的请求

案例

某业务系统,当用户进入某个页面时会同时请求多个接口,每个接口都会校验用户状态是否有效,用户状态存在 redis 里并设置有过期时间,对于 key 未过期但是过期时间大于指定阈值的,需要重新设置有效时间,否则需要使用 del 命令删除掉。但是部分 key 由于过期其实已经不存在了,所以出现部分无效 del 命令。用户越多,就会有越多的无效命令。

分析

ttl 命令对于 key 不存在的情况会返回-2,若 key 不存在则不需要再调用 del 命令,可减少无效请求。

小结

redis 的所有请求对于不存在的 key 都会有输出返回,合理利用返回值处理,避免不必要的请求,提升业务吞吐量。

05 避免 value 设置过大

案例

某开发人员将一个商品集合信息序列化后用 redis 的字符串类型存储,使用的时候再反序列化成对象列表使用,大小超过 1MB,在网络传输的时候由于数据比较大会触发拆包,会降低 redis 的吞吐量。

分析

数量比较多时可以考虑改用 hash 结构存储,每一个 field 是商品 id,value 是该商品对象,如果数量较大可使用 hscan 获取。

小结

String 类型尽量控制在 10KB 以内。虽然 redis 对单个 key 可以缓存的对象长度能够支持的很大,但是实际使用场合一定要合理拆分过大的缓存项,1k 基本是 redis 性能的一个拐点。当缓存项超过 10k、100k、1m 性能下降会特别明显。关于吞吐量与数据大小的关系可见下面官方网站提供的示意图。



吞吐量与数据大小的关系


在局域网环境下只要传输的包不超过一个 MTU(以太网下大约 1500 bytes),那么对于 10、100、1000 bytes 不同包大小的处理吞吐能力实际结果差不多。

06 设计规范的 key 名

可读性

以业务名为前缀,用冒号分隔,可使用业务名:子业务名:id 的结构命名,子业务下多单词可再用下划线分隔。


举例:活动系统-人拉人红包活动-id,可命名为 ACTIVITY:INVITE_REDPACKET:001

简洁性

保证语义的前提下,控制 key 的长度,当 key 较多时,内存占用也不容忽视。

不包含转义字符

不包含空格、换行、单双引号以及其他转义字符。

07 留心禁用命令

keys、monitor、flushall、flushdb 应当通过 redis 的 rename 机制禁掉命令,若没有禁用,开发人员要谨慎使用。其中 flushall、flushdb 会清空 redis 数据;keys 命令可能会引起慢日志;monitor 命令在开启的情况下会降低 redis 的吞吐量,根据压测结果大概会降低 redis50%的吞吐量,越多客户端开启该命令,吞吐量下降会越多。


keys 和 monitor 在一些必要的情况下还是有助于排查线上问题的,建议可在重命名后在必要情况下由 redis 相关负责人员在 redis 备机使用,monitor 命令可借助 redis-faina 等脚本工具进行辅助分析,能更快排查线上 ops 飙升等问题。

总结

本文整理出的几点 redis 开发规范主要是涉及 redis 客户端的使用部分,每个开发人员在使用 redis 开发过程中几乎都会涉及到上述提到的几个问题,需要多多留心,提高代码质量,提升 redis 的健康度。


本文转载自公众号中间件小哥(ID:huawei_kevin)。


原文链接:


https://mp.weixin.qq.com/s/gw1X34vtiwRcEYgLbWp23w


2019-10-21 11:191015

评论

发布
暂无评论
发现更多内容

App Cleaner & Uninstaller for mac(mac应用清理和卸载软件)v8.2.5中文激活版

影影绰绰一往直前

每日一题:LeetCode-128. 最长连续序列

半亩房顶

Go 面试 算法 数组 LeetCode

全面了解 Stable Diffusion API 调用教程

Liam

AI 前端 后端 API Stable Diffusion

AI数字人互动大屏独立部署的优势!

青否数字人

数字人

深度探讨全链路测试:定义、特点及与其他测试方法的对比

Apifox

测试 单元测试 自动化测试 全链路测试 测试工具

iCollections for mac(桌面整理软件) v8.1.81006永久激活版

mac

桌面管理工具 苹果mac Windows软件 iCollections

php设置和获取Cookie教程。

百度搜索:蓝易云

php Linux 运维 Cookie 云服务器

软件开发

Geek_8da502

提炼大模型智慧,助力小模型成长

百度开发者中心

深度学习 模型

互联网巨头想通过小程序来打造封闭生态的“超级App”时代将要翻篇?

Geek_2305a8

软件开发

Geek_8da502

发布!乘云数字参编中国信通院《可观测性技术发展研究报告》正式发布

乘云 DataBuff

QCN6224 vs QCN9224 - as a WiFi7 card chip - What are the different performance?

wifi6-yiyi

QCN6224 QCN9224

精彩回顾|【ACDU 中国行·西安站】数据库主题交流活动成功举办!

墨天轮

数据库 postgresql opengauss oceanbase KaiwuDB

Next Station of Flink CDC

Apache Flink

大数据 flink 实时计算

Mac电脑系统活动监控器推荐:iStat Menus最新中文版

胖墩儿不胖y

Mac软件 活动检测工具

强大模型与高效工具的完美结合

百度开发者中心

深度学习 nlp 大模型

软件测试/测试开发丨持续集成体系介绍 学习笔记

测试人

软件测试 持续集成 CI/CD 测试开发

Skia 编译及踩坑实践

京东科技开发者

Salesforce携手阿里云再来,这次本土CRM有几分胜算?

ToB行业头条

简约Markdown文本编辑器:Typora 破解中文版

mac大玩家j

markdown编辑器 文本编辑器 Mac软件 文本编辑

Mysql tls 会话:再一次抓包之后,我认识到…

华为云开发者联盟

后端 开发 华为云 华为云开发者联盟

人工智能的局限性与期望管理:理解’人工智障’的瞬间

人工智能

Miniconda安装使用教程

百度搜索:蓝易云

Python Linux 运维 云服务器 Miniconda

java浅拷贝BeanUtils.copyProperties引发的RPC异常 | 京东物流技术团队

京东科技开发者

喜报!上海电力联合乘云数字获评 "中国信通院可观测性实践优秀案例"

乘云 DataBuff

铭文质押挖矿系统

区块链技术

从 WasmEdge 运行环境读写 Rust Wasm 应用的时序数据

Greptime 格睿科技

数据库 rust Wasm

Live Wallpaper & Themes 4K Pro for Mac(超高清4K动态壁纸)v19.2中文激活版

影影绰绰一往直前

敏捷:应对软件定义汽车时代的开发模式变革

DevOps和数字孪生

软件定义汽车

深度学习与大模型的革新之路

百度开发者中心

人工智能 深度学习 大模型

Redis开发设计规范及案例分析_文化 & 方法_张家江_InfoQ精选文章