前言
Redis 是一款开源的高性能键值对存储系统,广泛应用于各种 Web 应用、日志存储等场景中。Redis 擅长处理读多写少的情况,同时具有快速读写、高并发、丰富的数据结构和命令等优点。但是在进行持久化时,Redis 的定位和传统关系型数据库有所不同,其主要采用的是异步持久化和快照持久化两种方式。本文将系统全面介绍 Redis 的持久化机制,从而为读者更深刻地理解 Redis 的存储机制提供帮助。
Redis 的持久化机制
Redis 的持久化机制包括两种方式:快照持久化和异步持久化。虽然这两种方式有所不同,但目的在于将所有数据保存到硬盘中。两种方式各自的优缺点如下:
快照持久化
Redis 快照持久化方案是以一定频率拍摄数据集的一个时间点,并将其写入磁盘中,可以看作是对数据的一次全量备份。其实现原理是通过 Redis 的 SAVE 命令和 BGSAVE 命令来实现的。其中 SAVE 命令会在 Redis 主进程中发送一个阻塞状态,直到快照操作完成,期间所有请求均处于阻塞状态。而 BGSAVE 命令则会在 Redis 主进程中调用子进程进行快照操作,期间主进程继续处理请求。
快照持久化的优点在于快速,即时且紧凑,因此可以比较方便地进行备份、还原或者移动实例。同时,Redis 采用基于写时复制(copy-on-write, COW)的方式来处理父子进程之间的共享内存,也就意味着快照持久化对于内存占用没有过多的负担。然而,快照持久化有缺点,它只解决了数据安全性问题,但是在节点发生故障后,可能会有部分数据丢失。
异步持久化
Redis 的异步持久化是在快照持久化的基础上引入的一种新的机制。它避免了每次都将整个数据集写入磁盘的缺点,由于 Redis 的所有写操作都是先写入内存中,然后再异步地写入磁盘中,所以如果 Redis 异常退出,就会丢失最后一次进行修改的数据,但是不会影响到一些不重要的历史数据。
Redis 的异步持久化主要有两种方式,分别是 RDB 和 AOF。在 RDB 中,Redis 根据配置周期性地将内存中的数据写入到硬盘中。而 AOF 则是将写操作追加到磁盘中的“日志文件”中。
RDB
在 RDB 中,Redis 会将当前的内存 dump 出来,生成一个快照文件,然后将这个快照文件写到磁盘中。可以配置 Redis 在进行全量备份时,是否需要进行多次备份,比如可以在每小时备份一次,每天备份一次,每周备份一次等。在 Redis 的开发初期,快照机制是 Redis 持久化的唯一方式。但由于快照持久化机制过于频繁,所以如果 Redis 集群规模比较庞大,可能带来非常不可预期的时间成本。
AOF
在 Redis 的 AOF 中,Redis 将所有的写操作追加到文件末尾。用户可以选择不同级别的 fsync 策略。当使用 RDB 存储的方式时,对于一个完整的数据集,只需要恢复最近一次的快照,并执行剩下的操作即可。在使用 AOF 方式时,发生故障后需要将日志文件中的操作重放一遍。但是,由于每个命令都被记录在这个文件中,因此这种方式的缺点是比较高的性能成本。
Redis 持久化配置
Redis 提供了两种持久化方式,需要通过配置来启动和配置。你可以在 Redis.conf 配置文件中修改一些参数。下面是 Redis 持久化相关配置的参数:
RDB
# 是否启用 RDB 持久化功能,开启之后 Redis 即可进行数据持久化 save 900 1 # 指定在 900 秒之内,有至少一个 key 被修改,则执行波动持久化 save 300 10 # 指定在 300 秒之内,有至少有 10 个 key 被修改,则执行波动持久化 save 60 10000 # 指定在 60 秒之内有至少 10000 个 key 被修改,则执行波动持久化 dbfilename dump.rdb # 指定快照持久化文件名,默认值为 dump.rdb dir /usr/local/redis/data # 指定快照持久化文件存储路径
AOF
# 是否启用 AOF 持久化功能,开启之后,所有写命令都会记到一个日志文件中 appendonly no # 指定日志文件名。如果不特别指定,则默认名字是 appendonly.aof appendfilename "appendonly.aof" no-appendfsync-on-rewrite no auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb
在实际应用过程中,需要根据业务需求来选择 Redis 持久化的方案。RDB 由于只保存全量数据,在数据量比较大的情况下,可能会存在 “几十 GB 的 Redis 持久化文件”,所以我们可以选择 AOF 持久化方案。
Redis 持久化中的主从复制
为了满足高可用性和读写分离的需求,Redis 提供了主从复制的机制,将同步数据的过程视为一种特殊类型的持久化。Redis 从节点的数据主要由两种方式同步,第一种是在进行全量同步的时候从主节点根据指令一步步执行下来,第二种是在偏移量概念的帮助下,部分数据的实时推送。
SAVE
命令是阻塞的,需要等待所有操作都执行完毕,代价比较高,所以一般都不使用。BGSAVE
命令则是非阻塞的,但是使用时需要小心,因为操作系统在 Fork 子进程时需要很大的内存空间。实际生产环境中,还可以选择和 AOF 一样开启 “/proc/sys/vm/overcommit_memory” 参数。
主从复制可以用于实现读写分离,以及容灾等,在 Redis 应用中起到至关重要的作用。在 Redis 节点需要进行数据同步的时候,准确、高效的主从复制,不仅可以提高应用的可用性和稳定性,同时也能优化应用的性能和效率。
总结
Redis 提供的持久化方式很多,可以根据应用场景的不同选择适合的机制。在应用过程中,需要仔细权衡每种机制的优劣,选择适合自己业务需求、效率最高的持久化方式。同时要注意合理的节点拓扑结构和同步机制的配置。在实践中,我们可以使用 Redis 的持久化机制,将空间复杂度从高的为 O(通用的内存和磁盘引擎)优化为 O(数据大小),这种方式可以有效提升 Redis 的应用场景,也可以支持更复杂的新型应用体系。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64a383f548841e9894fde339