Redis学习总结(持续更新)

ACP

Redis是 AP ,Redis的一致性模型是最终一致性

Redis是AP的还是CP的_redis 是 ap 模型-CSDN博客文章浏览阅读170次,点赞5次,收藏4次。然而,WAIT 仅能确保数据在 Redis 实例中有指定数量的副本中被确认,它并不能将一组 Redis 实例转变为具有强一致性的 CP 系统:在故障转移期间,已确认的写操作仍然可能会丢失,这取决于 Redis 持久化的具体配置。然而,使用 WAIT 后,在发生故障事件时丢失写操作的概率大大降低,只在某些难以触发的故障模式下才会发生。当一个节点宕机时,这个节点上的数据可能无法同步到其他节点,这就可能导致数据在节点之间的不一致。,即在某个时间点读取的数据可能并不是最新的,但最终会达到一致的状态。_redis 是 ap 模型https://blog.csdn.net/weixin_41510616/article/details/149165403?spm=1001.2014.3001.5501


数据类型

  • 字符串(String)
  • 哈希(Hash)
  • 列表(List)
  • 集合(Set)
  • 有序集合(Sorted Set)

高级数据类型:Streams、Bitmap、Geospatial以及HyperLogLog

Redis 支持哪几种数据类型?-CSDN博客文章浏览阅读85次。另外,Redis中还支持一些高级的数据类型,如:Streams、Bitmap、Geospatial以及HyperLogLog。https://blog.csdn.net/weixin_41510616/article/details/149164994?spm=1001.2014.3001.5501


String

Redis 自己定义了 SDS(Simple Dynamic Strings,简单动态字符串), 为了存储任意字符串(无需'\0'结尾),增加 alloc 表示分配的总长度**,len** 表示当前字符串长度**,提高各个操作的效率。**

Redis为什么要自己定义SDS?-CSDN博客文章浏览阅读227次。Redis采用自定义的SDS(简单动态字符串)替代C语言原生字符串,解决了C字符串无法存储任意字符和操作效率低下的问题。SDS通过alloc和len字段记录总长度和当前长度,避免了遍历操作,使字符串操作更高效。这种设计既支持任意字符存储,又提升了Redis处理字符串的性能。https://blog.csdn.net/weixin_41510616/article/details/149420002?spm=1001.2014.3001.5501


Sorted Set

  • 早期采用 ziplist(压缩列表)skiplist(跳跃表) 两种结构,Redis 5.0 引入 listpack(紧凑列表)取代 ziplist
  • 元素少时使用 ziplistlistpack节约内存。默认 128 个元素,每个元素小于 64 字节
  • skiplist其实就是多个索引层级的有序链表

ziplist

级联更新问题

ziplist 中的 Entry(实际存储数据项) 由三部分组成 prevlen (记录前一个entry的长度)、 encoding(内容编码)、content(实际数据)

prevlen:前一个entry长度 <254时占用1字节, ≥254:占用5字节(首字节固定为0xFE)

假设当前 ZipList 中包含3个 Entry,每个 Entry 的总长度均为253字节。此时在 Entry1 后插入一个长度为300字节的新 Entry,将触发连锁反应后面所有的 prevlen 都需要更新,导致显著的性能损耗。


listpack

如何解决级联更新问题

废弃原有 prevlen 字段,引入 backle n字段记录整个 Entry 的字节数


集群模式

  • 主从模式
  • 哨兵模式
  • Cluster模式(集群模式)

Redis的集群模式有哪些-CSDN博客文章浏览阅读593次,点赞12次,收藏17次。Redis有三种主要的集群模式,用于在分布式环境中实现高可用性和数据复制。这些集群模式分别是:主从复制(Master-Slave Replication)、哨兵模式(Sentinel)和Redis Cluster模式。https://blog.csdn.net/weixin_41510616/article/details/149180463?spm=1001.2014.3001.5501


Cluster

数据分片

在Redis的Cluster 集群模式中,使用哈希槽 (hash slot)的方式来进行数据分片,将整个数据集划分为16384 个槽,每个节点负责多个槽,通过 CRC16 算法得出数据在哪个槽

