中间件专题:Redis

news/2025/9/22 13:39:13/文章来源:https://www.cnblogs.com/fei1010/p/19105070

1. Redis 数据结构

# String
set `key` `value`
setnx `key` `value` # 不存在才set
setex `key` `value` `ttl`
incrby `key` `increment` # 自增# Hash 哈希表
hset `key` `field` `value` `field` `value`
hget `key` `field`
hsetnx `key` `value` # 不存在才set# List  双向链表
LPUSH `key` `element1` `element2` ... # 从左侧插入一个或多个元素
LPOP `key` # 移除左侧第一个元素,没有返回null
RPUSH `key` `element1` `element2` ...
RPOP `key`
LRANGE `key` `start` `end` # 返回start到end之间的元素# Set 无序集合
SADD `key` `member1` `member2` # 添加
SREM `key` `member1` `member2` # 删除
SCARD `key` # 返回set中元素的个数
SISMEMBER `key` `membern` # 判断是否是key成员
SmemberS `key` # 查询key的所有成员
SINNER `key1` `key2` # 获取交集
SDIFF `key1` `key2` # 求差集, key1有,key2没有
SUNION `key1` `key2` # 求并集# Zset/SortedSet  ### 跳表 + Hash表, 有序集合,查询效率高
ZADD `key` `score1` `member1` `score2` `member2` ...  # 添加一个或多个元素到sorted set,如果存在更新score
ZREM `key` `member` # 删除
ZSCORE `key` `member` # 获取元素的score
ZRANK `key` `member` # 获取元素排名
ZCARD  `key` # 获取元素个数
ZCOUNT `key` `min` `max` # 求指定范围score的元素个数
ZINCRBY `key` `increment` `member` # 对指定member自增
ZRANGE `key` `min` `max` # 获取指定排名范围的元素
ZRANGEBYSCORE `key` `min` `max` # 获取指定score范围内的元素

2. Redis 线程模型

3. 缓存解决方案

3.1 缓存击穿、缓存雪崩、缓存穿透

缓存击穿 缓存雪崩 缓存穿透
定义 单个热点 key 过期时,大量并发请求瞬间击穿缓存直达数据库 大量缓存 key 同时失效或缓存服务宕机,导致请求洪涌压垮数据库 请求不存在的数据,缓存与数据库均未命中,反复穿透缓存
核心解决方案 互斥锁 1. 随机过期时间:基础 TTL + 随机偏移量
2. 多级缓存:本地缓存(Caffeine)+ 分布式缓存(Redis)
3. 熔断限流:Hystrix/Sentinel 保护数据库
1. 布隆过滤器:拦截非法请求(误判率可控)
2. 缓存空值NULL 结果短时缓存(如 5 分钟)
3. 参数校验:过滤非法 ID(如 ID≤0)

3.2 Redis 内存淘汰策略

  1. noeviction: 默认不淘汰,新增数据时直接报错
  2. volatile-TTL: 如果设置了过期时间,淘汰即将过期的数据
  3. volatile-random: 从设置了过期时间中的数据随机淘汰
  4. allkeys-random: 从所有数据中随机淘汰
  5. allkeys-lru: 在所有数据中,按照最近最少使用的数据进行淘汰
  6. volatile-lru: 在设置了过期时间中的数据,按照最近最少使用的数据进行淘汰。

3.3 全局唯一ID

全局唯一Id生成策略:

  • UUID
  • Redis自增 INCR key
  • 雪花算法
  • 数据库自增

redis自增策略:

  • 每天一个key,方便统计订单量
  • id构造是:时间戳+计数器

4. 分布式缓存

Redis 主要通过三种模式实现分布式缓存,每种模式适用于不同的场景和需求。

特性 主从复制 (Replication) 哨兵模式 (Sentinel) 集群模式 (Cluster)
核心目标 数据备份、读写分离 高可用、自动故障转移 水平扩展、高可用、数据分片
数据分布 全量复制,所有节点数据相同 全量复制,所有节点数据相同 数据分片到16384个槽,每个节点负责部分槽
高可用性 手动故障转移 自动故障转移 自动故障转移
扩展性 读扩展(添加从节点) 读扩展(添加从节点) 读写扩展(添加主节点)
适用场景 数据备份、读多写少 对可用性有要求的业务 大数据量、高并发、需水平扩展

