百度360必应搜狗淘宝本站头条
当前位置:网站首页 > IT技术 > 正文

Redis实战经验大总结

wptr33 2024-12-31 15:03 29 浏览

1. key名设计

(1)【建议】: 可读性和可管理性

命令规范:以英文冒号分隔key,前缀概念的范围的返回从大到小,从不变到可变,从变化幅度小到变化幅度大。业务名:key用途:变量

例如:yoga:user:1,表示 yoga:user:{userID},即瑜伽子系统ID=1的用户信息

(2)【建议】:简洁性

保证语义的前提下,控制key的长度,不超64个字符。
当key较多时,内存占用也不容忽视,例如:

user:friends:messages:{mid} 简化为 u:fr:msg:{mid}

(3)【强制】:不要包含特殊字符

反例:包含空格、换行、单双引号以及其他转义字符

Redis 的 Key 一定要规范,这样在遇到问题时,能够进行方便的定位。Redis 属于无 scheme 的 KV 数据库,所以,我们靠约定来建立其 scheme 语义。其好处:

1、能够根据某类 key 进行数据清理

2、能够根据某类 key 进行数据更新

3、能够方面了解到某类 key 的归属方和应用场景

4、为统一化、平台化做准备,减少技术变更

2. value设计

(1)【强制】:拒绝bigkey

字符串类型:它的big体现在单个value值很大,一般认为超过10KB就是bigkey

非字符串类型:哈希、列表、集合、有序集合,它们的big体现在元素个数太多,元素个数不要超过5000

bigkey的危害

1、Redis集群的内存空间不均匀 由于Redis单线程的特性

2、操作bigkey的通常比较耗时,也就意味着阻塞Redis可能性越大

3、bigkey也就意味着每次获取要产生的网络流量较大,容易打满带宽

4、过期删除的时候会阻塞Redis

以下是压测结果,可直观看出bigkey对性能的影响:

(2)【推荐】:选择适合的数据类型

例如:实体类型(要合理控制和使用数据结构内存编码优化配置,例如ziplist,但也要注意节省内存和性能之间的平衡)

反例:

set user:1:name tom
set user:1:age 19
set user:1:favor football

正例:

hmset user:1 name tom age 19 favor football

(3)【强制】:控制key的生命周期,redis不是垃圾桶。

如果应用将Redis定位为缓存Cache使用,对于存放的Key一定要设置超时时间!因为若不设置,这些Key会一直占用内存不释放,造成极大的浪费,而且随着时间的推移会导致内存占用越来越大,直到达到服务器内存上限!另外Key的超时长短要根据业务综合评估,而不是越长越好!(某些业务要求key长期有效。可以在每次写入时,都设置超时时间,让超时时间顺延。)

Redis命令使用规范

1.【强制】严禁不设置范围的批量操作

  • 例如hgetall、lrange、smembers、zrange、sinter等并非不能使用,但是需要明确N的值,有遍历的需求可以使用hscan、sscan、zscan代替。
  • zrange、 zrangebyscore等多个操作 zset 的函数,严禁使用 zrange myzset 0 -1 等这种不设置范围的操作。请指定范围,如 zrange myzset 0 100,如不确定长度,可使用 zcard 判断长度。
  • hgetall会取出相关 hash 的所有数据,如果数据条数过大,同样会引起阻塞,请确保业务可控。如不确定长度,可使用 hlen 先判断长度。
  • 严禁使用 sunion, sinter, sdiff等一些聚合操作。

2.【强制】禁用 select 函数

select函数用来切换 database,对于使用方来说,这是很容易发生问题的地方,cluster 模式也不支持多个 database,且没有任何收益,dba已通过配置禁用。

3.【强制】禁用命令

禁止线上使用keys、flushall、flushdb等,通过redis的rename机制禁掉命令,或者使用scan的方式渐进式处理。dba已通过配置禁用这些命令。