为什么是16384

2的幂次方,可以使用位运算计算。官方在实践中得出比较合适的值

什么是Redis的数据分片?-CSDN博客文章浏览阅读540次,点赞9次,收藏10次。Redis数据分片通过哈希槽机制将数据分散在多个节点上,采用16384个固定槽位设计。这种设计综合考虑了消息大小(2K)、集群规模(≤1000节点)和负载均衡等因素,采用CRC16算法快速计算key所属槽位。核心优势在于提升性能、支持弹性扩展和保障高可用性,通过自动故障转移和数据迁移实现高效集群管理。_数据分片https://blog.csdn.net/weixin_41510616/article/details/149345692?spm=1001.2014.3001.5501


持久化机制

  • RDB 是定时备份,体积小,恢复速度快。
  • AOF 是实时备份,可靠性高。
  • 通常使用 RDB-AOF 混合持久化。先将数据以 RDB 格式写入 AOF 文件开头

Redis的持久化机制是怎样的?-CSDN博客文章浏览阅读292次,点赞4次,收藏5次。Redis提供RDB和AOF两种持久化机制。RDB通过快照实现,文件小恢复快但可能丢失数据;AOF记录所有写操作,可靠性高但占用空间大且负载高。Redis 4.0支持RDB-AOF混合模式,兼具启动速度快和数据丢失风险低的优势。业务可根据需求选择单独或混合使用这两种机制。https://blog.csdn.net/weixin_41510616/article/details/149205457?spm=1001.2014.3001.5501


写回策略

  • RDB分自动触发(可配置)和手动触发
  • AOFAlways(同步写回)、 Everysec(每秒写回) 、No(操作系统控制), 一般用Everysec

RDB和AOF的写回策略分别是什么?_librbd的写回调是什么时候触发-CSDN博客文章浏览阅读261次,点赞10次,收藏4次。Redis提供RDB和AOF两种持久化机制。RDB支持自动触发(通过save参数设置时间/键数阈值)和手动触发(SAVE/BGSAVE命令)。AOF提供三种写回策略:Always(同步写回)、Everysec(每秒异步刷盘)和No(由OS控制),其中Everysec在性能与可靠性间取得平衡,最常用。RDB适合定期备份,AOF提供更细粒度的持久化控制。_librbd的写回调是什么时候触发https://blog.csdn.net/weixin_41510616/article/details/149568993?spm=1001.2014.3001.5502


过期策略

定期删除惰性删除相结合的方式

Redis 的过期策略_redis的定期过期-CSDN博客文章浏览阅读137次,点赞3次,收藏3次。定期删除其实并不会立即释放内存,而是把这些键标记为"已过期",并放入一个专门的链表中。然后,在Redis的内存使用率达到一定阈值时,Redis会对这些"已过期"的键进行一次内存回收操作,释放被这些键占用的内存空间。一般来说,这些被删除的内存空间会被操作系统标记为"可重用的内存",等待被重新分配。因此,即使Redis进行了内存回收操作,也并不能保证Redis所占用的内存空间会立即释放给操作系统。需要注意的是,即使Redis进行了内存回收操作,也不能完全保证被删除的内存空间会立即被系统回收。_redis的定期过期https://blog.csdn.net/weixin_41510616/article/details/149242084?spm=1001.2014.3001.5501


内存淘汰策略

  • 用于内存满了之后,决定哪些key淘汰
  • 默认是 noeviction不淘汰,直接报错
  • 腾讯建议做为缓存使用时,用 allkeys-lru (从所有 key 中选择最近最少使用的那个 key 并删除),做为半持久化半缓存时,使用 volatile-lru (从设置了过期时间的 key 中选择最近最少使用的那个 key 并删除)
  • 阿里云默认 volatile-lru , 腾讯云默认 noeviction

缓存失效算法

  • FIFO先进先出
  • LRU最近最少使用
  • LFU最少频次使用,记录每个key的使用次数,很占内存
  • W-TinyLFU Caffeine中的算法,结合 LRULFU ,由窗口缓存过滤器主缓存组成
  • 窗口缓存采用 LRU 为新元素提供积累访问频率的机会
  • 在过滤其中与主缓存淘汰出来的 Key 进行比较