4.1 主从模式

4.1.1 主从结构

image-20250921173351153

4.1.2 数据同步原理

(1)全量同步

  1. slave执行replicaof命令,建立连接
    1. slave请求数据同步
    2. master判断是否时第一次请求同步,是第一次请求则slave获取master数据版本信息
    3. slave保持版本信息
  2. master异步执行bgsave,生成RDB
    1. master发送RDB文件给slave
    2. slave清空本地数据,加载RDB文件
  3. master记录生成RDB后的所有命令到repl_baklog
    1. 发送repl_baklog中的命令到slave
    2. 循环同步

master如何判断slave是否是第一次来同步数据的?

slave做数据同步,必须向master声明自己的replication idoffset, master才可以判断到底需要同步哪些数据。判断是否是第一次来,只需要判断master和slave的replid是否一致即可。

Replication Id: 是数据集的标识,id一致说明是同一个数据集。每一个master都有唯一的replid, slave 则会继承master的replid。

offset: 偏移量,随着记录在repl_baklog中的数据增多而逐渐增大。slave完全同步时也会记录当前同步的offset。如果slave的offset小于master的offset。说明slave数据落后于master,需要更新。

(4)增量同步

  1. slave 重启
    1. slave请求数据同步
    2. 判断replid一致,回复slave:continue
  2. 去repl_baklog中获取slave offset后的数据
    1. 发送offset后的命令

repl_baklog大小有上限,写满后会覆盖最早的数据。如果slave断开时间过久,导致尚未备份的数据被覆盖,则无法基于log做增量同步,只能再次全量同步。

image-20250921185654356

(3)主从同步优化

  • 在master中配置repl-diskless-sync yes启用无磁盘复制,避免全量同步时写入RDB文件的磁盘IO,直接将RDB IO流直接发送给slave。
  • Redis单节点上的内存占用要太大,减少RDB导致的过多磁盘IO。
  • 适当提高repl_baklog的大小,发现slave宕机时尽快实现故障恢复,尽可能避免全量同步
  • 限制一个master上的slave节点数量,如果实在是太多slave,则可以采用主从-从链式结构,减少master压力

image-20250921191806600

(4)总结

简述全量同步和增量同步的区别?

  • 全量同步:master将完整的内存数据生成RDB,发送RDB文件到slave。在生成RDB文件之后的命令操作,则记录在repl_baklog, 逐个发送给slave;
  • 增量同步:slave提交自己的offset到master,master获取repl_baklog中offset偏移量之后的命令给slave

什么时候执行全量同步?

  • slave初次同步
  • slave的偏移量offset超过了repl_baklog的大小

什么时候执行增量同步?

  • slave从故障中恢复并且offset在repl_baklog中能找到时

4.1.2. 哨兵模式

主从模式中slave宕机后恢复可以从master中同步数据,如果是master宕机呢?

哨兵的作用和原理

Redis 提供了哨兵(Sentinel)机制来实现主从集群的自动故障恢复。哨兵的结构和作用如下:

  • 监控:Sentinel会不断检查您的master和slave是否按预期工作
  • 自动故障恢复:如果master故障,Sentinel会将一个slave提升为master。当故障实例恢复后也会以新的master为主,实现主从切换。
  • 通知: Sentinel充当Redis客户端的服务发现来源。当Redis集群发送故障转移时,会将最新的信息推送到Redis客户端。

image-20250921193313845

(1)服务状态监控

Sentinel基于心跳机制检测服务状态,每隔一秒向集群的每个实例发送一个ping命令:

  • 主观下线:如果某个sentinel节点发现某个实例未在规定的时间响应,则认为该实例主观下线。
  • 客观下线:若超过指定数量(quorum)的sentinel都认为该实例下线,则该实例客观下线。 quorum最好超过实例数量的一半。

(2)选举master

