资讯动态

Redis 数据安全分析

发布时间:2026/10/9 10:25:51 来源:尧图企业网站定制
一、Redis 性能压测脚本介绍Redis 的所有数据保存在内存中读写性能强悍但内存断电即丢失。因此在实际项目中需要针对应用场景对 Redis 性能进行估算在数据安全性与读写性能之间找到平衡点。Redis 提供了压测脚本redis-benchmark可对 Redis 进行快速基准测试。# 20个线程100W个请求测试redis的set指令(写数据) redis-benchmark -a 123qweasd -t set -n 1000000 -c 20redis-benchmark更多参数使⽤redis-benchmark --help指令查看二、Redis 数据持久化机制详解1. 整体介绍Redis 提供多种持久化策略大体可组合为以下几种无持久化完全关闭数据持久化不保证数据安全相当于将 Redis 完全当作缓存使用。RDBRedis Database按照一定时间间隔保存 Redis 所有数据快照。AOFAppend Only File记录 Redis 收到的每一次写操作通过操作重演的方式恢复数据。RDB AOF同时保存 Redis 的数据和操作。RDB 优缺点优点RDB文件紧凑适合定期备份RDB快照非常适合灾难恢复RDB备份时主线程只需启动子线程对主线程 IO 性能几乎没有影响大数据量重启时比 AOF 快很多。缺点不能实时备份总会有数据丢失的可能fork 子线程时需要克隆内存数据数据量过大或 CPU 性能不佳时容易造成 Redis 短暂服务停顿。AOF 优缺点优点默认每秒写入一次服务崩溃最多损失一秒操作只追加不改写不会出现记录不完整文件过大时自动切换新日志文件记录方式简单易懂可手动调整日志如误执行 FLUSHALL 后删除最后一条指令即可恢复。缺点同样数据集下 AOF 文件通常比 RDB 更大写操作频繁时AOF 备份性能通常比 RDB 慢。整体使用建议仅当缓存使用直接关闭持久化。关注数据安全、可接受少量数据损失使用 RDB 策略性能较高。不建议单独使用 AOFRDB 配合 AOF 可让数据恢复更快。2. RDB 详解RDB 能干什么在指定时间间隔备份当前时间点内存中的全部数据集保存到磁盘文件通常是 dump.rdb。恢复时将快照文件直接读回内存。由于存的是全量数据甚至可以直接用 RDB 文件传递数据如同版本间同步。相关重要配置save 策略核心配置默认规则为 3600 秒内至少 1 次变更、300 秒内至少 100 次变更、60 秒内至少 10000 次变更时触发保存。例save 3600 1 300 100 60 10000dir文件目录。dbfilename文件名默认 dump.rdb。rdbcompression是否启用 RDB 压缩默认 yes不想消耗 CPU 可设为 no。stop-writes-on-bgsave-error默认 yes设为 no 表示不在乎数据不一致快照写入失败时仍接受新写入。rdbchecksum默认 yes。在存储快照后还可以让redis使⽤CRC64算法来进⾏数据校验但是这 样做会增加⼤约10%的性能消耗。如果希望获得最⼤的性能提升可以关闭此功能。何时触发 RDB 备份到达配置文件中默认的快照配置时自动触发。手动执行save或bgsave指令触发。save 会阻塞主线程bgsave 不阻塞主线程但 fork 子线程会占用更多内存和 CPU。主从复制时会触发 RDB 备份。可使用LASTSAVE指令查看最后一次成功执行快照的时间毫秒级 LONG 数字Linux 中可用date -d {timestamp}格式化。3. AOF 详解AOF 能干什么以日志形式记录每个写操作读操作不记录只允许追加文件不允许改写文件。相关重要配置appendonly是否开启 AOF默认不开启。appendfilename文件名称。Redis 7 中调整为三个文件base.rdb二进制数据文件、incr.aof增量操作日志、manifest记录文件信息的元文件。拆分后便于分别恢复文件也便于控制 AOF 文件大小。appendfsync同步方式。默认 everysec每秒记录一次no 表示不记录交由操作系统刷盘always 记录每次操作数据更安全但性能较低。appenddirnameAOF 文件目录实际目录为 {dir}{appenddirname}。例auto-aof-rewrite-percentage,auto-aof-rewrite-min-size文件重写触发策略默认每个文件 64M写到 100% 时进行一次重写。Redis 会定期优化重写如将多个 INCR 合并成一个 SET。也可通过BGREWRITEAOF手动触发。no-appendfsync-on-rewriteAOF 重写期间是否同步。AOF 文件内容解析AOF 增量文件按 Redis 协议记录每次操作。例如set k1 v1指令*3表示由三个部分组成$3 set表示三个字符长度的 set 组成第一部分。[root192-168-65-214 myredis]# redis-cli -a 123qweasd Warning: Using a password with -a or -u option on the command line interface may not be safe. 127.0.0.1:6379 keys * (empty array) 127.0.0.1:6379 set k1 v1 OK 127.0.0.1:6379 set k2 v2 OKAOF 日志恢复若 AOF 日志指令记录不完整如手动编辑 incr.aof 文件末尾添加文字Redis 重启会失败。需先修复日志文件再启动redis-check-aof --fix appendonly.aof.1.incr.aof修复过程实际上是将最后一条不完整的指令删除。RDB 文件也提供redis-check-rdb修复指令但由于 RDB 是二进制压缩文件一般不太可能被篡改使用较少。4. 混合持久化策略RDB 和 AOF 各有优劣Redis 支持同时开启两种持久化策略。配置参数aof-use-rdb-preamble yes同时开启时Redis 恢复数据会优先从 AOF 文件恢复因为 AOF 数据集通常比 RDB 更完整且 AOF 已包含 RDB 和 AOF 两种格式恢复效率较高。但仍建议保留 RDB 备份并定期备份作为数据安全的后手。注意持久化策略只能保证单机数据安全若磁盘损坏则无法保证需要集群化方案。三、Redis 主从复制 Replica 机制详解1. Replica作用主从复制当 Master 数据有变化时自动将新数据异步同步到其他 Slave 中。最典型作用读写分离Master 以写为主Slave 以读为主。数据备份 容灾恢复。2. 如何配置 Replica核心原则配从不配主。相关核心操作REPLICAOF host port | NO ONE一般配置到 redis.conf 中。SLAVEOF host port | NO ONE运行期间修改 slave 节点信息若已是某主库的从库会停止与原 master 的同步关系。3. 如何确定主从状态从库可以写数据吗通过info replication查看主从状态。Master 节点重点观察slave0的state状态应为 online和master_repl_offset偏移量变化Slave 节点重点观察master_link_status应为 up。默认情况下从库是只读的不允许写入数据否则会造成数据不一致。写入会报错READONLY You cant write against a read only replica.#redis.conf中配置了slave的默认权限 replica-read-only yes。对于slave从节点虽然禁止了对数据的写操作但是并没有禁止CONFIG、DEBUG等管理指令这些指令如果和主节点不一致还是容易造成数据不一致。如果为了安全起见可以使用rename-command方法屏蔽这些危险的指令。例如在redis.conf配置文件中增加配置 rename-command CONFIG 。就可以屏蔽掉slave上的CONFIG指令。很多企业在维护Redis时都会通过rename 直接禁用keys , flushdb, flushall等这一类危险的指令。4、如果Slave上已经有数据了同步时会如何处理当解除主从关系后从节点新数据更新后不变。重新建立主从关系后由于同步需要时间短时间内会出现主从数据不同步问题此时从节点数据为当前最新数据。当同步完成后从节点数据会被覆盖与主节点数据一致即slave节点数据被master覆盖。5. 主从复制工作流程主从复制是异步的但可配置 master 在未连接足够数量 replica 时停止接受写入replica 可在复制链接短暂断开时执行部分重新同步复制是自动的网络分区后 replica 会自动重连 master 并重新同步。1》 Slave启动后向master发送一个sync请求。等待建立成功后slave会删除掉自己的数据日志文件等待主节点同步。2》master接收到slave的sync请求后会触发一次RDB全量备份同时收集所有接收到的修改数据的指令。然后master将RDB和操作指令全量同步给slave。完成第一次全量同步。3》主从关系建立后master会定期向slave发送心跳包确认slave的状态。心跳发送的间隔通过参数repl-ping-replica-period指定。默认10秒。4》只要slave定期向master回复心跳请求master就会持续将后续收集到的修改数据的指令传递给slave。同时master会记录offset即已经同步给slave的消息偏移量。5》如果slave短暂不回复master的心跳请求master就会停止向slave同步数据。直到slave重新上线后master从offset开始继续向slave同步数据。6. 主从复制的缺点主从复制是后续哨兵集群和 Redis 集群的基础三种方案层层递进。主从复制本身不具备自动故障转移能力当 master 宕机时需要人工干预。1》复制延时信号衰减 所有写操作都是先在master上操作然后再同步到slave所以数据同步一定会有延迟。当系统繁忙或者slave数量增加时这个延迟会更加严重。2》master高可用问题 如果master挂了slave节点是不会自动切换master的只能等待人工干预重启master服务或者调整主从关系将一个slave切换成master同时将其他slave的主节点调整为新的master。后续的哨兵集群就相当于做这个人工干预的工作。当检测到master挂了之后自动从slave中选择一个节点切换成master。3》从数据安全性的角度主从复制牺牲了服务高可用但是增加了数据安全。四、Redis 哨兵集群 Sentinel 机制详解1. Sentinel作用Redis的Sentinel不负责数据读写主要就是给Redis的Replica主从复制提供高可用功能。主要作用有四个主从监控监控主从Redis运行是否正常消息通知将故障转移的结果发送给客户端故障转移如果master异常则会进行主从切换。将其中一个slave切换成为master。配置中心客户端通过连接哨兵可以获取当前Redis服务的master地址Sentinel 用于监控 master 状态在 master 宕机时自动将从节点切换为新的 master实现自动故障恢复。2. Sentinel 核心配置最核心的配置是 sentinel.conf 中的sentinel monitor master-name ip redis-port quorum其中 quorum 是最抽象的参数需要理解 Sentinel 的工作原理才能明白其含义。3. 解析 Sentinel 工作原理第一步如何发现 master 宕机。涉及两个概念S_DOWN主观下线每个 Sentinel 不断向 master 发送心跳若超过sentinel down-after-milliseconds默认 30 秒未收到响应则主观认为 master 下线。O_DOWN客观下线为防止网络抖动误判Sentinel 之间互相沟通当超过 quorum 个 Sentinel 节点都认为 master 出现 S_DOWN 后才标记为 O_DOWN此时才真正确定宕机并开始故障切换。配置 Sentinel 集群时通常搭建奇数个节点将 quorum 配置为过半数最大化保证可用性。第二步如何切换新的 master。故障切换经过以下步骤master 变成 O_DOWN 后Sentinel 集群通过Raft 算法选举产生一个 Leader负责协调整个故障切换过程。Sentinel 在剩余健康 Slave 中选举新 Master规则依次为replica-priority 配置最低的从节点默认 100→ 复制偏移量 offset 最大的从节点数据最全→ RunID 字典顺序最小的节点。Sentinel Leader 给新 master 执行slave of no one提升为 master并让其他 slave 成为新 master 的 slave。旧 master 恢复后Sentinel Leader 让其降级为 slave从新 master 同步数据恢复工作。最终各个Redis的配置信息会输出到Redis服务对应的redis.conf文件中完成配置覆盖。4. Sentinel 的缺点对客户端不太友好master 切换后客户端需要频繁切换写请求到新 master。数据不安全master 宕机时已完成但未同步给其他 slave 的操作会彻底丢失因为切换后所有数据以新 master 为准。因此在企业实际运用中用得更多的是下面的Redis集群服务。五、Redis 集群 Cluster 机制详解1. Cluster作用将多组 Redis Replica 主从集群整合到一起像一个 Redis 服务一样对外提供服务。核心依然是 Replica 复制集主要解决三个问题客户端需要频繁切换 master 的问题。服务端数据量太大后单个复制集难以承担的问题。master 节点挂了之后主动将 slave 切换成 master保证服务稳定。2. Cluster 的核心配置构建集群需在 redis.conf 中开启集群模式并指定集群配置文件cluster-enabled yes cluster-config-file nodes-6379.conf单机模拟三主三从集群的配置示例以其中一个配置文件 6381 为例# 允许所有的IP地址 bind * -::* # 后台运行 daemonize yes # 允许远程连接 protected-mode no # 密码 requirepass 123qweasd # 主节点密码 masterauth 123qweasd # 端口 port 6381 # 开启集群模式 cluster-enabled yes # 集群配置文件 cluster-config-file nodes-6381.conf # 集群节点超时时间 cluster-node-timeout 5000 # log日志 logfile /root/myredis/cluster/redis6381.log # pid文件 pidfile /var/run/redis_6381.pid # 开启AOF持久化 appendonly yes # 配置数据存储目录 dir /root/myredis/cluster # AOF目录 appenddirname aof # AOF文件名 appendfilename appendonly6381.aof # RBD文件名 dbfilename dump6381.rdb依次创建 6381,6382,6383,6384,6385,6386六个端口的Redis配置文件并启动服务构建集群命令将多个独立的Redis服务整合成一个统一的集群redis-cli -a 123qweasd --cluster create --cluster-replicas 1 192.168.65.214:6381 192.168.65.214:6382 192.168.65.214:6383 192.168.65.214:6384 192.168.65.214:6385 192.168.65.214:63863. Redis Slot 槽位机制详解Slot 槽位的作用Redis Cluster 采用数据分片Sharding的方式存储数据将整个数据集划分为16384 个哈希槽Slot。每个键通过 CRC16 算法计算哈希值再对 16384 取模得到该键所属的槽位最终由负责该槽位的节点存储。# 计算键所属槽位的公式 slot CRC16(key) % 16384Slot 槽位机制解决了单节点数据量过大的问题让数据可以均匀分布到集群中的多个节点上实现水平扩展。槽位分配与迁移集群创建时16384 个槽位会被平均分配到各个 master 节点。例如三主三从集群中每个 master 节点负责约 5461 个槽位。可通过cluster info查看槽位分配情况通过cluster nodes查看每个节点负责的槽位范围。当需要扩容或缩容时可以通过reshard操作将槽位从某个节点迁移到另一个节点迁移过程中数据会同步转移不影响集群对外服务。# 增加6387,6388两个Redis服务并启动 # 添加到集群当中 redis-cli -a 123qweasd -p 6381 --cluster add-node 192.168.65.214:6387 192.168.65.214:6388 # 确定集群状态 此时新节点上是没有slot分配的 redis-cli -a 123qweasd -p 6381 --cluster check 192.168.65.214:6381 # 手动触发reshard重新分配槽位 redis-cli -a 123qweasd -p 6381 reshard 192.168.65.214:6381 # 再次确定集群状态 此时新节点上会有一部分槽位分配 redis-cli -a 123qweasd -p 6381 --cluster check 192.168.65.214:6381槽位slot与键key的关系每个键只能属于一个槽位但一个槽位可以包含多个键。当客户端访问某个键时Redis 会先计算该键的槽位再定位到负责该槽位的节点。如果客户端连接的节点不是目标节点会返回MOVED重定向指令客户端根据该指令重新连接正确的节点。对于需要原子操作的多个键Redis 提供了Hash Tag机制只要键名中包含{}包裹的相同内容这些键就会被分配到同一个槽位从而支持在同一个节点上执行多键操作。# 使用 Hash Tag 让多个键落在同一槽位 set {user:1001}:name 张三 set {user:1001}:age 25 # 这两个键都会落在同一个槽位Slot 槽位的核心配置槽位数量固定为 16384不可修改。相关配置项如下cluster-enabled yes开启集群模式启用槽位机制。cluster-config-file nodes-6381.conf集群配置文件记录节点与槽位的映射关系。cluster-node-timeout 5000节点超时时间超过该时间未响应则判定节点故障。4. Redis集群选举原理1、gossip协议Redis集群之间通过gossip协议进行频繁的通信用于传递消息和更新节点状态。主要作用有节点间发送心跳和确认其他节点的存在。通知其他节点新节点的加入或已经下线的节点。通过反馈机制更新节点的状态如权重、过期时间等gossip协议包含多种消息包括pingpongmeetfail等等。meet某个节点发送meet给新加入的节点让新节点加入集群中然后新节点就会开始与其他节点进行通信ping每个节点都会频繁给其他节点发送ping其中包含自己的状态还有自己维护的集群元数据互相通过 ping交换元数据(类似自己感知到的集群节点增加和移除hash slot信息等)pong: 对ping和meet消息的返回包含自己的状态和其他信息也可以用于信息广播和更新fail: 某个节点判断另一个节点fail之后就发送fail给其他节点通知其他节点指定的节点宕机了。gossip集群是去中心化的各个节点彼此之间通过gossip协议互相通信保证集群内部各个节点最终能够达成统一。gossip协议更新元数据并不是同时在集群内部同步而是陆陆续续请求到所有节点上。因此gossip协议的数据统一是有一定的延迟的。gossip协议最大的好处在于即使集群节点的数量增加每个节点的负载也不会增加很多几乎是恒定的。因此在Redis集群中哪怕构建非常多的节点也不会对服务性能造成很大的影响。但是gossip协议的数据同步是有延迟的如果集群节点太多数据同步的延迟时间也会增加。这对于Redis是不合适的。因此通常不建议构建太大的Redis集群。需要注意下的是Redis集群中每个节点都有一个专门用于节点之间进行gossip通信的端口就是自己提供服务的端口10000.因此在部署Redis集群时要注意防火墙配置不要把这个端口屏蔽了。2、Redis集群选举流程当slave发现自己的master变为FAIL状态时便尝试进行Failover以期成为新的master。由于挂掉的master 可能会有多个slave从而存在多个slave竞争成为master节点的过程 其过程如下1》slave发现自己的master变为FAIL2》将自己记录的集群currentEpoch加1并广播FAILOVER_AUTH_REQUEST信息(currentEpoch可以理解为选举周期通过cluster info指令可以看到)3》其他节点收到该信息只有master响应判断请求者的合法性并发送FAILOVER_AUTH_ACK对每一个 epoch只发送一次ack4》尝试failover的slave收集master返回的FAILOVER_AUTH_ACK5》slave收到超过半数master的ack后变成新Master(这里解释了集群为什么至少需要三个主节点如果只有两 个当其中一个挂了只剩一个主节点是不能选举成功的)6》slave广播Pong消息通知其他集群节点从节点并不是在主节点一进入 FAIL 状态就马上尝试发起选举而是有一定延迟一定的延迟确保我们等待 FAIL状态在集群中传播slave如果立即尝试选举其它masters或许尚未意识到FAIL状态可能会拒绝投票延迟计算公式 DELAY 500ms random(0 ~ 500ms) SLAVE_RANK * 1000msSLAVE_RANK表示此slave已经从master复制数据的总量的rank。Rank越小代表已复制的数据越新。这种方 式下持有最新数据的slave将会首先发起选举理论上。七、总结与要点回顾1. 核心知识点总结性能压测使用redis-benchmark对 Redis 进行基准测试评估读写性能。持久化机制RDB 适合定期备份、恢复快AOF 记录每次写操作、数据更安全混合持久化兼顾两者优势。主从复制实现读写分离和数据备份但 master 宕机需要人工干预不具备自动故障转移能力。哨兵集群在主从复制基础上提供高可用自动监控 master 状态并完成故障切换。Cluster 集群通过 16384 个 Slot 槽位实现数据分片解决单节点容量瓶颈支持水平扩展。Slot 槽位数据分布的核心机制通过 CRC16 算法计算槽位支持 Hash Tag 实现多键原子操作。2. 三种方案对比方案解决的核心问题优点缺点主从复制读写分离、数据备份配置简单、数据安全master 宕机需人工干预哨兵集群自动故障转移高可用、自动切换客户端需频繁切换、数据可能丢失Cluster 集群数据分片、水平扩展容量大、扩展性强配置复杂、多键操作受限八、常见面试提问与解答1. Redis 的持久化方式有哪些各自有什么优缺点解答Redis 提供 RDB 和 AOF 两种持久化方式。RDB 按时间间隔保存数据快照文件紧凑、恢复速度快但不能实时备份可能丢失部分数据AOF 记录每次写操作数据更安全但文件较大、性能略低。实际生产中通常同时开启两种方式兼顾数据安全和恢复效率。2. 主从复制和哨兵集群有什么区别解答主从复制实现数据的读写分离和备份但 master 宕机时需要人工干预切换哨兵集群在主从复制基础上增加了自动监控和故障转移能力当 master 宕机时自动从 slave 中选举新的 master实现高可用。哨兵集群是主从复制的增强方案。3. Redis Cluster 是如何实现数据分片的解答Redis Cluster 将数据划分为 16384 个哈希槽每个键通过 CRC16 算法计算哈希值后对 16384 取模得到所属槽位。槽位被平均分配到各个 master 节点客户端访问时根据槽位定位到对应节点。通过槽位迁移可以实现集群的扩容和缩容。4. 什么是 Slot 槽位为什么是 16384 个解答Slot 槽位是 Redis Cluster 数据分片的基本单位整个集群被划分为 16384 个槽位每个键通过 CRC16(key) % 16384 计算归属。16384 这个数字是经过权衡的槽位数量足够多可以保证数据分布均匀同时槽位信息在节点间传递时开销可控心跳包中携带的槽位位图不会过大。5. 什么是 Hash Tag有什么作用解答Hash Tag 是 Redis Cluster 中让多个键落在同一槽位的机制。当键名中包含{}包裹的相同内容时Redis 只对花括号内的内容计算哈希值从而使这些键被分配到同一个槽位。这样可以保证多个键在同一个节点上执行支持多键原子操作如事务和 Lua 脚本。6. 哨兵集群中 quorum 参数的含义是什么解答quorum 是哨兵集群中确认 master 客观下线所需的最少哨兵节点数。当超过 quorum 个哨兵节点都认为 master 主观下线S_DOWN后才标记为客观下线O_DOWN触发故障切换。quorum 通常配置为哨兵节点总数的过半数防止网络抖动导致误判。7. Redis 集群中客户端访问数据时如果连接的节点不是目标节点会怎样解答客户端连接的节点会计算目标键的槽位如果该槽位不属于当前节点会返回MOVED重定向指令告知客户端目标节点的地址。客户端根据该指令重新连接正确的节点完成操作。这也是 Redis Cluster 客户端需要实现集群协议的原因。8. Redis集群能不能保证数据安全解答在Redis集群相对比较稳定的时候Redis集群是能够保证数据安全的。因为Redis集群中每个master都是可以配置slave从节点的。这些slave节点会即时备份master的数据。在master宕机时slave会自动切换成master。继续提供服务。但是由于Redis集群的gossip协议在同步元数据时不保证强一致性这意味着在特定的条件下Redis集群可能会丢掉一些被系统收到的写入请求命令。这些特定条件通常都比较苛刻概率比较小。比如网络抖动产生的脑裂问题。在企业中有良好运维支持通常可以认为Redis集群的数据是安全的。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