Skip to content

附录:Redis 核心知识点汇总

1. 核心命令速记

1.1 通用命令

命令功能示例
KEYS pattern查找匹配的键KEYS user:*
EXISTS key检查键是否存在EXISTS user:101
DEL key [key ...]删除键DEL user:101
TYPE key查看键的数据类型TYPE user:101
EXPIRE key seconds设置键的过期时间EXPIRE user:101 3600
TTL key查看键的剩余过期时间TTL user:101
PERSIST key移除键的过期时间PERSIST user:101
FLUSHDB清空当前数据库FLUSHDB
FLUSHALL清空所有数据库FLUSHALL
SELECT index切换数据库SELECT 1
DBSIZE查看当前数据库键数量DBSIZE

1.2 String 类型命令

命令功能示例
SET key value设置键值对SET name "zhangsan"
GET key获取键值GET name
SETEX key seconds value设置键值并指定过期时间SETEX code "1234" 60
MSET key1 value1 key2 value2 ...批量设置键值MSET name "zhangsan" age 25
MGET key1 key2 ...批量获取键值MGET name age
APPEND key value字符串拼接APPEND name "123"
STRLEN key获取字符串长度STRLEN name
INCR key数字自增1INCR counter
DECR key数字自减1DECR counter
INCRBY key increment数字增加指定值INCRBY counter 10
DECRBY key decrement数字减少指定值DECRBY counter 5

1.3 Hash 类型命令

命令功能示例
HSET key field value设置哈希字段值HSET user id 101 name "zhangsan"
HGET key field获取哈希字段值HGET user name
HMSET key field1 value1 field2 value2 ...批量设置哈希字段HMSET user id 101 name "zhangsan" age 25
HMGET key field1 field2 ...批量获取哈希字段HMGET user id name
HGETALL key获取哈希所有字段和值HGETALL user
HKEYS key获取哈希所有字段HKEYS user
HVALS key获取哈希所有值HVALS user
HDEL key field [field ...]删除哈希字段HDEL user age
HEXISTS key field判断哈希字段是否存在HEXISTS user name
HLEN key获取哈希字段数量HLEN user

1.4 List 类型命令

命令功能示例
LPUSH key element [element ...]从左侧插入元素LPUSH list "a" "b" "c"
RPUSH key element [element ...]从右侧插入元素RPUSH list "a" "b" "c"
LPOP key从左侧弹出元素LPOP list
RPOP key从右侧弹出元素RPOP list
LRANGE key start stop查看列表元素LRANGE list 0 -1
LLEN key查看列表长度LLEN list
LREM key count element删除列表中指定元素LREM list 2 "a"
LSET key index element修改列表指定位置元素LSET list 0 "d"
LINDEX key index获取列表指定位置元素LINDEX list 1

1.5 Set 类型命令

命令功能示例
SADD key member [member ...]向集合添加元素SADD set "a" "b" "c"
SMEMBERS key查看集合所有元素SMEMBERS set
SISMEMBER key member判断元素是否在集合中SISMEMBER set "a"
SREM key member [member ...]删除集合中指定元素SREM set "a"
SCARD key查看集合元素数量SCARD set
SINTER key1 key2集合交集SINTER set1 set2
SUNION key1 key2集合并集SUNION set1 set2
SDIFF key1 key2集合差集SDIFF set1 set2

1.6 Sorted Set 类型命令

命令功能示例
ZADD key score member [score member ...]向有序集合添加元素ZADD rank 100 "zhangsan" 90 "lisi"
ZRANGE key start stop [WITHSCORES]查看有序集合元素(升序)ZRANGE rank 0 -1 WITHSCORES
ZREVRANGE key start stop [WITHSCORES]查看有序集合元素(降序)ZREVRANGE rank 0 -1 WITHSCORES
ZSCORE key member查看元素分数ZSCORE rank "zhangsan"
ZINCRBY key increment member修改元素分数ZINCRBY rank 10 "zhangsan"
ZREM key member [member ...]删除有序集合中指定元素ZREM rank "zhangsan"
ZRANK key member查看元素排名(升序)ZRANK rank "zhangsan"
ZREVRANK key member查看元素排名(降序)ZREVRANK rank "zhangsan"
ZCARD key查看有序集合元素数量ZCARD rank