一旦发现master故障,sentinel需要在slave中选择一个作为新的master。

  • 断开时间:首先判断slave节点与master节点断开时间的长短,如果超过指定值(down-after-milliseconds * 10)则会排除该slave节点
  • 优先级:然后判断slave节点的slave-priority值,越小的优先级越高,如果是0则永不参与选举。
  • 偏移值offset:如果slave-priority一样,则判断slave节点的offset值,越大说明数据越新,优先级越高。
  • 运行id:最后判断slave节点的运行id大小,越小优先级越高(运行id是redis自动生成的id,也就是说这里随机挑选一个slave作为master)

(3)故障转移

当选中了一个slave作为新的master节点之后,需要进行故障转移。

  • sentinel给备选的slave发送slaveof no one命令,让该节点成为master
  • sentinel给所有其他slave发送slaveof 192.168.2.2 7002命令,让其他slave成为新master的从节点,开始从新的master上同步数据。
  • 最后,sentinel将故障节点标记未slave,当故障节点恢复后会自动成为新master节点的slave节点。

(4)总结

  • sentinel的三个作用是什么?

    • 状态监控
    • 故障修复
    • 故障恢复通知
  • Sentinel如何判断一个redis实例是否健康?

    • 心跳机制:基于心跳机制,每隔一秒向每个实例发送一个ping命令
    • 主观判断:如果某个实例没有在规定时间内响应,则认为该节点主观下线。
    • 客观判断:如果超过指定数量的sentinel都认为该节点主观下线,则该实例客观下线。
  • 故障转移步骤有哪些?

    • master选举
    • sentinel给备选slave发送slaveof no one命令,让该节点成为master
    • sentinel给其他slave节点发送该节点的ip + 端口信息,让其他slave节点成为新master节点的从节点。
    • sentinel把故障master标记为slave,恢复后会成为新master的slave节点。

搭建哨兵集群

RedisTemplate的哨兵模式

在Sentinel集群监管下的Redis主从集群,其节点会因为自动故障转移而发生变化,Redis的客户端必须感知这种变化,及时更新信息。Spring的RedisTemplate底层利用了lettuce实现了节点的感知和自动切换。

  1. 在pom文件中引入redis的starter依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
  1. 在配置文件中配置sentinel信息
spring:redis:sentinel:master: mymaster # 指定master名称nodes: # 指定redis-sentinel集群信息- 192.168.56.2:27001- 192.168.56.3:27001- 192.168.56.4:27001
  1. 配置主从读写分离
@Bean
public LettuceClientConfigurationBuilderCustomer configurationBuilderCustomer(){return configBuilder -> configBuilder.readFrom(ReadFrom.REPLICA_PREFERRED);
}

这里ReadFrom是配置Redis的读写策略。

  • MASTER:从节点读取
  • MASTER_PREFERRED: 优先从master节点读取
  • REPLICA: 仅从slave节点读取
  • REPLICA_PREFERRED: 优先从slave节点读取

4.1.3. 分片集群模式

3.1 搭建分片集群

3.2 散列插槽

3.3 集群伸缩

3.4 故障转移

3.5 RedisTemplate访问分片集群

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/909358.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Vue3 新趋势:弃用 ECharts!最强图表库诞生!

Vue3 新趋势:弃用 ECharts!最强图表库诞生!原文链接:https://mp.weixin.qq.com/s/hE7XmPjSOGpD6EYQCKSpkw在前端开发领域,数据可视化已然成为不可或缺的一环。 目前市面上主流的图表库诸如 ECharts、AntV 等,虽然…

群晖安装套件跳过版本检查

群晖安装套件跳过版本检查若遇到最新版群晖系统提示“10854与您的Synology NAS不兼容,请上传9.2.1-11320或以上版本”导致无法安装,请执行以下代码,通过SSH或者计划任务执行均可: cp /etc.defaults/synopackagesli…

负载排查和分析四

负载排查和分析四明白,我给你提供完整整合后的最终文档版本,把软/硬中断触发机制、背景、流程、表格全部补充进去,保持原有网络优化、Perf 分析、脚本和流程图不变。Linux 网络优化与性能分析完全指南(最终完整版)…

微信个人号开发API/文档/教程

