Skip to content

Redis

一、Redis基础

1.1 Redis概述

Redis是什么?主要特点是什么?

解析

Redis是开源的内存数据结构存储,用作数据库、缓存和消息代理。特点包括高性能、支持多种数据结构、持久化、主从复制等。

1.2 Redis数据类型

Redis支持哪些数据类型?各自的应用场景?

解析

  • String: 缓存、计数器(如INCR
  • Hash: 存储对象(如用户信息)
  • List: 消息队列、最新消息(如LPUSH+LRANGE
  • Set: 去重、共同好友(如SINTER
  • Sorted Set: 排行榜(如ZADD+ZRANGE
  • HyperLogLog: 基数统计(如UV统计)
  • Stream: 消息队列(类似Kafka)

1.3 持久化机制

RDB和AOF的区别?如何选择?

解析

  • RDB: 快照存储,恢复快但可能丢数据。
  • AOF: 日志追加,数据更安全但文件大。
  • 选择: 生产环境通常结合使用(AOF保证数据安全,RDB用于备份)。

二、Redis高级特性

2.1 发布订阅

Redis的Pub/Sub如何工作?有什么缺点?

解析

发布者发送消息到频道,订阅者接收。缺点:消息不持久化,订阅者离线会丢失消息。

2.2 事务与Lua脚本

Redis事务的原子性如何理解?

解析

Redis事务是“部分原子性”——命令按顺序执行且不会被其他客户端打断,但单命令失败不会回滚(与MySQL不同)。

2.3 管道(Pipeline)

Pipeline的作用是什么?Golang中如何实现?

解析

批量发送命令减少RTT。Go示例:

go
pipe := client.Pipeline()
pipe.Incr("counter1")
pipe.Incr("counter2")
_, err := pipe.Exec()

三、Redis性能与优化

3.1 高性能原因

Redis为什么快?

解析

内存操作、单线程避免锁竞争、IO多路复用、高效数据结构(如跳表)。

3.2 大Key问题

3.2.1 如何发现和处理大Key?

解析

  • 发现: redis-cli --bigkeysSACN + MEMORY USAGE
  • 处理: 拆分Key、使用Hash分片、异步删除(UNLINK)。

提醒

在使用 redis-cli --bigkeys 需要使用通过 --pass 指定密码,如果有用户名不是 default 可以通过 --user 指定。但是这样不太安全,可以通过 export REDISCLI_AUTH="default" 导出一个临时的环境变量,如果用户名不是 default 则可以通过 export REDISCLI_AUTH="default:default" 导出,之后在使用 redis-cli --bigkeys 即可!

点击查看更多相关说明

🍔 1. 使用 redis-cli --bigkeys (自动分析)

输出类似如下信息

text
# Scanning the entire keyspace to find biggest keys as well as
# average sizes per key type.  You can use -i 0.1 to sleep 0.1 sec
# per 100 SCAN commands (not usually needed).


-------- summary -------

Sampled 0 keys in the keyspace!
Total key length in bytes is 0 (avg len 0.00)


0 hashs with 0 fields (00.00% of keys, avg size 0.00)
0 lists with 0 items (00.00% of keys, avg size 0.00)
0 strings with 0 bytes (00.00% of keys, avg size 0.00)
0 streams with 0 entries (00.00% of keys, avg size 0.00)
0 sets with 0 members (00.00% of keys, avg size 0.00)
0 zsets with 0 members (00.00% of keys, avg size 0.00)

优缺点

优点

  • 自动分析所有 Key,无需手动编写命令。
  • 按数据类型分类,方便定位问题。

缺点

  • 可能漏掉某些大 Key(采样不完全)。
  • 对生产环境有一定性能影响(建议低峰期运行)。

🍔 2. 使用 SCAN + MEMORY USAGE(手动分析)

  • 功能:手动遍历 Key,检查内存占用情况。
  • 适用场景--bigkeys 无法满足需求时(如更精确分析、过滤特定 Key)。

使用方法

1. 遍历所有 Key

bash
redis-cli --scan --pattern '*' | head -n 1000  # 只取前 1000 个 Key(避免太多)

或进入交互模式:

bash
127.0.0.1:6379> SCAN 0 COUNT 1000  # 从游标 0 开始,每次返回 1000 个 Key

2. 检查 Key 内存占用

bash
127.0.0.1:6379> MEMORY USAGE your_key  # 返回字节数
127.0.0.1:6379> TYPE your_key          # 查看 Key 类型
127.0.0.1:6379> STRLEN your_key        # String 类型长度
127.0.0.1:6379> HLEN your_hash         # Hash 的字段数量
127.0.0.1:6379> LLEN your_list         # List 的元素数量

3. 使用脚本自动化

bash
redis-cli --scan --pattern '*' | while read key; do
    size=$(redis-cli MEMORY USAGE "$key")
    if [ "$size" -gt 10240 ]; then  # 大于 10KB 的 Key
        echo "Big key: $key ($size bytes)"
    fi
done

优缺点

优点

  • 更灵活,可自定义过滤条件(如只检查特定前缀的 Key)。
  • 可精确计算每个 Key 的内存占用。

缺点

  • 需要手动编写命令或脚本,效率较低。
  • 对生产环境有一定性能影响(建议分批执行)。

3.3 慢查询优化

如何排查Redis慢查询?

解析

  1. 配置slowlog-log-slower-than
  2. 通过SLOWLOG GET查看。
  3. 优化复杂命令(如KEYS改为SCAN)。

四、Redis集群与高可用

4.1 主从复制

主从复制的流程是什么?

解析

全量同步(RDB快照)→ 增量同步(缓冲区命令)。

4.2 Sentinel与Cluster

Sentinel和Cluster的区别?

解析

  • Sentinel: 监控主从节点,自动故障转移。
  • Cluster: 数据分片(16384 slots),支持水平扩展。

4.3 Golang连接集群

Go如何连接Redis Cluster?

解析

使用go-redis库:

go
client := redis.NewClusterClient(&redis.ClusterOptions{
    Addrs: []string{"node1:6379", "node2:6379"},
})

五、Redis与Golang集成

5.1 客户端选择

Go中常用的Redis客户端有哪些?

解析

  • go-redis(推荐,支持Cluster/Pipeline)。
  • redigo(轻量级)。

5.2 连接池配置

如何优化Go的Redis连接池?

go
client := redis.NewClient(&redis.Options{
    PoolSize:     100,  // 连接池大小
    IdleTimeout:  5 * time.Minute,
})

六、Redis实战问题

6.1 缓存击穿/雪崩

如何解决缓存雪崩?

解析

  • 雪崩: 大量Key同时失效 → 随机过期时间。
  • 击穿: 热点Key失效 → 互斥锁(如SETNX)。

6.2 分布式锁

Golang如何实现Redis分布式锁?

解析

使用SETNX+过期时间:

go
ok, err := client.SetNX("lock_key", "1", 10*time.Second).Result()
defer client.Del("lock_key")

七、Redis运维与监控

7.1 监控指标

需要监控哪些Redis指标?

解析

内存使用率、QPS、慢查询、连接数、复制延迟。

7.2 安全配置

如何保证Redis安全?

解析

设置密码、禁用高危命令(如FLUSHDB)、绑定IP。

八、Redis新特性

8.1 Redis Streams

Streams如何实现消息队列?

解析

支持消费者组、消息持久化,类似Kafka:

bash
XADD mystream * field1 value1
XREAD GROUP mygroup consumer1 STREAMS mystream >

8.2 Redis 7新功能

Redis 7有什么改进?

解析

多线程IO(非命令执行)、ACL增强、Function API(替代Lua脚本)。

总结

以上问题覆盖了Redis的核心知识点,特别标注了Golang相关的实现细节。实际面试中可根据候选人经验选择不同深度的问题。