2. 五大数据类型对比与使用场景汇总

数据类型特点适用场景优点缺点
String简单的键值对,存储字符串或数字缓存、计数器、会话存储操作简单,支持过期时间不适合存储复杂结构
Hash键值对集合,适合存储对象用户信息、商品详情、配置信息支持单独修改字段,节省内存不支持嵌套,字段过多时性能下降
List有序可重复集合,基于链表实现消息队列、最新列表、栈/队列支持顺序操作,插入删除快查找元素慢,不适合随机访问
Set无序不可重复集合标签、去重、共同好友自动去重,支持集合运算不支持排序,查找元素需要遍历
Sorted Set有序不可重复集合,带分数排行榜、排名、范围查询支持排序,范围查询高效内存占用较大,插入性能较低

2.1 数据类型选择建议

  1. 存储简单值:使用 String
  2. 存储对象:使用 Hash
  3. 存储有序数据:使用 List
  4. 存储唯一数据:使用 Set
  5. 存储需要排序的数据:使用 Sorted Set

3. 持久化(RDB/AOF)配置步骤与对比

3.1 RDB 配置

配置步骤

  1. 编辑 redis.conf 文件
  2. 设置快照触发条件
  3. 设置 RDB 文件名称和存储路径
  4. 重启 Redis 服务

配置示例

txt
# 快照触发条件
save 900 1      # 900秒内有1个键被修改
save 300 10     # 300秒内有10个键被修改
save 60 10000   # 60秒内有10000个键被修改

# RDB文件名称
dbfilename dump.rdb

# RDB文件存储路径
dir /var/lib/redis

3.2 AOF 配置

配置步骤

  1. 编辑 redis.conf 文件
  2. 开启 AOF 功能
  3. 设置同步策略
  4. 设置 AOF 重写参数
  5. 重启 Redis 服务

配置示例

txt
# 开启AOF
appendonly yes

# AOF文件名称
appendfilename "appendonly.aof"

# 同步策略(always/everysec/no)
appendfsync everysec

# AOF重写触发条件
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

# 开启混合持久化(Redis 4.0+)
aof-use-rdb-preamble yes

3.3 RDB 与 AOF 对比

特性RDBAOF
持久化方式内存快照命令日志
数据安全性较低(可能丢失数据)较高(最多丢失1秒数据)
恢复速度
文件大小
对性能影响小(仅在快照时)较大(每次写操作)
适用场景备份、灾难恢复数据安全性要求高的场景

3.4 最佳实践

  • 开发环境:可以只开启 RDB
  • 生产环境:建议开启 AOF 或混合持久化
  • 高安全性要求:使用 AOF 的 always 同步策略
  • 高性能要求:使用 RDB 或 AOF 的 everysec 同步策略

4. 分布式锁、缓存防护常用模板

4.1 分布式锁模板

获取锁

bash
# 设置分布式锁,过期时间10秒
SET lock:key 1 NX EX 10

释放锁(使用 Lua 脚本确保原子性)

lua
if redis.call('get', KEYS[1]) == ARGV[1] then
  return redis.call('del', KEYS[1])
else
  return 0
end

完整实现(Python 示例)

python
import redis
import uuid
import time

class DistributedLock:
    def __init__(self, redis_client, lock_name, expire_time=10):
        self.redis = redis_client
        self.lock_name = f"lock:{lock_name}"
        self.expire_time = expire_time
        self.lock_value = str(uuid.uuid4())
    
    def acquire(self):
        """获取锁"""
        return self.redis.set(self.lock_name, self.lock_value, nx=True, ex=self.expire_time)
    
    def release(self):
        """释放锁"""
        script = """
        if redis.call('get', KEYS[1]) == ARGV[1]:
            return redis.call('del', KEYS[1])
        else:
            return 0
        """
        return self.redis.eval(script, 1, self.lock_name, self.lock_value)
    
    def __enter__(self):
        """支持上下文管理器"""
        while not self.acquire():
            time.sleep(0.1)
        return self
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        """支持上下文管理器"""
        self.release()

# 使用示例
redis_client = redis.Redis(host='localhost', port=6379, db=0)