微信个人号开发API/文档/教程 大家一般需求点无非是以下几个需求: 1.开发个人微信营销系统 2.开发自定义的微信机器人, 3.开发微信智能聊天客服系统 4.定制行业内的群数据分析 功能需求很简单,业务代码贼好撸,但是如…

微指令控制器基本原理

微指令控制器的基本原理 微命令和微操作一一对应。一个微命令对于一根输出控制线 相容性微命令:可以并行完成的微命令 互斥型微命令:不可以并行完成的微命令 微命令格式 水平型微命令 一条微命令可定义多个可并行的微…

一个拒绝过度设计的 .NET 快速开发框架:开箱即用,专注干活

前言 .NET 生态快速发展的背景下,越来越多开发希望找到一个既能快速上手,又不过度设计的后端框架。尤其是在中小型项目中,复杂的架构、层层封装的服务逻辑往往让开发效率大打折扣。 今天推荐一个轻量级、高效实用的…

lookup-mehtod和replace-method标签的作用

lookup-mehtod和replace-method标签的作用下面通过一个基于Spring框架的简单示例来解释 lookup - method和 replace - method的作用。 1. 项目准备 首先创建一个Maven项目,添加Spring相关的依赖: <dependencies&g…

个人微信号二次开发API调用、微信API接口

个人微信号二次开发API调用、微信API接口微信API接口、微信二次开发API调用微信协议接口调用-加微信好友及通过好友请求发送小程序 请求URL: http://域名地址/sendApplets 请求方式: POST 请求头Headers: Content-T…

React 学习笔记4 Diffing/脚手架 - 详解

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

2025.9.21+7 [未完]

2025.9.21 Week 笔记2025.9.22

VisualStudio-Python-工具指南-全-

VisualStudio Python 工具指南(全)原文:zh.annas-archive.org/md5/396df14cf233d147d6dfcb4a589a8b75 译者:飞龙 协议:CC BY-NC-SA 4.0前言 和许多其他开发者一样,Python 开发者总是需要找到方法来管理不同工具之…

深入解析:Spring Boot注解

深入解析:Spring Boot注解2025-09-22 13:14 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; …

Gevent和Subprocess问题

Gevent和Subprocess问题Gevent和Subprocess问题 1、复现 在main文件中调用gevent、并做了monkey pathch, 然后再调用subprocess.Popen(),出现一直卡住的问题Python 标准库里的很多 IO(网络 socket、ssl、time.sleep…

WPF ListBox loaded 76.6M items with imagesource

Install-Package Microsoft.Extensions.DependencyInjection; Install-Package CommunityToolkit.mvvm; public async Task InitDataAsync() {watch.Start();string imgDir = @"../../../Images";if (!Direc…

Ansible自动化运维实战 - 详解

Ansible自动化运维实战 - 详解pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco"…

建筑行业能源管理破局:MyEMS 打造商业楼宇 “能耗可视化 + 智能调控” 方案

在建筑行业的可持续发展浪潮中,商业楼宇正面临着巨大的能源管理压力。高昂的运营成本、日趋严格的碳排政策以及业主与租户对舒适环境日益增长的需求,共同构成了行业必须面对的挑战。传统的能源管理方式往往依赖于人工…

【数据结构】双向链表 - 指南

【数据结构】双向链表 - 指南pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco"…

告别“能源糊涂账”:MyEMS如何帮企业把能耗数据“算明白、用到位”

对于许多企业而言,能源成本是运营中一笔不小的开支,但却常常是一笔“糊涂账”。电费账单只有一个总数,只知道“花了多少钱”,却不知道“钱花在了哪里”、“谁在用”、“什么时候用的”、“有没有浪费”。这种粗放式…

完整教程:ElasticSearch倒排索引原理

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

Windows 离线环境下使用 VS Code 连接容器 Python 环境完整指南(亲测可用)

前言 在离线服务器环境中进行 Python 开发时,如何利用 VS Code 的强大功能进行调试和开发是一个常见需求。本文将详细介绍如何在 Windows 离线环境下,通过 WSL 和 Docker 容器实现 VS Code 连接 Python 环境的完整方…