Redis的内存淘汰策略是怎么样的?_redis的淘汰策略有哪些-CSDN博客文章浏览阅读251次,点赞3次,收藏10次。Redis 的内存淘汰策略用于在内存满了之后,决定哪些 key 要被删除。Redis 支持多种内存淘汰策略,可以通过配置文件中的 maxmemory-policy 参数来指定。_redis的淘汰策略有哪些https://blog.csdn.net/weixin_41510616/article/details/149242165?spm=1001.2014.3001.5501


快的原因

  • 基于内存
  • 单线程模型
  • 高效的数据结构
  • IO多路复用技术
  • 6.0引入多线程处理网络请求

引入多线程的原因

单线程支持QPS 8万-10万,瓶颈在网络IO的处理上

Redis为什么这么快-CSDN博客文章浏览阅读106次。在Redis 中,每当一个套接字准备好执行连接应答、写入、读取、关闭等操作时,就会产生一个文件事件。其实,Redis的IO多路复用程序的所有功能都是通过包装操作系统的IO多路复用函数库来实现的。每个IO多路复用函数库在Redis源码中都有对应的一个单独的文件。IO多路复用在Linux下包括了三种,select、poll、epoll,抽象来看,他们功能是类似的,但具体细节各有不同。一旦有请求到达,就会交给 Redis 线程处理,这就实现了一个 Redis 线程处理多个 IO 流的效果。https://blog.csdn.net/weixin_41510616/article/details/149189832?spm=1001.2014.3001.5501


Lua 脚本

原子性

Redis 会将 Lua 脚本封装成一个单独的事务在Redis客户端运行,如果在这个进程中有其他客户端请求的时候,Redis 将会把它暂存起来,等到 Lua 脚本处理完毕后,才会再把被暂存的请求恢复。

Lua脚本保证的原子性是什么?-CSDN博客文章浏览阅读415次,点赞5次,收藏7次。Redis中Lua脚本的原子性具有双重特性:在并发层面保证执行的不可分割性(原子性),但在数据库层面不满足ACID原子性(不保证操作全部成功或回滚)。Lua是一种高效、跨平台的轻量级脚本语言,适合嵌入应用程序扩展功能。虽然Lua脚本能在单机Redis中实现原子操作,但在集群环境下存在使用限制(未展开说明)。https://blog.csdn.net/weixin_41510616/article/details/149386145?ops_request_misc=%257B%2522request%255Fid%2522%253A%25221703403f355dc5c02edd64534478d9f2%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=1703403f355dc5c02edd64534478d9f2&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-2-149386145-null-null.nonecase&utm_term=lua&spm=1018.2226.3001.4450


事务机制

Redis的事务是不支持回滚的

Redis 的事务机制是怎样的?-CSDN博客文章浏览阅读959次,点赞10次,收藏15次。Redis事务机制提供原子性执行,但不支持回滚操作。从2.6.5版本开始,Redis会在命令累积阶段检测错误,执行EXEC时发现错误会拒绝执行事务。事务执行中发生错误会继续执行剩余命令而非回滚。Lua脚本在并发层面具有原子性,但不满足ACID原子性,在集群环境存在限制。常用事务命令包括MULTI、EXEC、WATCH等。在电商场景中,可通过Jedis使用事务实现下单扣减库存等操作,通过判断exec()返回值确认事务是否成功执行。https://blog.csdn.net/weixin_41510616/article/details/149573417?spm=1001.2014.3001.5501

和 Lua 比较

  • 都保证原子性、都不能回滚
  • 事务发生错误不影响后续的命令执行,Lua影响
  • 事务多次网络交互,Lua 只有一次
  • 事务不能获取其他命令的中间结果,Lua 可以

通信协议

RESP 协议( 自己设计的,基于 TCP 协议**)**

