Yang's blog Yang's blog
首页
后端开发
密码学
机器学习
命令手册
关于
友链
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

xiaoyang

尽人事,听天命
首页
后端开发
密码学
机器学习
命令手册
关于
友链
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • SpringCloud

    • 微服务架构介绍
    • SpringCloud介绍
    • Spring Cloud:生产者与消费者
    • Spring Cloud Eureka:构建可靠的服务注册与发现
    • Spring Cloud Ribbon:负载均衡
    • Spring Cloud Fegin:服务调用
    • Spring Cloud Hystrix:熔断器
    • Spring Cloud Zuul:统一网关路由
    • Spring Cloud Config:配置中心
  • Java后端框架

    • LangChain4j

      • 介绍
      • 快速开始
      • Chat and Language Models
      • Chat Memory
      • Model Parameters
      • Response Streaming
      • AI Services
      • Agent
      • Tools (Function Calling)
      • RAG
      • Structured Outputs
      • Classification
      • Embedding (Vector) Stores
      • Image Models
      • Quarkus Integration
      • Spring Boot Integration
      • Kotlin Support
      • Logging
      • Observability
      • Testing and Evaluation
      • Model Context Protocol
  • 八股文

    • 操作系统
    • JVM介绍
    • Java多线程
    • Java集合框架
    • Java反射
    • JavaIO
    • Mybatis介绍
    • Spring介绍
    • SpringBoot介绍
    • Mysql
    • Redis
    • 数据结构
    • 云计算
    • 设计模式
    • 计算机网络
    • 锁核心类AQS
    • Nginx
    • 面试场景题
      • 1.开发中慢SQL怎么优化
        • 1.1 检查并优化索引
        • 1.2 优化 SQL 语句结构
        • 1.3 数据库配置与架构优化
      • 2. JVM 内存 OOM 排查思路
        • 2.1 虚拟机栈 OOM 的排查与处理
        • 2.2 堆内存 OOM 的排查与处理
      • 3. CPU 飙升如何排查
        • 3.1 常见表现
        • 3.2 常见原因
        • 3.3 排查思路与工具
        • 3.4 解决方案
      • 4.如何用一块只有10M的内存读取1个G的文件进行频率统计?
        • 4.1 核心问题分析
        • 4.2 两种情况分析
      • 5.限流算法:固定窗口 / 滑动窗口 / 令牌桶
        • 5.1 固定窗口(Fixed Window)
        • 5.2 滑动窗口(Sliding Window)
        • 5.3 令牌桶(Token Bucket)
        • 5.4 三种限流算法对比
      • 6.如果设计一个秒杀系统
      • 7. 订单超时自动取消如何实现
        • 7.1 背景说明
        • 7.2 实现方案对比
        • 方案 1:DelayQueue(Java 自带延时队列)
        • 方案 2:RocketMQ 定时/延时消息
        • 方案 3:Redis Key 过期监听
        • 方案 4:定时任务分批处理
        • 7.3 方案对比总结
      • 8.如何防止刷单
      • 9. Redis 大 Key 问题
        • 9.1 什么是大 Key(Big Key)?
        • 9.2 大 Key 带来的问题
        • 9.3 大 Key 产生的原因
        • 9.4 如何快速定位大 Key?
        • 9.5 优化与解决方案
  • 前端技术

    • 初识Vue3
    • Vue3数据双向绑定
    • Vue3生命周期
    • Vue-Router 组件
    • Pinia 集中式状态存储
  • 中间件

    • RocketMQ
  • 开发知识

    • 请求参数注解
    • 时间复杂度和空间复杂度
    • JSON序列化与反序列化
    • Timestamp vs Datetime
    • Java开发中必备能力单元测试
    • 正向代理和反向代理
    • 什么是VPN
    • 后端服务端主动推送消息的常见方式
    • 正则表达式
    • SseEmitter vs Flux 的本质区别与底层原理解析
    • Function Calling与MCP区别
  • 后端开发
  • 八股文
xiaoyang
2025-08-22
目录

面试场景题

# 1.开发中慢SQL怎么优化

慢 SQL 通常指执行时间过长(如超过 1 秒)的 SQL 语句,优化需从索引、语句结构、数据库配置等多维度分析:

# 1.1 检查并优化索引

  • 缺失索引:通过EXPLAIN分析执行计划,若type为ALL(全表扫描),需为WHERE、JOIN、ORDER BY字段添加索引。
  • 无效索引:删除重复索引(如同一字段多次建索引)、冗余索引(如联合索引中前缀字段已单独建索引)。
  • 索引失效场景:
    • 避免使用SELECT *(可能导致覆盖索引失效)。
    • 警惕函数 / 表达式操作索引字段(如WHERE SUBSTR(name,1,3)='abc')。
    • 避免!=、NOT IN、IS NOT NULL(可能导致索引失效,视数据库版本而定)。

# 1.2 优化 SQL 语句结构

  • 拆分大 SQL:将复杂JOIN拆分为多个单表查询(尤其多表联查超过 3 张时),减少锁竞争。
  • 避免子查询:子查询可能导致临时表创建,改用JOIN优化(如SELECT * FROM t1 WHERE id IN (SELECT id FROM t2)改为JOIN)。
  • 限制返回行数:使用LIMIT分页,避免一次性返回大量数据。

# 1.3 数据库配置与架构优化

  • 调整参数:增大innodb_buffer_pool_size(MySQL)、shared_buffers(PostgreSQL),减少磁盘 IO。
  • 分库分表:当单表数据量超过 1000 万行时,采用水平分表(按时间、用户 ID)或垂直分表(拆分大字段至单独表)。
  • 读写分离:通过主从复制,将读请求分流到从库,减轻主库压力。

# 2. JVM 内存 OOM 排查思路

# 2.1 虚拟机栈 OOM 的排查与处理

常见报错信息

  • java.lang.StackOverflowError:方法调用栈过深导致栈空间不足。
  • java.lang.OutOfMemoryError: unable to create new native thread:线程数量过多,耗尽了可用栈内存。

触发原因

  1. 递归过深
    • 递归无终止条件或调用层次过多,单线程栈帧无限增加。
  2. 线程过多
    • 无限制地创建新线程(如线程池未做上限控制),每个线程都会分配独立的栈内存,导致整体超出系统限制。

排查与解决方案

  • 递归过深
    • 查看错误堆栈(Stack Trace),定位递归调用方法。
    • 检查递归终止条件是否正确。
    • 调整栈内存大小:通过 -Xss 参数(如 -Xss256k)修改单线程栈大小。
    • 代码优化:递归改循环,减少调用深度。
  • 线程过多
    • 使用 jstack <PID> 检查线程数量;若线程数过高(如上万),需确认是否存在无限制创建线程的问题。
    • 优化线程池配置:合理设置 corePoolSize、maximumPoolSize,避免无限制扩张。
    • 复用线程:使用线程池代替频繁创建新线程。

# 2.2 堆内存 OOM 的排查与处理

触发原因

  1. 对象过多,超过堆空间上限,内存溢出
    • 程序中创建了大量对象,且存活时间较长,GC 无法及时回收。
    • 常见场景:大集合(List/Map)无限增长、读取大文件数据全部加载进内存等。
  2. 内存泄漏(Memory Leak)
    • 无用对象仍然被引用,GC 无法释放内存。
    • 常见场景:静态集合缓存未清理、未关闭的连接对象(JDBC、IO、Socket)、监听器未移除等。

排查与解决方案

  • 确认是否为内存不足
    • 调整堆内存大小:通过 -Xmx 和 -Xms 参数增加堆空间(如 -Xms512m -Xmx2g)。
    • 检查是否有必要在 JVM 层面扩大堆,或通过代码优化减少对象占用。
  • 定位内存泄漏
    • 使用内存分析工具:
      • jmap -dump:format=b,file=heap.hprof <PID> 导出堆快照。
      • 使用工具(如 Eclipse MAT、VisualVM、JProfiler、YourKit)分析对象引用关系,定位泄漏点。
    • 常见优化措施:
      • 清理无用的缓存数据,避免静态集合无限增长。
      • 使用弱引用(WeakReference / SoftReference)存储缓存对象。
      • 确保关闭资源(数据库连接、文件流、网络连接等)。
      • 移除不再使用的监听器或回调。

# 3. CPU 飙升如何排查

在 Java 应用运行过程中,若某一线程进入死循环、频繁 GC 或大量上下文切换,可能导致 CPU 使用率飙升,影响系统整体性能。