4.【强制】不推荐使用事务

Redis的事务功能较弱(不支持回滚),而且集群版本(自研和官方)要求一次事务操作的key必须在一个slot上。

优化建议

1. 缩短键值对的存储长度

键值对的长度是和性能成反比的,比如我们来做一组写入数据的性能测试,执行结果如下:

不同key大小性能测试
从以上数据可以看出,在 key 不变的情况下,value 值越大操作效率越慢,因为 Redis 对于同一种数据类型会使用不同的内部编码进行存储,比如字符串的内部编码就有三种:int(整数编码)、raw(优化内存分配的字符串编码)、embstr(动态字符串编码),这是因为 Redis 的作者是想通过不同编码实现效率和空间的平衡,然而数据量越大使用的内部编码就越复杂,而越是复杂的内部编码存储的性能就越低。

2. 冷热数据分离

不要将所有数据全部都放到Redis中,建议根据业务只将高频热数据存储到Redis中【QPS大于5000】,重要性级别较低的但却需求容量较大的场景可申请完全兼容Redis操作的Pika,对于低频冷数据可以使用MySQL/ElasticSearch等基于磁盘的存储方式。

3. 业务数据分离

不要将不相关的数据业务都放到一个 Redis中。一方面避免业务相互影响,另一方面避免单实例膨胀,并能在故障时降低影响面,快速恢复。

4. 大文本数据要压缩

对于大文本【超过500 byte】写入到Redis时,一定要压缩后存储!大文本数据存入Redis,除了带来极大的内存占用外,在访问量高时,很容易就会将网卡流量占满,进而造成整个服务器上的所有服务不可用,并引发雪崩效应,造成各个系统瘫痪。

5. 使用连接池

使用带有连接池的客户端,可以有效控制连接,同时提高效率

6. 缓存 Key 设置失效时间的建议

如果在大型系统中有大量缓存在同一时间同时过期,那么会导致 Redis 循环多次持续扫描删除过期字典,直到过期字典中过期键值被删除的比较稀疏为止,而在整个执行过程会导致 Redis 的读写出现明显的卡顿,卡顿的另一种原因是内存管理器需要频繁回收内存页,因此也会消耗一定的 CPU。

为了避免这种卡顿现象的产生,我们需要预防大量的缓存在同一时刻一起过期,就简单的解决方案就是在过期时间的基础上添加一个指定范围的随机数。

7. 限制Redis 分片大小

乐信标准,Redis都有分片,最少一个分片,单分片的大小是4G ,为何不建议一直往上加内存?

  • 单台服务器内存资源有限,不利于扩展
  • 单个分片内存过大,服务器出故障时,影响面大
  • Redis持久化时,虽然操作是异步化,但会有fork进程的操作,这一步是由主进程来完成的,分片内存越大,页表就越大,fork执行时间就越长,就会给主线程带来阻塞风险
  • 不利于平台标准化,后期迁移困难
  • Redis是单进程模型,只能利用一个CPU核心,多分片有利于提高Redis集群能力,充分利用多核性能。

8. 认真对待最大内存淘汰策略

根据自身业务类型选择好最大内存淘汰策略,可保证有用数据不被删除,也可避免Redis实例出现OOM,让Redis持续高效。

  • noeviction:不淘汰任何数据,当内存不足时,新增操作会报错,Redis 默认内存淘汰策略
  • allkeys-lru:淘汰整个键值中最久未使用的键值
  • allkeys-random:随机淘汰任意键值
  • volatile-lru:淘汰所有设置了过期时间的键值中最久未使用的键值(乐信默认)
  • volatile-random:随机淘汰设置了过期时间的任意键值
  • volatile-ttl:优先淘汰更早过期的键值

在 Redis 4.0 版本中又新增了 2 种淘汰策略:

  • volatile-lfu:淘汰所有设置了过期时间的键值中,最少使用的键值
  • allkeys-lfu:淘汰整个键值中最少使用的键值