with DistributedLock(redis_client, 'resource'):
    # 执行需要加锁的操作
    print("获取锁成功,执行操作...")
    time.sleep(5)
print("操作完成,锁已释放")

4.2 缓存防护模板

缓存穿透防护

python
def get_with_penetration_protection(key):
    """带缓存穿透防护的获取方法"""
    # 先查缓存
    value = redis.get(key)
    if value:
        return value if value != "NULL" else None
    
    # 缓存未命中,查数据库
    value = db.query(key)
    if value:
        # 缓存存在的值
        redis.set(key, value, ex=3600)
    else:
        # 缓存空值,设置较短过期时间
        redis.set(key, "NULL", ex=300)
    
    return value

缓存击穿防护

python
def get_with_breakdown_protection(key):
    """带缓存击穿防护的获取方法"""
    # 先查缓存
    value = redis.get(key)
    if value:
        return value
    
    # 缓存未命中,尝试获取分布式锁
    lock = DistributedLock(redis, f"lock:{key}")
    if lock.acquire():
        try:
            # 再次检查缓存(防止其他线程已经更新)
            value = redis.get(key)
            if value:
                return value
            
            # 查数据库
            value = db.query(key)
            if value:
                # 缓存热点数据,设置较长过期时间
                redis.set(key, value, ex=7200)
        finally:
            # 释放锁
            lock.release()
    else:
        # 未获取到锁,等待一段时间后重试
        time.sleep(0.1)
        return get_with_breakdown_protection(key)
    
    return value

缓存雪崩防护

python
def set_with_avalanche_protection(key, value, base_expire=3600):
    """带缓存雪崩防护的设置方法"""
    # 添加随机过期时间,避免同时过期
    expire_time = base_expire + int(random.uniform(0, 600))
    redis.set(key, value, ex=expire_time)

5. 新手易错点对照表

错误类型常见表现原因解决方案
命令拼写错误执行命令返回错误命令拼写不正确检查命令拼写,使用 HELP 命令查看正确用法
数据类型不匹配执行命令返回错误对错误的数据类型执行命令使用 TYPE 命令查看数据类型,使用正确的命令操作
键不存在执行命令返回 (nil)尝试操作不存在的键使用 EXISTS 命令检查键是否存在,或设置默认值
密码错误连接时提示认证失败Redis设置了密码,输入错误检查密码配置,使用正确的密码登录
端口占用服务启动失败Redis默认端口被其他进程占用查看端口占用情况,修改Redis端口或停止占用进程
内存不足服务启动失败或写操作失败系统内存不足或Redis内存配置过小增加系统内存,调整Redis最大内存配置
持久化未开启服务重启后数据丢失未开启RDB或AOF持久化开启持久化配置,选择合适的持久化方式
危险命令误操作数据被误删除执行了FLUSHDB/FLUSHALL等危险命令重命名或禁用危险命令,谨慎操作
缓存穿透大量请求打数据库查询不存在的数据缓存空值,设置较短过期时间
缓存击穿热点数据过期导致数据库压力骤增热点key过期使用分布式锁,设置永不过期
缓存雪崩大量key同时过期导致数据库压力骤增批量数据设置了相同的过期时间设置随机过期时间,避免同时过期
分布式锁死锁锁无法释放未设置过期时间,或进程崩溃始终设置过期时间,使用唯一标识避免误解锁

6. Redis 与后端语言协同示例代码

6.1 PHP 连接 Redis

安装扩展

bash
# 使用PECL安装
pecl install redis

# 或使用包管理器
sudo apt-get install php-redis  # Ubuntu
sudo yum install php-redis      # CentOS

示例代码

php
<?php

// 连接Redis
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);

// 验证密码(如果设置了密码)
// $redis->auth('your_password');

// 字符串操作
$redis->set('name', 'zhangsan');
echo $redis->get('name');  // 输出:zhangsan

// 哈希操作
$redis->hSet('user', 'id', 101);
$redis->hSet('user', 'name', 'zhangsan');
$redis->hSet('user', 'age', 25);
print_r($redis->hGetAll('user'));