# 3.1 常见表现

  • top / htop 查看进程 CPU 使用率持续高企(单核常见为 100%)。
  • 系统负载过高(load average 远超 CPU 核数)。
  • 应用响应缓慢,甚至无响应。

# 3.2 常见原因

  1. 代码层面
    • 死循环 / 无限递归(如 while(true) 无 sleep)。
    • 频繁加锁 / 自旋锁导致线程竞争消耗 CPU。
    • 高频率日志打印、无效计算。
  2. JVM 层面
    • 频繁 GC:堆内存过小或内存泄漏导致频繁 Full GC。
    • JIT 编译 / 类加载过多:应用启动初期或动态代理场景可能带来短时 CPU 飙升。
  3. 系统层面
    • 大量线程上下文切换。
    • 外部依赖阻塞(如网络抖动),导致线程忙等消耗 CPU。

# 3.3 排查思路与工具

  1. 定位高 CPU 线程

    • 使用 top -Hp <PID> 找出 CPU 占用最高的线程(显示的是线程 ID TID)。

    • 将十进制 TID 转换为十六进制:

      printf "%x\n" <TID>
      
      1
  2. 分析线程堆栈

    • 使用 jstack <PID> | grep -A 30 <TID_in_hex> 查看对应线程的堆栈。
    • 常见现象:
      • 无限循环:线程停留在某个方法内反复执行。
      • 锁竞争:大量 BLOCKED 或 WAITING 线程。
      • GC 线程:GC Thread 占用过高。
  3. 进一步定位问题

    • 使用 Arthas 或 BTrace 动态跟踪方法调用和执行耗时。
    • 使用 Java Flight Recorder (JFR) 或 Async-profiler 分析 CPU 火焰图。

# 3.4 解决方案

  • 代码问题
    • 优化算法,避免死循环 / 空轮询,合理加锁。
    • 使用异步 / 批处理代替高频率小任务提交。
  • JVM 问题
    • 适当调大堆内存,减少 GC 频率。
    • 调整 GC 策略(G1/ZGC)提升效率。
  • 系统问题
    • 优化线程池配置,避免过多线程导致频繁上下文切换。
    • 检查外部依赖(数据库、缓存、网络)的超时与重试机制。

# 4.如何用一块只有10M的内存读取1个G的文件进行频率统计?

# 4.1 核心问题分析

  • 文件大小远大于可用内存 → 无法一次性加载整个文件
  • 频率统计需要存储元素及其计数 → 内存是否足够取决于元素的基数(唯一元素数量)

# 4.2 两种情况分析

情况一:唯一元素数量小

  • 内存足够存下全部计数
  • 可以直接 内存内统计:
    • 按块读取文件(例如 1~2MB 缓冲区)
    • 每读一块就更新 HashMap 或数组里的计数
  • 不需要持久化,处理简单高效

示例代码(Java):

Map<String, Integer> freqMap = new HashMap<>();
BufferedReader reader = new BufferedReader(new FileReader("largefile.txt"), 2 * 1024 * 1024);
String line;
while ((line = reader.readLine()) != null) {
    freqMap.put(line, freqMap.getOrDefault(line, 0) + 1);
}
reader.close();
1
2
3
4
5
6
7

情况二:唯一元素数量大

  • 内存不足以存下全部计数 → 需要 外部存储或分桶
  • 典型方法:
    1. 分块读取文件,每次统计部分数据
    2. 分桶/哈希:
      • 根据元素哈希值,将元素写入不同临时文件
      • 确保每个桶的数据量可以在内存内统计
    3. 统计每个桶:
      • 将桶内元素计数存入 HashMap
      • 写入磁盘或直接合并桶内统计结果
    4. 最终合并:
      • 合并所有桶的统计结果得到完整频率

原理:类似 MapReduce 外部统计,保证 内存受限也能处理超大文件

# 5.限流算法:固定窗口 / 滑动窗口 / 令牌桶

# 5.1 固定窗口(Fixed Window)

核心原理:

  • 将时间划分为固定大小的窗口(如 1 分钟)
  • 每个窗口内统计请求次数,超过上限就拒绝
  • 简单易实现,但可能在窗口边界出现“突发峰值”
import java.util.HashMap;
import java.util.Map;

public class FixedWindowRateLimiter {
    private static final int MAX_REQUESTS = 10;  // 每分钟最大请求数
    private static final long WINDOW_SIZE = 60000; // 窗口大小(毫秒)

