# Redis 实战指南 ## 目录 1. [Redis 介绍](#1-redis-介绍) 2. [Redis 部署](#2-redis-部署) 3. [Redis 使用](#3-redis-使用) 4. [Redis 数据类型](#4-redis-数据类型) 5. [Redis 主从复制](#5-redis-主从复制) 6. [Redis Sentinel](#6-redis-sentinel) 7. [Redis Cluster](#7-redis-cluster) --- ## 1. Redis 介绍 ### 1.1 什么是 Redis Redis(Remote Dictionary Server)是一个开源的、基于内存的数据结构存储系统,可用作**数据库、缓存和消息队列**。 ### 1.2 Redis 特点 | 特性 | 说明 | |------|------| | 内存存储 | 数据存储在内存中,读写速度极快 | | 持久化 | 支持 RDB 和 AOF 两种持久化方式 | | 数据结构丰富 | 支持 String、Hash、List、Set、ZSet 等 | | 主从复制 | 支持 master-slave 复制架构 | | 集群 | 支持 Redis Cluster 分布式集群 | | 发布/订阅 | 支持消息发布和订阅 | | 事务 | 支持简单的事务操作 | | Lua 脚本 | 支持 Lua 脚本执行 | | 高可用 | 支持 Sentinel 哨兵机制 | ### 1.3 Redis 应用场景 | 场景 | 说明 | |------|------| | 缓存 | 热点数据缓存,减轻数据库压力 | | 会话存储 | Session、Token 存储 | | 实时排行 | ZSet 实现排行榜 | | 消息队列 | List 实现消息队列 | | 分布式锁 | SETNX 实现分布式锁 | | 计数器 | 原子自增操作 | | 限流 | 滑动窗口算法限流 | ### 1.4 Redis 与其他数据库对比 | 特性 | Redis | MySQL | MongoDB | |------|-------|-------|---------| | 数据模型 | Key-Value | 关系型 | 文档型 | | 存储介质 | 内存+磁盘 | 磁盘 | 磁盘 | | 性能 | 极高 | 中等 | 中等 | | 扩展性 | 集群 | 主从/分片 | 分片 | | 事务 | 弱事务 | 强事务 | 弱事务 | --- ## 2. Redis 部署 ### 2.1 环境要求 - 操作系统:Linux(CentOS/Ubuntu/Debian) - 编译器:GCC 4.8+ - 内存:至少 2GB(生产环境建议 4GB+) ### 2.2 编译安装 ```bash # 下载源码 wget https://download.redis.io/redis-7.2.4.tar.gz tar -zxf redis-7.2.4.tar.gz cd redis-7.2.4 # 编译 make -j4 # 安装 make install PREFIX=/usr/local/redis # 创建配置目录 mkdir -p /usr/local/redis/{etc,logs,data,run} ``` ### 2.3 RPM 包安装(CentOS/RHEL) ```bash # 安装 EPEL 源 yum install epel-release -y # 安装 Redis yum install redis -y # 启动 Redis systemctl start redis systemctl enable redis ``` ### 2.4 Docker 安装 ```bash # 拉取镜像 docker pull redis:7.2 # 运行容器 docker run -d \ --name redis \ -p 6379:6379 \ -v /data/redis/data:/data \ redis:7.2 \ redis-server --appendonly yes # 使用配置文件启动 docker run -d \ --name redis \ -p 6379:6379 \ -v /data/redis/redis.conf:/usr/local/etc/redis/redis.conf \ -v /data/redis/data:/data \ redis:7.2 \ redis-server /usr/local/etc/redis/redis.conf ``` ### 2.5 基础配置 ```bash # /usr/local/redis/etc/redis.conf # 绑定地址 bind 0.0.0.0 # 端口 port 6379 # 守护进程运行 daemonize yes # PID 文件 pidfile /usr/local/redis/run/redis.pid # 日志文件 logfile /usr/local/redis/logs/redis.log # 数据目录 dir /usr/local/redis/data # 持久化 - RDB save 900 1 save 300 10 save 60 10000 # 持久化 - AOF appendonly yes appendfsync everysec # 内存最大限制 maxmemory 2gb # 内存淘汰策略 maxmemory-policy allkeys-lru # 连接密码 requirepass your_password # 最大客户端连接数 maxclients 10000 ``` ### 2.6 启动和停止 ```bash # 启动 /usr/local/redis/bin/redis-server /usr/local/redis/etc/redis.conf # 停止 /usr/local/redis/bin/redis-cli shutdown # 停止(强制) /usr/local/redis/bin/redis-cli shutdown nosave # 连接客户端 /usr/local/redis/bin/redis-cli -a your_password # 测试连接 redis-cli ping # 返回:PONG ``` --- ## 3. Redis 使用 ### 3.1 Redis 客户端 ```bash # 命令行客户端 redis-cli # 带密码连接 redis-cli -a password # 连接远程主机 redis-cli -h 192.168.1.100 -p 6379 # 选择数据库(0-15) redis-cli -n 1 # 交互模式 redis-cli > SELECT 0 > KEYS * ``` ### 3.2 Key 操作 ```bash # 查看所有 key KEYS pattern # 示例:KEYS user:* # 查看 key 类型 TYPE key # 查看 key 存在性 EXISTS key # 设置过期时间(秒) EXPIRE key 3600 # 查看剩余过期时间 TTL key # 移除过期时间 PERSIST key # 删除 key DEL key # 重命名 RENAME key newkey # 序列化 DUMP key # 反序列化 RESTORE key 0 "serialized-value" ``` ### 3.3 数据库操作 ```bash # 切换数据库 SELECT db # 清空当前数据库 FLUSHDB # 清空所有数据库 FLUSHALL # 查看数据库 key 数量 DBSIZE # 查看最后访问时间 LASTSAVE ``` ### 3.4 慢查询日志 ```bash # 查看慢查询配置 SLOWLOG GET # 设置慢查询阈值(毫秒) CONFIG SET slowlog-log-slower-than 1000 # 保留慢查询条数 CONFIG SET slowlog-max-len 128 # 查看慢查询 SLOWLOG GET 10 ``` ### 3.5 服务器信息 ```bash # 服务器信息 INFO # 内存信息 INFO memory # CPU 信息 INFO cpu # 复制信息 INFO replication # 客户端信息 CLIENT LIST CLIENT KILL ip:port # 实时统计 MONITOR ``` --- ## 4. Redis 数据类型 ### 4.1 String(字符串) 最基本的数据类型,最大 512MB。 ```bash # 设置值 SET key value SET key value EX 3600 # 设置过期时间(秒) SET key value PX 3600000 # 设置过期时间(毫秒) SETNX key value # key 不存在时设置 SETXX key value # key 存在时设置 MSET key1 value1 key2 value2 # 批量设置 # 获取值 GET key MGET key1 key2 # 批量获取 # 数字操作 INCR key # 加 1 DECR key # 减 1 INCRBY key 10 # 加 10 DECRBY key 10 # 减 10 INCRBYFLOAT key 1.5 # 加浮点数 # 字符串操作 APPEND key "suffix" # 追加 STRLEN key # 长度 GETRANGE key 0 3 # 截取(0-3) SETRANGE key 5 "xx" # 替换 # 位操作 SETBIT key 7 1 # 设置位 GETBIT key 7 # 获取位 BITCOUNT key # 统计 1 的个数 BITOP AND destkey key1 key2 # 位运算 ``` ### 4.2 Hash(哈希) 键值对集合,适合存储对象。 ```bash # 设置 HSET key field value HSET key field1 value1 field2 value2 HSETNX key field value # 获取 HGET key field HMGET key field1 field2 HGETALL key HKEYS key # 所有字段 HVALUES key # 所有值 HLEN key # 字段数量 # 判断 HEXISTS key field # 删除 HDEL key field1 field2 # 数字操作 HINCRBY key field 10 HINCRBYFLOAT key field 1.5 ``` ### 4.3 List(列表) 有序字符串列表,支持两端操作。 ```bash # 插入 LPUSH key value1 value2 # 头部插入 RPUSH key value1 value2 # 尾部插入 LINSERT key BEFORE/AFTER pivot value # 插入 # 获取 LRANGE key 0 -1 # 获取所有 LINDEX key 0 # 按索引获取 LLEN key # 长度 # 修改 LSET key index value # 设置指定索引 LTRIM key 0 9 # 保留指定范围 # 删除 LPOP key # 头部弹出 RPOP key # 尾部弹出 LREM key count value # 删除指定元素 ``` ### 4.4 Set(无序集合) 无序且不重复的字符串集合。 ```bash # 添加 SADD key member1 member2 # 获取 SMEMBERS key # 所有成员 SCARD key # 成员数量 SISMEMBER key member # 是否存在 # 删除 SREM key member1 member2 SPOP key # 随机弹出 SRANDMEMBER key count # 随机获取 # 集合运算 SUNION key1 key2 # 并集 SINTER key1 key2 # 交集 SDIFF key1 key2 # 差集 SUNIONSTORE dest key1 key2 # 并集存储 SINTERSTORE dest key1 key2 # 交集存储 SDIFFSTORE dest key1 key2 # 差集存储 ``` ### 4.5 ZSet(有序集合) 有序且不重复的字符串集合,每个成员关联一个分数。 ```bash # 添加 ZADD key score1 member1 score2 member2 # 获取 ZRANGE key 0 -1 # 按索引获取 ZREVRANGE key 0 -1 # 倒序获取 ZRANGEBYSCORE key 0 100 # 按分数范围获取 ZSCORE key member # 获取分数 ZRANK key member # 排名(正序) ZREVRANK key member # 排名(倒序) # 数量 ZCARD key # 成员数量 ZCOUNT key min max # 分数范围内数量 # 删除 ZREM key member1 member2 ZREMRANGEBYSCORE key min max ZREMRANGEBYRANK key start stop ``` ### 4.6 HyperLogLog 用于基数统计,内存占用极低。 ```bash # 添加 PFADD key element1 element2 # 统计 PFCOUNT key1 key2 # 合并 PFMERGE destkey key1 key2 ``` ### 4.7 Geospatial 地理坐标存储和查询。 ```bash # 添加坐标 GEOADD key longitude latitude member # 获取坐标 GEOPOS key member # 计算距离 GEODIST key member1 member2 [km/m/ft/mi] # 附近查询 GEORADIUS key longitude radius km GEORADIUSBYMEMBER key member radius km ``` ### 4.8 Stream 消息队列功能。 ```bash # 添加消息 XADD key * field1 value1 field2 value2 # 读取消息 XRANGE key - + COUNT 10 XREAD COUNT 10 STREAMS key 0 # 消费者组 XGROUP CREATE key group 0 XREADGROUP GROUP group consumer COUNT 10 STREAMS key > # 消息确认 XACK key group message-id ``` --- ## 5. Redis 主从复制 ### 5.1 复制原理 Redis 主从复制采用**异步复制**模式,包含全量同步和增量同步。 ``` 全量同步流程: 1. 从库发送 PSYNC 命令 2. 主库执行 BGSAVE 生成 RDB 文件 3. 主库发送 RDB 文件给从库 4. 从库加载 RDB 文件 5. 主库发送缓冲区命令给从库 增量同步流程: 1. 主库将写命令发送给从库 2. 从库执行写命令 ``` ### 5.2 配置主从复制 ```bash # 从库配置 - redis.conf replicaof 192.168.1.100 6379 # 或者运行时执行 REPLICAOF 192.168.1.100 6379 # 取消复制 REPLICAOF NO ONE # 设置主库密码 masterauth your_password # 只读模式(从库默认) replica-read-only yes ``` ### 5.3 一主多从配置 ```bash # 主库配置 bind 0.0.0.0 port 6379 requirepass master_password appendonly yes # 从库 1 配置 replicaof 192.168.1.100 6379 masterauth master_password # 从库 2 配置 replicaof 192.168.1.100 6379 masterauth master_password ``` ### 5.4 拓扑结构 ``` ├── 主库(Master) │ ├── 从库 1(Slave) │ ├── 从库 2(Slave) │ └── 从库 3(Slave) ``` ### 5.5 主从复制管理 ```bash # 查看复制状态 INFO replication # 查看从库列表 CLIENT LIST # 断开复制 REPLICAOF NO ONE # 手动故障转移(从库执行) CLUSTER FAILOVER ``` ### 5.6 复制安全 ```bash # 主库设置密码 requirepass your_password # 从库配置主库密码 masterauth your_password # 加密复制流量 repl-diskless-sync yes repl-diskless-sync-delay 5 ``` --- ## 6. Redis Sentinel ### 6.1 Sentinel 概述 Redis Sentinel 是Redis 的高可用解决方案,负责监控主从库、自动故障转移、通知客户端。 ### 6.2 Sentinel 架构 ``` ┌─────────────┐ │ Client │ └──────┬──────┘ │ ┌──────▼──────┐ │ Sentinel │ │ (Monitor) │ └──────┬──────┘ │ ┌─────────────────┼─────────────────┐ │ │ │ ┌────▼────┐ ┌────▼────┐ ┌────▼────┐ │ Master │ │ Slave 1 │ │ Slave 2 │ └─────────┘ └─────────┘ └─────────┘ ``` ### 6.3 Sentinel 配置 ```bash # sentinel.conf # 端口 port 26379 # 守护进程 daemonize yes # 日志 logfile /var/log/redis/sentinel.log # 工作目录 dir /tmp # 监控主库 # sentinel monitor sentinel monitor mymaster 192.168.1.100 6379 2 # 主库密码 sentinel auth-pass mymaster your_password # 故障转移超时时间(毫秒) sentinel down-after-milliseconds mymaster 30000 # 并行同步数量 sentinel parallel-syncs mymaster 1 # 故障转移超时时间 sentinel failover-timeout mymaster 180000 ``` ### 6.4 启动 Sentinel ```bash # 方式 1:直接启动 redis-sentinel /etc/redis/sentinel.conf # 方式 2:redis-server 启动 redis-server /etc/redis/sentinel.conf --sentinel ``` ### 6.5 Sentinel 管理命令 ```bash # 连接 Sentinel redis-cli -p 26379 # 查看主库信息 SENTINEL get-master-addr-by-name mymaster # 查看所有从库 SENTINEL slaves mymaster # 查看 Sentinel 信息 SENTINEL sentinels mymaster # 手动故障转移 SENTINEL failover mymaster # 强制故障转移(主库宕机) SENTINEL failover force mymaster ``` ### 6.6 Java 客户端连接 ```bash # Jedis JedisSentinelPool pool = new JedisSentinelPool( "mymaster", Set.of("192.168.1.101:26379", "192.168.1.102:26379"), poolConfig, timeout, password ); # Lettuce RedisSentinelConfiguration config = new RedisSentinelConfiguration() .master("mymaster") .sentinel("192.168.1.101", 26379) .sentinel("192.168.1.102", 26379); ``` --- ## 7. Redis Cluster ### 7.1 Cluster 概述 Redis Cluster 是 Redis 的分布式解决方案,自动将数据分片到多个节点,支持高可用和水平扩展。 ### 7.2 集群架构 ``` ┌─────────────────────────────────────────────────┐ │ Redis Cluster │ ├──────────┬──────────┬──────────┬──────────┬────┤ │ Node 1 │ Node 2 │ Node 3 │ Node 4 │ .. │ │ (Master) │ (Master) │ (Master) │ (Master) │ │ │ Slot 0 │ Slot 5500│ Slot 1100│ Slot 5501│ │ │ 5461 │ 10922 │ 5462 │ 10923 │ │ ├──────────┼──────────┼──────────┼──────────┼────┤ │ Slave │ Slave │ Slave │ Slave │ │ └──────────┴──────────┴──────────┴──────────┴────┘ ``` ### 7.3 槽(Slot)分配 - Redis Cluster 有 **16384 个槽** - 每个节点负责一部分槽(0-16383) - 数据根据 key 的 CRC16 哈希值分配到对应槽 ``` 槽号计算:CRC16(key) % 16384 ``` ### 7.4 集群配置 ```bash # 节点配置 - redis.conf # 集群模式 cluster-enabled yes # 集群配置文件 cluster-config-file nodes-6379.conf # 节点超时时间 cluster-node-timeout 15000 # 集群节点端口(客户端连接端口 + 10000) cluster-announce-port 6379 cluster-announce-bus-port 16379 # 集群节点 IP cluster-announce-ip 192.168.1.100 ``` ### 7.5 创建集群 ```bash # 启动所有节点 redis-server /usr/local/redis/etc/redis-1.conf redis-server /usr/local/redis/etc/redis-2.conf redis-server /usr/local/redis/etc/redis-3.conf redis-server /usr/local/redis/etc/redis-4.conf redis-server /usr/local/redis/etc/redis-5.conf redis-server /usr/local/redis/etc/redis-6.conf # 创建集群(6 节点,3 主 3 从) redis-cli --cluster create \ 192.168.1.101:6379 \ 192.168.1.102:6379 \ 192.168.1.103:6379 \ 192.168.1.104:6379 \ 192.168.1.105:6379 \ 192.168.1.106:6379 \ --cluster-replicas 1 # 参数说明:--cluster-replicas 1 表示每个主库有 1 个从库 ``` ### 7.6 集群管理 ```bash # 连接集群 redis-cli -c # 查看集群信息 CLUSTER INFO # 查看节点信息 CLUSTER NODES # 查看槽分配 CLUSTER SLOTS # 手动分配槽 CLUSTER ADDSLOTS 0 5460 # 槽迁移 CLUSTER SETSLOT 16383 MIGRATING node_id CLUSTER SETSLOT 16384 IMPORTING node_id # 重新分片 redis-cli --cluster reshard 192.168.1.101:6379 # 添加节点 redis-cli --cluster add-node new_host:new_port existing_host:existing_port # 删除节点 redis-cli --cluster del-node host:port node_id # 故障转移(从库执行) CLUSTER FAILOVER ``` ### 7.7 集群高可用 ```bash # 检查集群状态 redis-cli --cluster check 192.168.1.101:6379 # 手动故障转移 redis-cli -h 192.168.1.104 -p 6379 CLUSTER FAILOVER # 修复集群 redis-cli --cluster fix 192.168.1.101:6379 ``` ### 7.8 Java 客户端连接 ```bash # Jedis Set nodes = new HashSet<>(); nodes.add(new HostAndPort("192.168.1.101", 6379)); nodes.add(new HostAndPort("192.168.1.102", 6379)); nodes.add(new HostAndPort("192.168.1.103", 6379)); JedisCluster cluster = new JedisCluster( nodes, 3000, 10, poolConfig ); # Spring Boot spring.data.redis.cluster.nodes=192.168.1.101:6379,192.168.1.102:6379,192.168.1.103:6379 ``` --- ## 附录 ### 常用命令速查表 | 命令 | 说明 | |------|------| | `redis-cli ping` | 测试连接 | | `redis-cli shutdown` | 关闭 Redis | | `KEYS *` | 查看所有 key | | `FLUSHDB` | 清空当前数据库 | | `BGSAVE` | 后台保存 RDB | | `LASTSAVE` | 上次保存时间 | ### 配置文件参数速查 | 参数 | 说明 | |------|------| | `bind` | 绑定地址 | | `port` | 端口 | | `daemonize` | 守护进程 | | `requirepass` | 密码 | | `maxmemory` | 最大内存 | | `maxmemory-policy` | 内存淘汰策略 | | `appendonly` | AOF 持久化 | | `save` | RDB 持久化策略 | ### 内存淘汰策略 | 策略 | 说明 | |------|------| | `noeviction` | 不淘汰,返回错误 | | `volatile-lru` | LRU 淘汰过期 key | | `allkeys-lru` | LRU 淘汰所有 key | | `volatile-random` | 随机淘汰过期 key | | `allkeys-random` | 随机淘汰所有 key | | `volatile-ttl` | 淘汰 TTL 最短的 key | | `volatile-lfu` | LFU 淘汰过期 key | | `allkeys-lfu` | LFU 淘汰所有 key | --- *文档创建时间:2024年*