相关推荐

开发者必看的八大Material Design开源项目

MaterialDesign是介于拟物和扁平之间的一种设计风格,自从它发布以来,便引起了很多开发者的关注,在这里小编介绍在Android开发者当中里最受青睐的八个MaterialDesign开源项...

另类插这么可爱,一定是…(另类t恤)

IT之家(www.ithome.com):另类插图:这么可爱,一定是…OSXMavericks和Yosemite打破了苹果对Mac操作系统传统的命名方式,使用加州的某些标志性景点来替换猫...

Android常用ADB命令(安卓adb工具是什么)

杀死应用①根据包名获取APP的PIDadbshellps|grep应用包名②执行kill命令...

微软Mac版PowerPoint测试Reading Order Pane功能

IT之家5月20日消息,微软公司昨日(5月19日)发布博文,邀请Microsoft365Insiders成员,测试macOS新版PowerPoint演示文稿应用,重点引入...

Visual Studio跨平台开发实战(4):Xamarin Android控制项介绍

前言不同于iOS,Xamarin在VisualStudio中针对Android,可以直接设计使用者界面.在本篇教学文章中,笔者会针对Android的专案目录结构以及基本控制项进行介绍,包...

用云存储30分钟快速搭建APP,你信吗?

背景不管你承认与否,移动互联的时代已经到来,这是一个移动互联的时代,手机已经是当今世界上引领潮流的趋势,大型的全球化企业和中小企业都把APP程序开发纳入到他们的企业发展策略当中。但随着手机APP上传的...

谷歌P图神器来了!不用学不用教,输入一句话,分分钟给结果

Pine发自凹非寺量子位|公众号QbitAI当你拍照片时,“模特不好好配合”怎么办?...

iOS文本编辑控件UITextField和UITextVie

记录一个菜鸟的IOS学习之旅,如能帮助正在学习的你,亦枫不胜荣幸;如路过的大神如指教几句,亦枫感激涕淋!细心的朋友可能已经注意到了,IOS学习之旅系列教程在本篇公众号的文章中,封面已经换成美女图片了,...

Android入门图文教程集锦(android 入门教程)

Android入门视频教程集锦AndroidStudio错误gradientandroid:endXattributenotfound...

如何使用Android自定义复合视图(如何使用android自定义复合视图)

在最近的一个客户应用中,我遇到了一个需求,根据选定的值来生成指定数量的编辑框字段,这样用户可以输入人物信息。最初我的想法是把这些逻辑放到Fragment中,只是根据选中值的变化来向线性布局容器中增加编...

原生安卓开发app的框架frida常用关键代码定位

前言有时候可能会对APP进行字符串加密等操作,这样的话你的变量名等一些都被混淆了,看代码就可能无从下手...

教程10 | 三分钟搞定一个智能输入法程序

一案例描述1、考核知识点网格布局线性布局样式和主题Toast2、练习目标掌握网格布局的使用掌握Toast的使用掌握线性布局的使用...

(Android 8.1) 功能与新特性(android的功能)

和你一起终身学习,这里是程序员AndroidAndroid8.1(API级别27)为用户和开发人员引入了各种新特性和功能。本文档重点介绍了开发人员的新功能。通过本章阅读,您将获取到以下内容:Andr...

怎样设置EditText内部文字被锁定不可删除和修改

在做项目的时候,我曾经遇到过这样的要求,就是跟百度贴吧客户端上的一样,在回复帖子的时候,在EditText中显示回复人的名字,而且这个名字不可以修改和删除,说白了就是不可操作,只能在后面输入内容。在E...

如何阻止 Android 活动启动时 EditText 获得焦点

技术背景在Android开发中,当活动启动时,EditText有时会自动获得焦点并弹出虚拟键盘,这可能不是用户期望的行为。为了提升用户体验,我们需要阻止...