    private final Map<String, Integer> requestCount = new HashMap<>();
    private long currentWindow = System.currentTimeMillis() / WINDOW_SIZE;

    public synchronized boolean allowRequest(String uid) {
        long now = System.currentTimeMillis();
        long windowKey = now / WINDOW_SIZE;

        if (windowKey != currentWindow) {
            requestCount.clear();
            currentWindow = windowKey;
        }

        requestCount.putIfAbsent(uid, 0);
        int count = requestCount.get(uid);

        if (count < MAX_REQUESTS) {
            requestCount.put(uid, count + 1);
            return true;
        }
        return false;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

# 5.2 滑动窗口(Sliding Window)

核心原理:

  • 使用 时间戳队列 记录每次请求时间
  • 窗口滑动时,移除过期请求,统计窗口内请求数
  • 精确限流,可平滑处理边界突发流量
import java.util.*;

public class SlidingWindowRateLimiter {
    private static final int MAX_REQUESTS = 10;
    private static final long WINDOW_SIZE_MILLIS = 60000;
    private final Map<String, Deque<Long>> userRequests = new HashMap<>();

    public synchronized boolean allowRequest(String uid) {
        long now = System.currentTimeMillis();
        userRequests.putIfAbsent(uid, new LinkedList<>());
        Deque<Long> timestamps = userRequests.get(uid);

        while (!timestamps.isEmpty() && now - timestamps.peekFirst() >= WINDOW_SIZE_MILLIS) {
            timestamps.pollFirst();
        }

        if (timestamps.size() < MAX_REQUESTS) {
            timestamps.addLast(now);
            return true;
        }
        return false;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 5.3 令牌桶(Token Bucket)

核心原理:

  • 系统维护固定容量的令牌桶,每次请求消耗一个令牌
  • 定期往桶中补充令牌,允许请求以固定速率通过
  • 可实现平滑流量控制,允许突发请求(桶中有剩余令牌)
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

public class TokenBucketRateLimiter {
    private static final int MAX_TOKENS = 10;
    private static final int REFILL_RATE = 1;
    private final ConcurrentHashMap<String, AtomicInteger> userBuckets = new ConcurrentHashMap<>();
    private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);

    public TokenBucketRateLimiter() {
        scheduler.scheduleAtFixedRate(() -> {
            for (String uid : userBuckets.keySet()) {
                userBuckets.get(uid).updateAndGet(tokens -> Math.min(MAX_TOKENS, tokens + REFILL_RATE));
            }
        }, 0, 1000, TimeUnit.MILLISECONDS); // 每秒补充1个令牌
    }

    public boolean allowRequest(String uid) {
        userBuckets.putIfAbsent(uid, new AtomicInteger(MAX_TOKENS));
        AtomicInteger tokens = userBuckets.get(uid);
        if (tokens.get() > 0) {
            tokens.decrementAndGet();
            return true;
        }
        return false;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

# 5.4 三种限流算法对比

算法 优点 缺点 使用场景
固定窗口 简单易实现 窗口边界可能出现突发 请求量波动不大
滑动窗口 精确控制请求数,平滑限流 内存消耗略大(存储时间戳) 需要严格限流场景
令牌桶 支持突发流量、平滑限流 需定时任务管理令牌 高并发平滑限流,允许突发

# 6.如果设计一个秒杀系统

秒杀场景的特点是并发量非常大,但是库存很少,所以核心问题就是要 抗住高并发、防止超卖和重复下单。

在架构上,我会分几层:

  • 前端层:页面静态化,静态资源放 CDN,减少回源压力;秒杀开始前加上排队等待和验证码来拦截机器人。
  • 接入层:Nginx 或网关做限流和负载均衡,避免请求直接打爆后台。
  • 缓存层(Redis):活动开始前把商品信息和库存预热到 Redis,用 Lua 脚本保证库存检查和扣减的原子性;同时通过 SETNX(userId+skuId) 防止用户重复下单。
  • 消息队列(MQ):扣减成功的请求写入 MQ,走异步下单,这样可以削峰填谷,避免数据库被瞬时流量冲垮。
  • 数据库层:订单真正落库时再做一次校验,并通过唯一索引保证幂等。

整体流程就是:用户请求 → 网关限流 → Redis 原子扣减库存 → 成功后写 MQ → 消费者异步创建订单 → 数据库校验落单。

最后,为了防止超卖和一致性问题,除了 Redis 和 Lua,还需要配合 幂等机制、数据库唯一索引、以及库存回补机制 来保证最终一致。


# 7. 订单超时自动取消如何实现

# 7.1 背景说明

在电商、外卖、秒杀等场景中,订单往往需要设置有效期:

  • 用户未在规定时间内支付,订单需要自动取消,释放库存。
  • 优惠券到期需要自动作废。
  • 限时秒杀、拼团活动需要在活动结束时统一关闭。

核心目标:

  • 事件能在超时时间点准确触发。
  • 支持大规模并发订单。
  • 保证不丢单、不超卖。

# 7.2 实现方案对比

# 方案 1:DelayQueue(Java 自带延时队列)

DelayQueue

原理:

  • 订单创建时,封装成一个延时任务,放入 DelayQueue;
  • 消费线程不断轮询队列,取出到期任务,执行取消操作。

优点:

  • 简单实现,不依赖第三方中间件;
  • 开发成本低,适合 Demo 或小型系统。

缺点:

  • 所有订单都要常驻内存,内存占用大;
  • 无法分布式扩展,只能在单机或 Leader 节点执行;
  • 不适合订单量大、分布式场景。

适用场景:小规模系统,订单量不大。


# 方案 2:RocketMQ 定时/延时消息

RocketMQ

原理:

  • 下单时发送一条“延时消息”到 MQ;
  • 到期时消息被投递给消费者 → 执行订单关闭逻辑。

优点:

  • 使用简单,和普通消息一致;
  • 支持分布式;
  • 精度较高,可精确到秒。

缺点:

  • 时间上限 24 小时(RocketMQ 定时消息的限制);
  • 每个订单一条消息,消息堆积会带来较大存储压力;
  • 如果同一时间大量消息同时触发,容易形成消费高峰,导致延迟。

适用场景:中等规模订单系统,且超时时间在 24h 内。


# 方案 3:Redis Key 过期监听

Redis expire

原理:

  • 创建订单时设置 Redis Key,过期时间 = 订单超时时间;
  • 通过 Redis 过期事件通知,触发订单关闭。

优点:

  • 使用简单;
  • 延迟精度较高。

缺点:

  • 不可靠:Redis 重启或通知丢失 → 订单可能无法关闭;
  • 需要额外补偿机制(如定时任务扫库);
  • 订单量大时 Redis 内存占用高,增加维护成本。

适用场景:订单量不大 + 有补偿机制的中小型系统。


# 方案 4:定时任务分批处理

ScheduledTask

原理:

  • 数据库订单表存储“创建时间/过期时间”;
  • 定时任务(如 Quartz、xxl-job)定期扫描超时订单,批量关闭。

优点:

  • 简单稳定,订单信息集中在数据库;
  • 不依赖消息队列、Redis 通知;
  • 批量处理,适合大规模订单。

缺点:

  • 实时性较差(取决于任务调度间隔,如 1 分钟、5 分钟);
  • 高峰期批量更新数据库,可能造成压力。

适用场景:大规模订单系统,允许几分钟级延迟。


# 7.3 方案对比总结

方案 精度 扩展性 可靠性 适用场景
DelayQueue 高 差 一般 小型系统
RocketMQ 定时消息 高 好 好 中等规模,<24h
Redis 过期监听 高 中 一般 中小型,需补偿
定时任务批处理 分钟级 好 高 大规模,能容忍延迟

# 8.如何防止刷单

防刷单要从 入口限制、过程监控和事后风控 三个层面来做:

  1. 入口限制
    • 登录/注册必须绑定手机号、短信验证码,避免批量注册。
    • 对同一个 IP 或设备号限制频率,比如一分钟内最多请求几次。
    • 接入验证码(滑动/点选),拦截脚本请求。
  2. 过程控制
    • 对下单接口做 限流和幂等校验,避免短时间内频繁下单。
    • 引入 风控规则,比如:同一用户短时间内下多单、同一设备绑定多个账号、异地异常登录等。
    • 高风险订单可以进入审核或延迟支付流程。
  3. 事后风控与大数据分析
    • 结合大数据做用户画像,识别羊毛党(频繁薅优惠、异常下单)。
    • 建立黑名单系统,对异常账号、设备、IP 段进行封禁。
    • 利用机器学习/规则引擎,持续优化风控策略。

总结来说,防止刷单是一个 多层防护体系:前端用验证码 + 限流拦截,后台用幂等校验 + 风控规则,事后再用大数据画像做监控和封禁。

# 9. Redis 大 Key 问题

# 9.1 什么是大 Key(Big Key)?

在 Redis 中,大 Key 并不是指 key 的字符串本身很长,而是指 key 对应的 value 体量过大。常见的几种情况包括:

  • 单个 key 的 value 数据量过大(例如一个 string 占用几十 MB)。
  • 集合类 key(如 list、set、zset、hash)的成员数量过多(百万甚至千万级)。
  • 集合中单个成员数据过大(例如 hash 中某个 field 存储了长文本或大对象)。

# 9.2 大 Key 带来的问题

大 Key 会直接影响 Redis 的性能与稳定性,主要表现在:

  • 内存占用过高:导致 Redis 内存紧张,影响其他数据存储。
  • 性能下降:访问或操作大 Key 时耗时过长,可能导致请求延迟显著增加。
  • 阻塞其他操作:如 DEL、LRANGE、HGETALL 等对大 Key 的操作可能阻塞单线程 Redis 主进程,拖慢所有请求。
  • 网络阻塞:返回大 Key 时产生大数据包,导致网络传输延迟或阻塞。
  • 数据倾斜:在分布式场景(如 Redis Cluster)中,大 Key 可能集中在少数节点,造成负载不均衡。

# 9.3 大 Key 产生的原因

常见原因包括:

  1. 存储大型数据结构:未经过拆分或序列化压缩的对象直接写入 Redis。
  2. 缓存滥用:将原本不适合缓存的完整数据结构(如大日志文件、大列表)写入 Redis。
  3. 应用设计不合理:未对业务数据进行分片,导致热点数据持续堆积在某个 Key 中。
  4. 数据累计:未设置过期时间或清理机制,数据不断增加。

# 9.4 如何快速定位大 Key?

Redis 提供了一些工具与命令帮助排查:

  • SCAN 命令:支持渐进式遍历,不会阻塞 Redis 主线程,可用于批量扫描 key,对扫描出来的 key,结合 MEMORY USAGE 或集合类命令统计大小:。

  • --bigkeys 参数:在使用 redis-cli 时加上 --bigkeys 参数,可以统计不同数据结构的大 Key 分布情况。

    redis-cli --bigkeys
    
    1
  • Redis RDB Tools:对 RDB 文件进行分析,统计 key 的大小、类型、分布情况。


# 9.5 优化与解决方案

针对大 Key 问题,可以从以下几个角度优化:

  1. 拆分成小 Key
    • 将一个大集合拆分为多个小集合,按业务维度或时间维度切分。
    • 例如,将一个存储所有用户数据的 hash,拆分为多个用户 ID 分片存储。
  2. 优化数据结构
    • 根据场景选择合适的 Redis 数据类型,避免存储冗余数据。
    • 使用压缩编码(如 ziplist、listpack)或序列化方式减小数据体积。
  3. 设置合理的过期时间
    • 防止数据长期累积,定期清理历史数据。
    • 对临时性数据(如会话信息、缓存结果)设置合理 TTL。
  4. 启用内存淘汰策略
    • 在 redis.conf 中设置 maxmemory-policy,避免内存占满导致 OOM。
    • 常用策略有 volatile-lru、allkeys-lru 等。
  5. 数据分片
    • 在 Redis Cluster 或分布式场景下,将数据按业务维度打散,避免数据倾斜。
  6. 删除大 Key
    • 对历史遗留大 Key,采用 UNLINK(异步删除)替代 DEL,避免阻塞。
    • 对集合类大 Key,可以分批删除子元素,避免一次性清理导致卡顿。
  7. 增加内存容量
    • 在硬件允许的情况下,适当增加 Redis 实例内存,缓解大 Key 占用问题。
编辑 (opens new window)
上次更新: 2025/08/31, 08:58:18

← Nginx 初识Vue3→

最近更新
01
Function Calling与MCP区别
06-25
02
SseEmitter vs Flux 的本质区别与底层原理解析
05-12
03
操作系统
03-18
更多文章>
Theme by Vdoing | Copyright © 2023-2025 xiaoyang | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式