Redis 使用什么协议进行通信?-CSDN博客文章浏览阅读202次。Redis采用自行设计的RESP协议进行通信,该协议基于TCP且简单高效。RESP使用\r\n分隔数据,格式包含参数个数、长度和内容,支持多种数据类型。示例展示了SET命令的请求(*3\r\n$3\r\nSET...)和响应(+OK\r\n),协议还支持事务、脚本等高级功能。RESP因其易解析性在业界被广泛应用。https://blog.csdn.net/weixin_41510616/article/details/149356631?spm=1001.2014.3001.5501


Pipeline

一种优化网络延迟的技术,客户端可以将多个命令一次性发送至 Redis 服务器,无需等待每个命令的响应

Redis的Pipeline-CSDN博客文章浏览阅读732次,点赞13次,收藏20次。Redis Pipeline机制通过批量发送命令优化网络性能,减少往返通信次数。相比传统单命令模式,Pipeline允许客户端一次性发送多个指令,服务器顺序执行后返回结果。该机制与事务不同,不保证原子性。通过Java Jedis客户端示例展示了Pipeline的典型用法:批量执行set、append、incr等操作后统一获取响应,显著提升批量处理效率,特别适合高延迟网络环境下的Redis操作优化。https://blog.csdn.net/weixin_41510616/article/details/149610462?spm=1001.2014.3001.5502


与 Memcached 区别

  • Memcached 只支持简单的键值对存储,不支持持久化,只能手动分片
  • Memcached 使用多线程处理数据,只支持基本的 GET、SET 操作
  • Memcached 使用文本协议,只支持一个默认数据库

Redis 适用于数据结构复杂、需要高级功能和数据持久化的场景;而 Memcached 则适用于简单的键值存储场景

Redis 和 Memcached 的区别-CSDN博客文章浏览阅读102次。Redis与Memcached对比摘要:Redis支持多种数据结构、持久化和事务处理,适合复杂应用场景;Memcached仅支持键值对,无持久化,但多线程架构使其在简单缓存场景中性能优异。选择时需根据数据结构复杂度、持久化需求等决定。https://blog.csdn.net/weixin_41510616/article/details/149359304?spm=1001.2014.3001.5501


常见问题

热key

同一时间点同一个key被大量访问,就会导致流量过于集中,使得很多物理资源无法支撑。

如何解决

热key拆分、多级缓存、限流

热key标准

QPS集中、带宽集中、CPU集中

结合业务而定,京东有hotkey框架可以根据业务随时调整热key的访问频率

识别热key

经验预判、实时监测(埋点、代理层统一收集、redis自带命令)

Redis的热Key问题_什么是热key问题,如何解决热key问题-CSDN博客文章浏览阅读671次,点赞18次,收藏6次。当我们使用Redis作为存储时,如果发生一些特殊情况,比如明星官宣的突发事件,世界杯等重大活动,双十一的活动秒杀等等,就会出现特别大的流量,并且会导致某些热词、商品等被频繁的查询和访问。这也是为什么某某明星官宣之后,微博上面就会出现宕机的情况。有时候这种宕机发生后,其他功能都是可以使用的,只是和这个热点有关的内容会无法访问,这其实就和热点数据有关系了。对于事前预测就是根据一些根据经验,提前的识别出可能成为热key的Key,比如大促秒杀活动等。_什么是热key问题,如何解决热key问题https://blog.csdn.net/weixin_41510616/article/details/149242646?spm=1001.2014.3001.5501


大Key

这个Key对应的value占用空间很大或者元素很多

危害

影响性能、占用内存、集群中内存分布不均、备份迁移恢复困难等

如何解决

大 Key 拆分、删除大 Key、设置合理的过期时间防止膨胀

识别大key

自带命令 redis-cli --bigkeys

什么是大Key问题,如何解决?_缓存大key的问题-CSDN博客文章浏览阅读736次,点赞15次,收藏20次。Big Key是Redis中存储了大量数据的Key,不要误以为big key只是表示Key的值很大,他还包括这个Key对应的value占用空间很多的情况,通常在String、list、hash、set、zset等类型中出现的问题比较多。一般来说,如果一个key的value比较大,占用的内存比较多,或者某个key包含的元素数量比较多,这些都可以被认为是大key。1、影响性能:由于big key的values占用的内存会很大,所以读取它们的速度会很慢,会影响系统的性能。_缓存大key的问题https://blog.csdn.net/weixin_41510616/article/details/149293417?spm=1001.2014.3001.5501