// 列表操作
$redis->lPush('list', 'a');
$redis->lPush('list', 'b');
$redis->lPush('list', 'c');
print_r($redis->lRange('list', 0, -1));

// 集合操作
$redis->sAdd('set', 'a');
$redis->sAdd('set', 'b');
$redis->sAdd('set', 'c');
print_r($redis->sMembers('set'));

// 有序集合操作
$redis->zAdd('rank', 100, 'zhangsan');
$redis->zAdd('rank', 90, 'lisi');
$redis->zAdd('rank', 80, 'wangwu');
print_r($redis->zRevRange('rank', 0, -1, true));

// 关闭连接
$redis->close();
?>

6.2 Java 连接 Redis

添加依赖

xml
<!-- Maven依赖 -->
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>3.7.0</version>
</dependency>

示例代码

java
import redis.clients.jedis.Jedis;

public class RedisExample {
    public static void main(String[] args) {
        // 连接Redis
        Jedis jedis = new Jedis("127.0.0.1", 6379);
        
        // 验证密码(如果设置了密码)
        // jedis.auth("your_password");
        
        // 字符串操作
        jedis.set("name", "zhangsan");
        System.out.println(jedis.get("name"));  // 输出:zhangsan
        
        // 哈希操作
        jedis.hset("user", "id", "101");
        jedis.hset("user", "name", "zhangsan");
        jedis.hset("user", "age", "25");
        System.out.println(jedis.hgetAll("user"));
        
        // 列表操作
        jedis.lpush("list", "a");
        jedis.lpush("list", "b");
        jedis.lpush("list", "c");
        System.out.println(jedis.lrange("list", 0, -1));
        
        // 集合操作
        jedis.sadd("set", "a");
        jedis.sadd("set", "b");
        jedis.sadd("set", "c");
        System.out.println(jedis.smembers("set"));
        
        // 有序集合操作
        jedis.zadd("rank", 100, "zhangsan");
        jedis.zadd("rank", 90, "lisi");
        jedis.zadd("rank", 80, "wangwu");
        System.out.println(jedis.zrevrangeWithScores("rank", 0, -1));
        
        // 关闭连接
        jedis.close();
    }
}

6.3 Python 连接 Redis

安装依赖

bash
pip install redis

示例代码

python
import redis

# 连接Redis
r = redis.Redis(host='localhost', port=6379, db=0)

# 验证密码(如果设置了密码)
# r.auth('your_password')

# 字符串操作
r.set('name', 'zhangsan')
print(r.get('name'))  # 输出:b'zhangsan'

# 哈希操作
r.hset('user', 'id', 101)
r.hset('user', 'name', 'zhangsan')
r.hset('user', 'age', 25)
print(r.hgetall('user'))

# 列表操作
r.lpush('list', 'a')
r.lpush('list', 'b')
r.lpush('list', 'c')
print(r.lrange('list', 0, -1))

# 集合操作
r.sadd('set', 'a')
r.sadd('set', 'b')
r.sadd('set', 'c')
print(r.smembers('set'))

# 有序集合操作
r.zadd('rank', {'zhangsan': 100, 'lisi': 90, 'wangwu': 80})
print(r.zrevrange('rank', 0, -1, withscores=True))

# 关闭连接(Redis-py 3.0+ 自动管理连接池)
# r.close()

7. 高频面试题及参考答案

7.1 基础概念题

Q1: 什么是 Redis? A: Redis 是一个开源的、高性能的、基于内存的键值对数据库,主打高速缓存与数据存储,是最流行的非关系型数据库之一。

Q2: Redis 的核心优势有哪些? A: 高速读写、支持多数据类型、可持久化、支持分布式、轻量易用,解决高并发场景下的数据访问瓶颈。

Q3: Redis 支持哪些数据类型? A: 字符串(String)、哈希(Hash)、列表(List)、集合(Set)、有序集合(Sorted Set)。

Q4: Redis 的应用场景有哪些? A: 缓存应用、会话存储、计数器与限流、消息队列、排行榜等。

Q5: Redis 与 MySQL 的区别是什么? A: Redis 是内存存储(高速),非关系型数据库;MySQL 是磁盘存储(持久),关系型数据库。两者互补使用。

7.2 核心命令题

