Redis 详细教程

Redis(Remote Dictionary Server)是一个开源的内存数据结构存储系统,常用作数据库、缓存和消息代理。以下是 Redis 的全面教程:

1. Redis 简介

主要特点

  • 内存存储:数据主要存储在内存中,提供极高的读写性能
  • 数据结构丰富:支持字符串、哈希、列表、集合、有序集合等
  • 持久化:支持 RDB 和 AOF 两种持久化方式
  • 高可用:支持主从复制和 Redis Sentinel
  • 分布式:通过 Redis Cluster 实现分布式存储
  • 原子操作:所有操作都是原子性的

适用场景

  • 缓存系统
  • 会话缓存
  • 排行榜/计数器
  • 消息队列
  • 实时数据分析

2. Redis 安装

Linux 安装

# Ubuntu/Debian
sudo apt update
sudo apt install redis-server

# CentOS/RHEL
sudo yum install epel-release
sudo yum install redis

# 启动Redis
sudo systemctl start redis
sudo systemctl enable redis

Mac 安装

brew install redis
brew services start redis

Windows 安装

Windows 官方不支持 Redis,但可以使用:

  1. Microsoft 维护的 Windows 版本:https://github.com/microsoftarchive/redis
  2. 使用 WSL (Windows Subsystem for Linux)

Docker 运行 Redis

docker run --name some-redis -d redis

3. Redis 命令行客户端

连接 Redis

redis-cli
# 带密码连接
redis-cli -a password
# 指定主机和端口
redis-cli -h host -p port

基本命令

PING        # 测试连接,返回 PONG
AUTH pwd    # 认证密码
SELECT n    # 选择数据库(0-15)
QUIT        # 退出连接
INFO        # 获取服务器信息
FLUSHDB     # 清空当前数据库
FLUSHALL    # 清空所有数据库

4. Redis 数据结构与操作

1. 字符串(String)

SET key value          # 设置键值
GET key               # 获取值
DEL key               # 删除键
EXISTS key            # 检查键是否存在
EXPIRE key seconds    # 设置过期时间(秒)
TTL key               # 查看剩余时间
INCR key              # 值递增1
DECR key              # 值递减1
INCRBY key increment  # 值增加指定数值
APPEND key value      # 追加值

2. 哈希(Hash)

HSET key field value     # 设置哈希字段值
HGET key field           # 获取哈希字段值
HGETALL key              # 获取所有字段和值
HDEL key field           # 删除哈希字段
HEXISTS key field        # 检查字段是否存在
HKEYS key                # 获取所有字段名
HVALS key                # 获取所有字段值
HLEN key                 # 获取字段数量

3. 列表(List)

LPUSH key value1 [value2]  # 从左侧插入
RPUSH key value1 [value2]  # 从右侧插入
LPOP key                   # 从左侧弹出
RPOP key                   # 从右侧弹出
LLEN key                   # 获取列表长度
LRANGE key start stop      # 获取列表范围
LINDEX key index           # 获取指定位置元素
LREM key count value       # 删除元素

4. 集合(Set)

SADD key member1 [member2]  # 添加元素
SMEMBERS key                # 获取所有元素
SISMEMBER key member        # 检查元素是否存在
SCARD key                   # 获取元素数量
SREM key member             # 删除元素
SINTER key1 key2            # 交集
SUNION key1 key2            # 并集
SDIFF key1 key2             # 差集

5. 有序集合(Sorted Set)

ZADD key score1 member1 [score2 member2]  # 添加元素
ZRANGE key start stop [WITHSCORES]        # 按索引范围获取
ZREVRANGE key start stop [WITHSCORES]     # 按索引倒序获取
ZRANGEBYSCORE key min max [WITHSCORES]    # 按分数范围获取
ZREM key member                           # 删除元素
ZCARD key                                 # 获取元素数量
ZCOUNT key min max                        # 统计分数范围内元素
ZRANK key member                          # 获取元素排名(升序)
ZREVRANK key member                       # 获取元素排名(降序)

5. Redis 高级功能

1. 发布/订阅

# 订阅频道
SUBSCRIBE channel1 channel2

# 发布消息(另开客户端)
PUBLISH channel1 "Hello Redis"

# 模式订阅
PSUBSCRIBE news.*

# 取消订阅
UNSUBSCRIBE channel1
PUNSUBSCRIBE news.*

2. 事务

MULTI       # 开始事务
SET key1 value1
SET key2 value2
EXEC        # 执行事务
DISCARD     # 取消事务

3. Lua 脚本

EVAL "return redis.call('GET', KEYS[1])" 1 mykey

4. 管道(Pipeline)

客户端技术,减少网络往返时间,示例(Python):

pipe = r.pipeline()
pipe.set('foo', 'bar')
pipe.get('foo')
result = pipe.execute()

6. Redis 持久化

1. RDB (Redis Database)

  • 定时快照
  • 配置(redis.conf):

    conf

    save 900 1      # 900秒内至少1个key变化
    save 300 10     # 300秒内至少10个key变化
    save 60 10000   # 60秒内至少10000个key变化
    dbfilename dump.rdb
    dir ./
    

