Redis的基础,经典,高级问题解答篇

目录

一,基础

二,经典

缓存雪崩:

1. Redis事务的原子性

2. 与MySQL事务的区别

1. 主从复制原理

2. 哨兵模式故障转移流程

3. 客户端感知故障转移

三,高级


  • 一,基础

  1. Redis的5种基础数据类型及使用场景?Zset底层实现原理?

    1. String(字符串)

      • 场景:缓存简单键值对(如用户会话信息、计数器)、分布式锁(如SETNX)、二进制数据存储(如图片Base64)。

      • 特点:支持原子操作(如INCRDECR),最大存储512MB。

    2. List(列表)

      • 场景:消息队列(LPUSH/RPOP实现生产者-消费者)、最新消息排行(如微博时间线)、阻塞式任务调度。

      • 特点:双向链表,支持按索引操作(但时间复杂度高)。

    3. Hash(哈希表)

      • 场景:存储对象(如用户信息字段:HSET user:1 name "Alice")、聚合数据(如购物车商品信息)。

      • 特点:支持单字段读写,内存优化(底层为ziplist或hashtable)。

    4. Set(集合)

      • 场景:去重数据(如用户标签)、共同好友(SINTER求交集)、随机抽奖(SRANDMEMBER)。

      • 特点:无序、自动去重,支持集合运算(并/交/差)。

    5. Zset(有序集合)

      • 场景:排行榜(按分数排序)、延迟队列(以时间戳为score)、带权重的任务调度。

      • 特点:元素唯一但score可重复,支持范围查询(ZRANGEBYSCORE)。

    6. Zset的底层由 跳跃表(Skip List) 和 字典(Dict) 组成,或在小数据量时使用 listpack(替代旧版的ziplist)

      • 跳跃表

        • 多层链表结构,高层链表作为“快速通道”,支持O(log N)的查询、插入、删除。

        • 每个节点包含scorevalue,按score排序,支持高效范围操作(如ZRANGE)。

      • 字典

        • 维护value -> score的映射,实现O(1)的单元素查询。

      • 内存优化

        • 元素数≤zset-max-listpack-entries且元素大小≤zset-max-listpack-value时,使用listpack存储。

  2. Redis持久化机制RDB和AOF的区别?如何选择?

    1. 特性RDBAOF
      原理定时生成全量数据快照(二进制文件)记录所有写命令(追加日志文件)
      文件体积小(压缩二进制)大(文本命令,需重写优化)
      恢复速度快(直接加载内存)慢(重放命令)
      数据安全可能丢失最后一次快照后的数据可配置fsync策略(无/秒级/每次写)
      资源消耗高(fork子进程内存开销)低(追加日志,重写时才有fork开销)
    2. 选择策略

      1. 高数据安全:选择AOF(appendfsync everysec),容忍秒级丢失。

      2. 快速恢复/备份:选择RDB(如每日备份)。

      3. 混合模式:Redis 4.0+支持RDB+AOF,AOF记录增量,RDB做全量备份。

  3. 如何用Redis实现分布式锁?需要注意哪些问题?

    1. 实现步骤

    2. // 加锁:SET key unique_value NX PX 30000
      String result = jedis.set("lock_key", "client1", "NX", "PX", 30000);
      if ("OK".equals(result)) {// 执行业务逻辑
      } // 解锁:Lua脚本保证原子性
      String script = "if redis.call('get', KEYS[1]) == ARGV[1] then " +"   return redis.call('del', KEYS[1]) " +"else " +"   return 0 " +"end";
      Object unlockResult = jedis.eval(script, Collections.singletonList("lock_key"), Collections.singletonList("client1"));

      注意事项

      1. 锁过期时间:需预估业务耗时,建议设置自动续期(如Redisson的看门狗)。

      2. 唯一标识:value使用唯一值(如UUID+线程ID),避免误删其他客户端的锁。

      3. 优化方案

      4. 使用Redisson库,内置看门狗、可重入锁、红锁(RedLock)实现。

      5. 对锁操作添加重试机制(如指数退避)。

      6. 原子性操作:加锁(SET NX PX)和释放锁(Lua脚本)必须原子化。

      7. 集群问题

        • 主从异步复制:主节点宕机可能导致锁丢失,可考虑RedLock算法(需部署多实例)。

        • RedLock争议:依赖系统时钟一致性,需权衡CAP。

  • 二,经典

  1. 什么是缓存穿透/雪崩/击穿?分别给出解决方案
    1. 缓存穿透:
      1. 问题:大量请求查询数据库中不存在的数据(如非法ID),绕过缓存直接压垮数据库。
        解决方案:        

        1. 布隆过滤器(Bloom Filter):在缓存层前加布隆过滤器,预存所有合法键的哈希值,拦截非法请求。

          • 特点:存在一定误判率(可能将非法请求误判为合法),需权衡内存占用。

        2. 缓存空值:对查询结果为null的键,缓存空值并设置短过期时间(如30秒)。

          • 注意:需定期清理无效空值,避免内存浪费。

    2. 缓存雪崩:
      1. 问题:大量缓存同时过期或缓存服务宕机,导致请求全部涌向数据库。
        解决方案

        1. 随机过期时间:为缓存设置基础过期时间 + 随机偏移值(如 TTL = 24h + random(0, 1h))。

        2. 永不过期 + 异步更新

          • 缓存不设过期时间,通过后台线程定期更新。

          • 结合双缓存策略:主缓存永不过期,备份缓存设置过期时间作为兜底。

        3. 熔断降级:使用Hystrix等工具,在数据库压力过大时直接返回默认值或限流。

    3. 缓存击穿:
      1. 问题热点数据过期时,高并发请求瞬间击穿缓存,直接访问数据库。
        解决方案

      2. 互斥锁(Mutex Lock)

        • 当缓存失效时,通过分布式锁(如Redis的SETNX)控制只有一个线程重建缓存,其他线程等待。

        • 示例代码:

        • public String getData(String key) {String value = redis.get(key);if (value == null) {if (redis.setnx("lock_" + key, "1", 10)) { // 获取锁value = db.query(key);redis.setex(key, 3600, value);redis.del("lock_" + key); // 释放锁} else {Thread.sleep(100); // 等待后重试return getData(key);}}return value;
          }
        • 逻辑过期:缓存永不过期,但存储的数据中增加逻辑过期时间字段,由业务代码判断是否需要异步更新。

  2. Redis事务的原子性如何理解?与MySQL事务的区别?
    1. 1. Redis事务的原子性
      • 实现方式:通过MULTI(开启事务)、EXEC(提交事务)、DISCARD(取消事务)命令实现。

      • 原子性含义

        • 命令队列的原子执行:事务中的命令会被序列化并按顺序执行,不会被其他客户端命令打断。

        • 不支持回滚:若事务中某条命令执行失败(如语法错误),其他命令仍会继续执行,无回滚机制。

        • 示例:

        • MULTI
          SET key1 "A"  # 入队
          INCR key2     # 入队(若key2非数值类型,执行时报错)
          EXEC          # 提交事务,第二条命令执行失败,但第一条仍生效
      • 2. 与MySQL事务的区别
        特性RedisMySQL
        原子性仅保证命令队列的批量执行,无回滚支持ACID,失败时自动回滚
        隔离性无隔离级别,事务执行期间可能被其他客户端修改数据支持多隔离级别(如读已提交、可重复读)
        持久性依赖持久化机制(RDB/AOF)依赖Redo Log和Binlog保证持久性
        使用场景简单批量操作(如批量SET)复杂业务逻辑(如转账、订单处理)
  3. Redis主从复制原理?哨兵模式如何实现故障转移?
    1. 1. 主从复制原理
    2. 核心流程

      1. 全量同步(首次连接)

        • 从节点发送PSYNC ? -1命令请求同步。

        • 主节点执行BGSAVE生成RDB文件并发送给从节点,同时缓存期间的写命令到复制缓冲区。

        • 从节点加载RDB后,主节点发送缓冲区中的写命令使其追上最新状态。

      2. 增量同步(断线重连)

        • 从节点发送PSYNC <runid> <offset>,主节点根据offset从复制缓冲区发送增量数据。

        • 若复制缓冲区数据丢失(如缓冲区溢出),触发全量同步。

    3. 关键配置

      • repl-backlog-size:调整复制缓冲区大小,避免频繁全量同步。

    4. 2. 哨兵模式故障转移流程

      哨兵(Sentinel)是Redis的高可用解决方案,负责监控、通知和自动故障转移:

    5. 监控

      • 每个哨兵节点定期向主节点、从节点和其他哨兵发送PING命令检测存活状态。

    6. 主观下线(SDOWN)

      • 若哨兵在down-after-milliseconds时间内未收到主节点的有效响应,标记其为主观下线。

    7. 客观下线(ODOWN)

      • 当超过半数哨兵认为主节点主观下线,则标记为客观下线。

    8. 选举Leader哨兵

      • 通过Raft算法选举一个Leader哨兵来执行故障转移。

    9. 故障转移

      • Leader哨兵从从节点列表中选出一个新的主节点(基于优先级、复制偏移量等)。

      • 向其他从节点发送SLAVEOF命令,使其复制新主节点。

      • 更新客户端配置,通知其连接新主节点。

    10. 3. 客户端感知故障转移
    11. 客户端通过订阅哨兵的+switch-master事件获取新主节点地址,或通过哨兵API动态查询。

  • 三,高级

  1. Redis Cluster集群模式的数据分片原理?如何实现动态扩容?
    1. 数据分片原理
      Redis Cluster采用哈希槽(Hash Slot)机制进行数据分片,共有16384个槽位。每个键通过CRC16(key)计算哈希值,再对16384取模确定所属槽位。集群中的每个节点负责一部分槽,数据分布由槽分配决定。客户端请求时,若连接节点不负责该槽,会返回MOVED重定向错误,引导客户端访问正确节点。节点间通过Gossip协议交换集群状态,维护槽分配信息的一致性。

      动态扩容实现

    2. 添加新节点:使用CLUSTER MEET将新节点加入集群。

    3. 迁移槽数据

      • 使用redis-cli --cluster reshard触发槽重新分片。

      • 源节点将槽内键逐个迁移到目标节点,期间对正在迁移的键的请求,源节点返回ASK重定向,客户端需重试到目标节点。

    4. 更新槽分配:迁移完成后,槽归属信息通过Gossip协议同步到整个集群。

    5. 副本扩展:新增副本节点通过CLUSTER REPLICATE同步主节点数据。

  2. Redis内存淘汰策略有哪些?如何设计大Key热Key的解决方案?
    1. 内存淘汰策略(通过maxmemory-policy配置)

    2. noeviction:拒绝写入新数据(默认)。

    3. volatile-ttl:淘汰过期时间最近的键。

    4. LRU/LFU策略

      • allkeys-lru/volatile-lru:基于最近最少使用。

      • allkeys-lfu/volatile-lfu:基于访问频率(4.0+)。

    5. 随机淘汰allkeys-random/volatile-random

    6. 大Key解决方案

    7. 拆分:如将大Hash拆分为多个小Hash,通过键名后缀分片。

    8. 异步删除:使用UNLINK代替DEL,非阻塞释放内存。

    9. 压缩:对Value进行压缩(如GZIP),但会增加CPU开销。

    10. 监控:通过redis-cli --bigkeys定期扫描大Key。

    11. 热Key解决方案

    12. 多级缓存:本地缓存(如Guava)减少Redis访问。

    13. 读写分离:通过副本节点分散读压力。

    14. 分片打散:使用Hash Tag(如{user1000}.profile)强制热Key分布到同一节点,并增加副本。

    15. Proxy支持:如Twemproxy或Codis自动分散请求。

  3. Redis多线程模型演进(从单线程到IO多线程)?管道技术原理?
    1. 多线程演进

    2. 单线程模型(6.0前):单线程处理所有网络I/O、命令解析和执行,避免锁竞争,但无法利用多核CPU。

    3. I/O多线程(6.0+)

      • 多线程网络I/O:主线程负责接收连接,I/O线程处理读写(配置io-threads启用)。

      • 单线程命令执行:命令执行仍为单线程,保证原子性。

    4. 性能提升:高并发场景下,网络I/O瓶颈缓解,吞吐量显著提升。

    5. 管道技术(Pipeline)原理

    6. 批量发送:客户端将多个命令打包发送,减少网络往返次数(RTT)。

    7. 服务端顺序执行:服务器按顺序依次执行命令,全部完成后一次性返回结果。

    8. 优势:适用于批量操作(如批量写入),提升吞吐量。

    9. 注意点:不保证原子性,且返回结果需客户端按序解析。

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

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

相关文章

hackmyvm-reversteg

arp-scan -l nmap -sS -v 192.168.222.45 在源码中可以看到 根据下面的提示可以猜测117db0148dc179a2c2245c5a30e63ab0是一个图像文件 将图片下载到本地 隐写术 在两张图片上使用strings,发现有一些可打印的字符串 strings 117db0148dc179a2c2245c5a30e63ab0.jpg base64解码…

通过国内源在Ubuntu20.0.4安装repo

国内三大免费源&#xff1a; 清华大学&#xff1a;清华大学开源软件镜像站 | Tsinghua Open Source Mirror中国科技大学&#xff1a;USTC Open Source Software Mirror阿里云&#xff1a;阿里巴巴开源镜像站-OPSX镜像站-阿里云开发者社区 repo只在清华源网站里搜到&#xff1a;…

基于EFISH-SBC-RK3576的无人机智能飞控与数据存储方案

一、方案背景 民用无人机在电力巡检、农业植保、应急救援等领域快速普及&#xff0c;但传统方案面临‌多协议设备兼容性差‌、‌野外环境数据易丢失‌、‌复杂电磁干扰‌三大痛点。 电鱼智能推出‌EFISH-SBC-RK3576‌&#xff0c;可集成双冗余总线接口与工业级加固存储&#x…

飞牛NAS本地部署小雅Alist结合内网穿透实现跨地域远程在线访问观影

文章目录 前言1. VMware安装飞牛云&#xff08;fnOS&#xff09;1.1 打开VMware创建虚拟机1.3 初始化系统 2. 飞牛云搭建小雅Alist3. 公网远程访问小雅Alist3.1 安装Cpolar内网穿透3.2 创建远程连接公网地址 4. 固定Alist小雅公网地址 前言 嘿&#xff0c;小伙伴们&#xff0c…

Java多线程与高并发专题—— CyclicBarrier 和 CountDownLatch 有什么异同?

引入 上一篇我们了解CountDownLatch的原理和常见用法&#xff0c;在CountDownLatch的源码注释中&#xff0c;有提到&#xff1a; 另一种典型用法是将一个问题分解为 N 个部分&#xff0c;用一个Runnable描述每个部分&#xff0c;该Runnable执行相应部分的任务并对闭锁进行倒计…

自建隐私优先的元搜索引擎:SearXNG 部署全指南

一、SearXNG 简介 SearXNG 是一款开源的元搜索引擎,通过聚合 Google、Bing、DuckDuckGo 等 70 多个搜索引擎的结果,为用户提供无广告、无追踪的搜索体验。其核心特性包括: 隐私保护:不记录用户 IP、搜索记录或使用 Cookie。多格式输出:支持 HTML 和 JSON 格式,便于与其他…

新手SEO优化实战快速入门

内容概要 对于SEO新手而言&#xff0c;系统化掌握基础逻辑与实操路径是快速入门的关键。本指南以站内优化为切入点&#xff0c;从网站结构、URL设计到内链布局&#xff0c;逐层拆解搜索引擎友好的技术框架&#xff1b;同时聚焦关键词挖掘与内容策略&#xff0c;结合工具使用与…

递归、搜索、回溯算法

记忆化搜索算法 记忆化搜索是一种将动态规划与递归相结合的算法&#xff0c;它通过记录已解决的子问题的解来避免重复计算&#xff0c;从而提高算法的效率。它主要用于解决具有重叠子问题性质的问题&#xff0c;例如斐波那契数列的计算、最短路径问题等。记忆化搜索的实现通常采…

Windows 10 ARM64平台MFC串口程序开发

Windows 10 IoT ARM64平台除了支持新的UWP框架&#xff0c;也兼容支持老框架MFC。使得用户在Windows 10 IoT下可以对原MFC工程进行功能升级&#xff0c;不用在新框架下重写整个工程。熟悉MFC开发的工程师也可以在Windows 10 IoT平台下继续使用MFC进行开发。 本文展示MFC串口程序…

browser-use 库网页元素点击测试工具

目录 代码代码解释输出结果 代码 import asyncio import jsonfrom browser_use.browser.browser import Browser, BrowserConfig from browser_use.dom.views import DOMBaseNode, DOMElementNode, DOMTextNode from browser_use.utils import time_execution_syncclass Eleme…

vue 点击放大,图片预览效果

背景&#xff1a; 在vue框架element组件的背景下&#xff0c;我们对图片点击放大(单张)&#xff1b;如果是多张图片&#xff0c;要支持左右滑动查看多张图片(多张)。 图片单张放大&#xff0c;el-image图片组件&#xff0c;或者原生的img标签。previewSrcList string[单个] 图片…

个人学习编程(3-27) leetcode刷题

合并两个有序链表&#xff1a; 当我们执行 current->next node; 时&#xff0c;current 最初指向的是 dummy 节点&#xff0c;因此这行代码实际上是&#xff1a; dummy->next node; /*** Definition for singly-linked list.* struct ListNode {* int val;* st…

游戏引擎学习第177天

仓库:https://gitee.com/mrxiao_com/2d_game_4 今日计划 调试代码有时可能会非常困难&#xff0c;尤其是在面对那些难以发现的 bug 时。显然&#xff0c;调试工具是其中一个非常重要的工具&#xff0c;但在游戏开发中&#xff0c;另一个非常常见的工具就是自定义的调试工具&a…

【MySQL】MySQL结构体系及核心组件功能是怎样的?

简要回答&#xff1a; MySQL采用三层架构&#xff1a;连接层处理网络连接和认证&#xff1b;服务层包含SQL解析、优化器等核心功能&#xff1b;存储引擎层插件式支持InnoDB等引擎。其中InnoDB通过redo log 实现事务持久性&#xff0c;优化器负责选择最优执行计划。 1.MySQL整体…

VR视频加密是如何实现的对视频保护?

如今VR&#xff08;虚拟现实&#xff09;技术正以前所未有的速度改变着我们的生活和工作方式。从沉浸式的游戏体验到远程教育、企业培训、医疗康复等多个领域&#xff0c;VR视频的应用场景不断拓展&#xff0c;为人们带来了全新的视觉盛宴。然而&#xff0c;随着VR视频的广泛应…

Faster RCNN Pytorch 实现 代码级 详解

基本结构&#xff1a; 采用VGG提取特征的Faster RCNN. self.backbone:提取出特征图->features self.rpn:选出推荐框->proposals self.roi heads:根据proposals在features上进行抠图->detections features self.backbone(images.tensors)proposals, proposal_losses…

LabVIEW时间触发协议

介绍了基于LabVIEW开发的时间触发协议应用&#xff0c;通过实例解析了FlexRay总线的设计与优化。通过技术细节、系统构建和功能实现等方面&#xff0c;探讨了LabVIEW在现代工业通信系统中的应用效能&#xff0c;特别是在提高通信可靠性和实时性方面的贡献。 ​ 项目背景 在工…

Linux 进程3-fork创建子进程继承父进程缓冲区验证

目录 1. fork创建子进程继承父进程缓冲区验证 1.1 write向标准输出&#xff08;终端屏幕&#xff09;写入数据验证 1.1.1 write函数写入数据不带行缓冲刷新 \n 1.1.2 write函数写入数据带行缓冲刷新 \n 1.2 fork创建前执行printf函数 1.2.1 fork创建前执行printf函数带\n…

Celery 全面指南:Python 分布式任务队列详解

Celery 全面指南&#xff1a;Python 分布式任务队列详解 Celery 是一个强大的分布式任务队列/异步任务队列系统&#xff0c;基于分布式消息传递&#xff0c;专注于实时处理&#xff0c;同时也支持任务调度。本文将全面介绍 Celery 的核心功能、应用场景&#xff0c;并通过丰富…

excel 列单元格合并(合并列相同行)

代码 首先自定义注解CellMerge&#xff0c;用于标记哪些属性需要合并&#xff0c;哪个是主键**&#xff08;这里做了一个优化&#xff0c;可以标记多个主键&#xff09;** import org.dromara.common.excel.core.CellMergeStrategy;import java.lang.annotation.*;/*** excel…