redis-性能下降的原因排查

发布于:2025-02-24 ⋅ 阅读:(20) ⋅ 点赞:(0)

问题现象

Redis 响应变慢,查询或写入操作耗时增加。

原因

  • 数据量过大,导致操作复杂度增加。
  • 频繁的大 key 操作(如 HGETALLSMEMBERS)。
  • 网络延迟或带宽不足。
  • Redis 实例负载过高,CPU 或内存资源不足。
  • AOF 或 RDB 持久化操作影响性能。

解决方案

  • 优化大 key:拆分大 key,避免一次性操作大量数据。
  • 使用 Pipeline:将多个命令打包发送,减少网络开销。(如果redis分片,不建议使用)
  • 升级硬件:增加 CPU、内存或网络带宽。
  • 调整持久化策略:根据业务需求调整 AOF 或 RDB 的配置,例如减少 fsync 频率。(从节点做持久化)
  • 监控性能:使用 SLOWLOG 或监控工具分析慢查询。

优化大 key

String类型

  • 使用压缩格式
  • 如果时对象序列化成的字符串,考虑减少对象中的属性
  • 如果是json格式,考虑使用hash存储,需要哪个字段,就查哪个

List、Set、Zset类型

考虑方向:将1个key分散到多个节点

原始大 Key:user:1000:orders,存储了 100 万个订单

拆分后:user:1000:orders:1user:1000:orders:2,每个 Key 存储 1 万个订单。

分片:使用一致性哈希算法,将 user:1000:orders 的数据分布到多个 Redis 实例

Pipeline

作用:将多个命令打包发送,减少网络开销。

package org.example;

import org.redisson.Redisson;
import org.redisson.api.*;
import org.redisson.config.Config;

import java.util.Arrays;
import java.util.List;

public class LuaTest {


    private static final String KEY = "lock_test";
    private static final RedissonClient redisson;

    static {
        Config config = new Config();
        config.useSingleServer()
                .setAddress("redis://*****.redis.rds.aliyuncs.com:6379")
                .setUsername("****")
                .setPassword("******")
        ;
        redisson = Redisson.create(config);
    }


    public static void main(String[] args) {


        // 3. 创建 RBatch 实例
        RBatch batch = redisson.createBatch();
        // 4. 批量添加 String 类型数据
        batch.getBucket("stringKey1").setAsync("value1");
        batch.getBucket("stringKey2").setAsync("value2");
        // 5. 批量添加 List 类型数据
        RListAsync<Object> list1 = batch.getList("listKey1");
        list1.addAllAsync(Arrays.asList("item1", "item2", "item3"));
        RListAsync<Object> list2 = batch.getList("listKey2");
        list2.addAllAsync(Arrays.asList("itemA", "itemB", "itemC"));
        // 6. 执行 RBatch
        batch.execute();

        // 7. 验证结果
        System.out.println("String Key1: " + redisson.getBucket("stringKey1").get());
        System.out.println("String Key2: " + redisson.getBucket("stringKey2").get());
        List<Object> listResult1 = redisson.getList("listKey1").readAll();
        List<Object> listResult2 = redisson.getList("listKey2").readAll();
        System.out.println("List Key1: " + listResult1);
        System.out.println("List Key2: " + listResult2);

    }

}