第 1 章 初识 Redis
- Redis 8个特性:速度快、基于键值对的数据结构服务器、功能丰富、简单稳定、客户端语言多、持久化、主从复制、支持高可用和分布式。
- Redis 不是万金油,有些场景不适合 Redis 进行开发。
- 开发运维解合以及阅读源码是用好 Redis 的重要方法。
- 生产环境中使用配置文件启动 Redis。
- 生产环境选取稳定版本的 Redis。
- Redis 3.0 是重要的里程碑,发布了 Redis 官方的分布式实现 Redis Cluster。
第 2 章 API 的理解和使用
- Redis 提供 5 种数据结构(常用),每种数据结构都有多种内部编码实现。
- 纯内存操作、IO 多路复用、单线程架构是造就 Redis 高性能的三个因素。
- 由于 Redis 单线程架构,所以需要每个命令能快速执行完,否则会存在阻塞 Redis 的可能,理解 Redis 单线程命令的处理机制是开发运维 Redis 的核心之一。
- 批量操作命令能够有效提高命令执行的效率,但要注意每次批量操作的个数和字节数。
- 了解每个命令的时间复杂度在开发中至关重要,需要考虑到数据规模对于 Redis 的影响。
- persist 命令可以删除任意类型键的过期时间,但是 set 命令也会删除字符串类型键的过期时间,这在开发时会被忽视。
- move、dump+restore、migrate 是 Redis 发展过程中三种迁移键的方式,其中 move 基本废弃,migrate 命令用于原子性的方式实现了 dump+restore,并且支持批量操作,是Redis Cluster 实现水平扩容的重要工具。
- scan 命令可以解决 keys 命令可能带来的阻塞问题,同时 Redis 还提供了 hscan、sscan、zscan 渐进式遍历 hash、set、zset。
第 3 章 小功能大用处
- 慢查询两个重要参数。
- 慢查询只计算执行时间,不算网络传输和排队时间。
- 有必要定期持久化存放慢查询
- redis-cli 一些重要选项
- redis-benchmark 的使用方法和重要参数
第 4 章 客户端
- RESP 协议
- 客户端输入缓冲区不能配置,强制限制在 1G 以内,但不会受到 maxmemory 限制。
- 客户端输出缓冲区支持普通客户的、发布订阅客户端、复制客户端,但是不会收到 maxmemory 的限制。
- Redis 的 timeout 配置可以自动关闭闲置客户端,tcp-keepalive 参数可以周期性检查关闭无效 TCP 连接。
- monitor 命令好用,但大并发下存在输出缓冲区暴涨的可能性。
- 理解 Redis 通讯原理和建立完善的监控系统对快速定位客户问题很有帮助。
第 5 章 持久化
- Redis 提供了两种持久化方式 RDB 和 AOF。
- RDB 使用一次性生成内存快照的方式,产生的文件紧凑压缩比更高,因此读取 RDB 恢复速度更快。由于每次生成 RDB 开销较大,无法做到实时持久化,一般用于冷数据冷备和复制传输。
- save 命令会阻塞主线程,不建议使用,bgsave 通过 fork 子进程生成 RDB 避免阻塞。
- AOF 通过追加写命令到文件实现持久化,通过 appendfsync 参数可以控制试试/秒级持久化。因为要不断追加写命令,所以 AOF 文件体积逐渐变大,需要定期执行重写操作来降低文件体积。
- AOF 重写可以通过 auto-aof-rewrite-min-size 和 auto-aof-rewrite-percentage 参数控制自动触发,也可以通过 bgrewriteaof 命令手动触发。
- 子进程执行期间使用 copy-on-write 机制与父进程共享内存,避免内存消耗翻倍。AOF 重写期间还要维护重写缓冲区,保存新的写入命令避免数据丢失。
- 持久化阻塞主进程场景有:fork 阻塞和 AOF 追加阻塞。fork 阻塞时间跟内存量和系统有关,AOF 追加阻塞说明磁盘资源紧张。
- 单机下部署多个实例时,为了防止出现多个子进程执行重写操作,建议做隔离控制,避免 CPU 和 IO 资源竞争。
第 6 章
- 主从复制可以通过 slave of 建立和断开复制流程。
- 支持级联复制,全量和增量复制。
- 主从节点维护心跳和偏移量检查机制。
- Redis 复制为异步,先写主后直接返回客户端,从机有延迟情况。
第 7 章 阻塞
- 内在原因:确认主线程是否存在阻塞,检查慢查询等信息,发现不合理使用 API 或数据结构的情况,关注 CPU 使用率防止单核跑满,当磁盘 IO 资源紧张是,AOF 追加也会阻塞主线程。
- 外在原因:从 CPU 竞争、内存交换、网络问题等方面检测
第 8 章 理解内存
- Redis 实际内存消耗主要包括:键值对象、缓冲区内存、内存碎片。
- 通过调整 maxmemory 控制 Redis 最大可用内存。当内存使用超时,根据 maxmemory-policy 控制内存回收策略。
- 内存优化思路:
精简键值对大小,键值字面量精简,实用高效二进制序列化工具;
适用对象共享池优化小整数对象;
数据优先使用整数,比字符串节省空间;
优化字符串使用,避免预分配造成的内存浪费;
使用 ziplist 压缩编码优化 hash、list 等结构,注意效率和空间的平衡;
使用 intset 编码优化整数集合;
使用 ziplist 编码的 hash 结构降低小对象链规模。
第 9 章 哨兵
- Sentinel 是 Redis 高可用实现方案:故障发现、故障自动转移、配置中心、客户端通知。
- 从 Redis 2.8 版本可用。
- 尽可能在不同的物理机上部署 Sentinel 所有节点。
- Sentinel 中的 Sentinel 节点个数应该大于等于 3 且最好为奇数。
- Sentinel 中的数据节点与普通数据节点没有区别。
- 客户端初始化连接的是 Sentinel 节点,但只是配置中心不是代理。
- Sentinel 通过三个定时任务实现 Sentinel 节点对于主节点、从节点、其余 Sentinel 节点的监控。
- Sentinel 对节点失效判定时分为主客观下线。
- 看懂 Sentinel 故障转移日志对 Redis Sentinel 以及问题排查非常有帮助。
- Sentinel 实现读写分离高可用可以依赖 Sentinel 节点的消息通知获取 Redis 数据节点的状态变化。
第 10 章 集群
- Redis 集群采用虚拟槽方式,将所有的键映射到 16384 个槽中,每一个节点负责一部分槽和相关数据,实现数据和请求的负载均衡。
- 集群搭建三个步骤:准备节点,节点握手,分配槽。
- 集群内部节点通讯采用 Gossip 协议彼此发送消息,消息分为 ping pong meet fail 等。
- 集群伸缩通过在节点之间移动槽和相关数据实现。扩容时潜移槽,收缩时潜移走槽和数据再 cluster forget。
- 集群自动转移过程分为故障发现和故障恢复。节点下线分为主观下线和客观下线,当超过半数主节点认为故障节点为主观下线时标记它为客观下线。从节点负责对客观下线的主节点触发故障恢复流程,保证集群可用。
- 开发和运维集群过程中常见的问题包括:超大规模集群带宽消耗, pub/sub广播问题,集群节点倾斜问题,手动故障转移,在线迁移等。
其它
安全建议
- 根据网络环境决定是否设置 Redis 密码
- rename-command 可以伪装命令,但是要注意成本
- 合理防火墙是防止攻击的利器
- bind 可以将 Redis 的访问绑定到指定的网卡上
- 定期备份数据应该作为习惯性操作
- 可以适当错开 Redis 默认端口启动
- 使用非 ROOT 用户启动 Redis