2. AOF (Append Only File)

  • 记录所有写操作
  • 配置(redis.conf):

    conf

    appendonly yes
    appendfilename "appendonly.aof"
    appendfsync everysec  # 每秒同步
    # appendfsync always  # 每次写都同步
    # appendfsync no      # 不主动同步
    

7. Redis 高可用

1. 主从复制

# 从服务器配置(redis.conf)
replicaof 主服务器IP 主服务器端口
masterauth 主服务器密码

2. Redis Sentinel

监控主从服务器,自动故障转移

配置 sentinel.conf:

conf

sentinel monitor mymaster 127.0.0.1 6379 2
sentinel auth-pass mymaster password
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000

启动 Sentinel:

redis-server /path/to/sentinel.conf --sentinel

3. Redis Cluster

分布式解决方案,数据分片存储在多个节点

创建集群(至少3主3从):

redis-cli --cluster create 127.0.0.1:7000 127.0.0.1:7001 \
127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 \
--cluster-replicas 1

8. Redis 安全

1. 认证密码

配置 redis.conf:

conf

requirepass yourpassword

2. 绑定IP

conf

bind 127.0.0.1

3. 禁用危险命令

conf

rename-command FLUSHALL ""
rename-command CONFIG ""

4. 防火墙设置

iptables -A INPUT -p tcp --dport 6379 -s trusted_ip -j ACCEPT
iptables -A INPUT -p tcp --dport 6379 -j DROP

9. Redis 性能优化

  1. 合理使用数据结构:根据场景选择最适合的数据结构
  2. 批量操作:使用管道或批量命令(MSET, HMSET等)
  3. 避免大键:单个键值不宜过大(建议小于1MB)
  4. 设置合理过期时间:避免内存无限增长
  5. 使用连接池:减少连接创建开销
  6. 持久化优化

    • RDB适合备份,AOF适合数据安全
    • 根据业务需求选择适当的同步策略
  7. 内存优化

    • 使用redis-cli --bigkeys分析大键
    • 使用MEMORY USAGE key查看键内存占用

10. 常用客户端

Python (redis-py)

import redis

r = redis.Redis(host='localhost', port=6379, db=0)
r.set('foo', 'bar')
print(r.get('foo'))

Java (Jedis)

Jedis jedis = new Jedis("localhost");
jedis.set("foo", "bar");
System.out.println(jedis.get("foo"));
jedis.close();

Node.js (ioredis)

const Redis = require('ioredis');
const redis = new Redis();

redis.set('foo', 'bar');
redis.get('foo', (err, result) => {
  console.log(result);
});

11. Redis 监控与管理

1. 监控命令

INFO          # 查看服务器信息
INFO memory   # 内存信息
INFO stats    # 统计信息
INFO cpu      # CPU信息
CLIENT LIST   # 查看客户端连接
SLOWLOG GET   # 查看慢查询

2. 性能测试

redis-benchmark -h 127.0.0.1 -p 6379 -c 100 -n 100000

3. 数据迁移

# 导出
redis-cli --rdb dump.rdb

# 导入
redis-cli --pipe < dump.rdb

12. Redis 常见应用场景实现

1. 缓存实现

def get_data(key):
    data = redis.get(key)
    if not data:
        data = db.query(...)  # 从数据库获取
        redis.setex(key, 3600, data)  # 缓存1小时
    return data

2. 分布式锁

def acquire_lock(lock_name, acquire_timeout=10):
    identifier = str(uuid.uuid4())
    end = time.time() + acquire_timeout
    while time.time() < end:
        if redis.setnx(lock_name, identifier):
            redis.expire(lock_name, lock_timeout)
            return identifier
        elif not redis.ttl(lock_name):
            redis.expire(lock_name, lock_timeout)
        time.sleep(0.001)
    return False

def release_lock(lock_name, identifier):
    with redis.pipeline() as pipe:
        while True:
            try:
                pipe.watch(lock_name)
                if pipe.get(lock_name) == identifier:
                    pipe.multi()
                    pipe.delete(lock_name)
                    pipe.execute()
                    return True
                pipe.unwatch()
                break
            except redis.exceptions.WatchError:
                pass
    return False

3. 排行榜

# 添加分数
ZADD leaderboard 100 "player1" 200 "player2"

# 获取前10名
ZREVRANGE leaderboard 0 9 WITHSCORES

# 获取玩家排名
ZREVRANK leaderboard "player1"

4. 限流器

def rate_limiter(user_id, limit=10, period=60):
    key = f"rate_limit:{user_id}"
    current = redis.llen(key)
    if current >= limit:
        return False
    if not redis.exists(key):
        pipeline = redis.pipeline()
        pipeline.rpush(key, "1")
        pipeline.expire(key, period)
        pipeline.execute()
    else:
        redis.rpushx(key, "1")
    return True

Redis 是一个功能强大且灵活的工具,适用于各种高性能场景。通过合理使用其数据结构和特性,可以构建出高效可靠的系统。









results matching ""

    No results matching ""