Redis 数据持久化

发布于:2024-06-23 ⋅ 阅读:(45) ⋅ 点赞:(0)

Redis 提供了多种持久化机制,用于将数据从内存保存到磁盘,以便在重启时恢复数据。主要的持久化机制包括 RDB(Redis Database File)和 AOF(Append-Only File)。这两种机制各有优缺点,可以根据实际需求选择使用。

RDB 持久化

RDB 通过创建指定时间点的数据快照将数据持久化到磁盘。RDB 持久化适用于需要低延迟的情况,但如果 Redis 崩溃,可能会丢失最后一次快照之后的数据。

配置 RDB 持久化

在 Redis 配置文件 redis.conf 中配置 RDB 持久化。以下是一些常用的配置选项:

# 保存 RDB 快照的频率
# 下面的配置表示在 900 秒内如果至少有 1 次写操作,就触发一次快照
save 900 1

# 在 300 秒内如果至少有 10 次写操作,就触发一次快照
save 300 10

# 在 60 秒内如果至少有 10000 次写操作,就触发一次快照
save 60 10000

# RDB 文件的保存路径
dir ./

# RDB 文件的名称
dbfilename dump.rdb

手动创建 RDB 快照

你可以使用 SAVEBGSAVE 命令手动创建 RDB 快照:

# 同步保存数据到 RDB 文件
SAVE

# 异步保存数据到 RDB 文件
BGSAVE

AOF 持久化

AOF 通过记录每个写操作将数据持久化到日志文件。AOF 持久化可以更好地保证数据的完整性,但会增加磁盘 I/O 负担。

配置 AOF 持久化

redis.conf 中配置 AOF 持久化。以下是一些常用的配置选项:

# 启用 AOF 持久化
appendonly yes

# AOF 文件的名称
appendfilename "appendonly.aof"

# AOF 同步频率
# appendfsync always   # 每次写操作后都同步(最安全,最慢)
# appendfsync everysec # 每秒同步一次(折衷,推荐)
# appendfsync no       # 不同步(由操作系统决定同步时机,最快)
appendfsync everysec

# 重写 AOF 文件策略
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

手动重写 AOF 文件

你可以使用 BGREWRITEAOF 命令手动重写 AOF 文件,以减少文件大小和磁盘 I/O

BGREWRITEAOF

RDB 和 AOF 结合使用

Redis 允许同时启用 RDB 和 AOF 持久化,这样可以结合两者的优点。配置如下

# 启用 RDB 持久化
save 900 1
save 300 10
save 60 10000
dir ./
dbfilename dump.rdb

# 启用 AOF 持久化
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

在 Redis 启动时,它会优先使用 AOF 文件恢复数据。如果 AOF 文件不可用,则使用 RDB 文件。

示例:配置和使用持久化

配置文件(redis.conf)

# RDB 持久化配置
save 900 1
save 300 10
save 60 10000
dir ./
dbfilename dump.rdb

# AOF 持久化配置
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

启动 Redis

使用指定的配置文件启动 Redis:

redis-server /path/to/redis.conf

使用 Redis CLI 查看持久化信息

你可以使用 Redis CLI 命令查看持久化信息

# 查看最后一次 RDB 保存时间
LASTSAVE

# 查看持久化相关的统计信息
INFO persistence

示例代码:使用 Redis 持久化

以下是一个 C++ 示例代码,展示如何通过 hiredis 与 Redis 进行交互,并使用持久化机制

#include <hiredis/hiredis.h>
#include <iostream>
#include <string>

void set_data(redisContext* context, const std::string& key, const std::string& value) {
    redisReply* reply = (redisReply*)redisCommand(context, "SET %s %s", key.c_str(), value.c_str());
    if (reply == NULL) {
        std::cerr << "SET command failed" << std::endl;
        return;
    }
    std::cout << "SET command: " << reply->str << std::endl;
    freeReplyObject(reply);
}

std::string get_data(redisContext* context, const std::string& key) {
    redisReply* reply = (redisReply*)redisCommand(context, "GET %s", key.c_str());
    if (reply == NULL || reply->type == REDIS_REPLY_NIL) {
        std::cerr << "GET command failed" << std::endl;
        return "";
    }
    std::string value = reply->str;
    freeReplyObject(reply);
    return value;
}

int main() {
    redisContext* context = redisConnect("127.0.0.1", 6379);
    if (context == NULL || context->err) {
        if (context) {
            std::cerr << "Error: " << context->errstr << std::endl;
            redisFree(context);
        } else {
            std::cerr << "Can't allocate redis context" << std::endl;
        }
        return 1;
    }

    set_data(context, "mykey", "Hello, Redis!");
    std::string value = get_data(context, "mykey");
    std::cout << "GET command: " << value << std::endl;

    // 手动触发持久化
    redisReply* save_reply = (redisReply*)redisCommand(context, "BGSAVE");
    if (save_reply == NULL) {
        std::cerr << "BGSAVE command failed" << std::endl;
    } else {
        std::cout << "BGSAVE command: " << save_reply->str << std::endl;
        freeReplyObject(save_reply);
    }

    redisFree(context);
    return 0;
}

总结

Redis 提供了两种主要的持久化机制:RDB 和 AOF。

RDB 创建数据快照,适用于低延迟场景,但可能会丢失最近的数据;

AOF 记录每个写操作,保证数据的完整性,但增加磁盘 I/O。

可以根据需要选择使用其中一种或同时使用两种持久化机制。通过合适的配置和使用,可以确保 Redis 数据的持久化和恢复。