Q1: 如何设置一个键值对并指定过期时间? A: 使用 SET key value EX seconds 命令,例如 SET name "zhangsan" EX 3600

Q2: 如何批量设置多个键值对? A: 使用 MSET key1 value1 key2 value2 ... 命令,例如 MSET name "zhangsan" age 25

Q3: 如何查看哈希类型的所有字段和值? A: 使用 HGETALL key 命令,例如 HGETALL user

Q4: 如何向列表左侧插入元素? A: 使用 LPUSH key element [element ...] 命令,例如 LPUSH list "a" "b" "c"

Q5: 如何获取有序集合的前 N 个元素(降序)? A: 使用 ZREVRANGE key 0 N-1 [WITHSCORES] 命令,例如 ZREVRANGE rank 0 4 WITHSCORES

7.3 实战场景题

Q1: 如何解决缓存穿透问题? A: 缓存空值,设置较短的过期时间,避免请求直接打数据库。

Q2: 如何解决缓存击穿问题? A: 使用分布式锁,确保只有一个线程去数据库查询;或设置热点数据永不过期。

Q3: 如何解决缓存雪崩问题? A: 为批量数据设置随机过期时间,避免同时过期;或使用分层缓存。

Q4: 如何实现分布式锁? A: 使用 SET key value NX EX seconds 命令获取锁,使用 Lua 脚本原子释放锁。

Q5: 如何选择 RDB 和 AOF 持久化方式? A: 开发环境可以只使用 RDB;生产环境建议使用 AOF 或混合持久化;高安全性要求使用 AOF 的 always 同步策略;高性能要求使用 RDB 或 AOF 的 everysec 同步策略。

7.4 安全题

Q1: 如何提高 Redis 的安全性? A: 设置强密码、修改默认端口、绑定IP、禁用危险命令、及时更新版本。

Q2: 如何设置 Redis 密码? A: 在 redis.conf 文件中设置 requirepass your_password,或使用 CONFIG SET requirepass your_password 临时设置。

Q3: 如何禁用危险命令? A: 在 redis.conf 文件中使用 rename-command 指令重命名或禁用危险命令,例如 rename-command FLUSHDB ""

7.5 进阶题

Q1: Redis 集群的工作原理是什么? A: Redis Cluster 使用哈希槽(16384个)将数据分布到多个节点,每个主节点负责一部分哈希槽,从节点作为备份。当主节点故障时,从节点自动提升为主节点。

Q2: Redis 的内存淘汰策略有哪些? A: volatile-lru、allkeys-lru、volatile-ttl、volatile-random、allkeys-random、noeviction。

Q3: Redis 的持久化机制有哪些? A: RDB(快照持久化)和 AOF( Append Only File)。

Q4: Redis 的主从复制原理是什么? A: 主节点将数据同步到从节点,从节点作为只读副本。复制方式包括全量复制和增量复制。

Q5: 如何优化 Redis 的性能? A: 合理设计键名、使用批量命令、优化数据结构、配置合适的内存淘汰策略、选择合适的持久化方式、使用管道操作、避免使用危险命令。

7.6 面试技巧

  1. 理解核心概念:掌握 Redis 的基本概念、数据类型和常用命令。
  2. 熟悉实战场景:了解 Redis 在实际项目中的应用场景和解决方案。
  3. 掌握优化技巧:了解 Redis 的性能优化和安全防护措施。
  4. 准备实际案例:准备一个自己使用 Redis 的实际案例,展示实践经验。
  5. 理清思路:回答问题时,先理清思路,分点作答,逻辑清晰。
  6. 诚实面对:遇到不会的问题,坦诚承认,表现出学习意愿。

实战总结

本附录汇总了Redis的核心知识点,包括常用命令、数据类型对比、持久化配置、分布式锁模板、新手易错点、后端语言集成示例和面试题等内容。这些知识点是Redis学习和应用的重要参考资料,希望能帮助你快速掌握Redis的核心功能和最佳实践。

Redis是一个功能强大的缓存和数据存储系统,通过不断学习和实践,你可以将其威力发挥到极致,为你的应用提供高性能、高可用的数据存储解决方案。

© 2026 编程马·菜鸟教程 版权所有