缓存击穿

某一key的缓存过期时大并发量的请求同时访问此key,瞬间击穿缓存服务器直接访问数据库,让数据库处于负载的情况。

如何解决

异步定时更新、互斥锁(如果缓存没有先上锁,从数据库获取数据上缓存后再释放)


缓存穿透

缓存服务器中没有缓存数据,数据库中也没有符合条件的数据,导致业务系统每次都绕过缓存服务器查询下游的数据库,缓存服务器完全失去了其应有的作用。

如何解决

缓存空值、布隆过滤器

缓存雪崩

大量缓存同时过期或缓存服务宕机,所有请求的都直接访问数据库,造成数据库高负载,影响性能,甚至数据库宕机。

如何解决

设置不同的过期时间(加随机数)、集群部署

什么是缓存击穿、缓存穿透、缓存雪崩?-CSDN博客文章浏览阅读739次,点赞22次,收藏7次。缓存击穿:是指当某一key的缓存过期时大并发量的请求同时访问此key,瞬间击穿缓存服务器直接访问数据库,让数据库处于负载的情况。缓存穿透:是指缓存服务器中没有缓存数据,数据库中也没有符合条件的数据,导致业务系统每次都绕过缓存服务器查询下游的数据库,缓存服务器完全失去了其应有的作用。缓存雪崩:是指当大量缓存同时过期或缓存服务宕机,所有请求的都直接访问数据库,造成数据库高负载,影响性能,甚至数据库宕机。https://blog.csdn.net/weixin_41510616/article/details/149334457?spm=1001.2014.3001.5501


集群模式中使用事务和 Lua 的限制

执行 Lua 脚本时,脚本中访问的所有键也必须位于同一节点

如何解决

默认情况下,Redis 使用键的哈希值 来决定将数据存储在哪个节点。我们可以通过 HashTag来干预哈希值的生成

Redis Cluster 中使用事务和 lua 有什么限制?_redis lua脚本使用限制-CSDN博客文章浏览阅读211次。RedisCluster采用主从架构实现高可用,数据分片存储在不同节点。与MySQL类似,RedisCluster的事务和Lua脚本存在跨节点限制:所有操作键必须位于同一节点,否则会失败。跨节点执行Lua脚本会报"commandkeysmustinsameslot"错误。官方文档(https://redis.io/docs/latest/operate/oss_and_stack/reference/cluster-spec/)详细说明了这一限制。解决方案待探讨。_redis lua脚本使用限制https://blog.csdn.net/weixin_41510616/article/details/149413423?spm=1001.2014.3001.5501


相关推荐
会编程的林俊杰2 分钟前
Redisson中的分布式锁
redis·分布式·redisson
野犬寒鸦19 分钟前
Pipeline功能实现Redis批处理(项目批量查询点赞情况的应用)
java·服务器·数据库·redis·后端·缓存
꧁༺摩༒西༻꧂25 分钟前
Spring Boot Actuator 监控功能的简介及禁用
java·数据库·spring boot
程序员JerrySUN33 分钟前
当前主流GPU全景讲解:架构、功能与应用方向
数据库·人工智能·驱动开发·redis·缓存·架构
__Smile°33 分钟前
kubeadm-k8s 中的 etcd 备份与恢复
数据库·docker·云原生·容器·kubernetes·etcd
小醉你真好1 小时前
12、Docker Compose 安装 Redis
redis·docker·容器
Runing_WoNiu1 小时前
最佳左前缀法则(Optimal Left-Prefix Rule)
数据库·mysql
IvorySQL2 小时前
如何使用 pg_rman 进行 PostgreSQL 的备份与恢复
数据库
Tapdata2 小时前
一文了解增量物化视图维护(IVM):原理、演化与实践落地
数据库
码间舞2 小时前
IndexDB适用于什么场景?如何使用IndexDB?
前端·javascript·数据库