Redis 的持久化机制详解

前言

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

- ---- --- ---------- ----- ---------
---- --- -  - --- --- --------- --- ------------
---- --- -- - --- --- -------- -- - --- ------------
---- -- ----- - --- -- ------ ----- - --- ------------

---------- -------- - --------------- --------
--- --------------------- - -------------

AOF

- ---- --- ---------------------------
---------- --
- ---------------------- --------------
-------------- ----------------
------------------------- --
--------------------------- ---
------------------------- ----

在实际应用过程中,需要根据业务需求来选择 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


猜你喜欢

  • 使用 Enzyme 构建 React 组件测试驱动开发流程

    在前端开发中,测试驱动开发(TDD)已经成为了不可或缺的一部分。它可以大幅度提高代码质量、减少 bug,同时对开发者的思考方式也有很大的借鉴意义。在 React 开发中,Enzyme 是一个非常流行的...

    1 年前
  • CSS Flexbox 实现响应式布局中的圣杯布局

    什么是响应式布局? 响应式布局是指设计一个能够自适应不同设备屏幕大小的网页布局。随着不同设备的普及,如手机、平板电脑以及桌面电脑等,让网页具有响应式布局使得网页在任何尺寸的屏幕上都可以呈现出适当的布局...

    1 年前
  • 使用 Chai 中 Should 部分代替 Expect 部分进行测试示例

    在前端开发中,单元测试是很重要的一环。在单元测试中,对于测试框架的选择是非常关键的,而在测试框架中,对于断言的选择也非常重要。Chai 是一个非常流行的测试框架,它提供了三种不同的断言风格:expec...

    1 年前
  • Server-sent Events 基础知识

    Server-sent events(SSE)是一种服务器推送技术,可以用于实现实时通信等功能。在前端开发中,使用 SSE 可以方便地实现部分页面的实时更新,如聊天室、股票行情等。

    1 年前
  • 更好的响应式设计:使用 viewport 单位

    在移动设备的普及和网页设计的多样化背景下,响应式设计成为了现代网页设计的必备技能。而 viewport 单位(viewport units)作为 CSS3 新增的一种单位,在响应式设计中有着广泛的应用...

    1 年前
  • Node.js 中 cluster 模块用法介绍

    在 Node.js 中,cluster 模块是处理多进程的重要工具。它允许 Node.js 应用程序在多个进程之间共享端口以充分利用多核处理器的优势,提供更高效的性能和更快的响应时间。

    1 年前
  • 如何在 React 中使用 SVG

    SVG 是一种矢量图形格式,可以实现任何复杂的图形效果,同时还支持交互和动画。React 中使用 SVG 可以轻松地控制图形,实现更好的可维护性和可复用性。本文将介绍如何在 React 中使用 SVG...

    1 年前
  • Jest 测试框架:如何进行增量测试

    前言 在前端开发中,我们经常需要进行测试以确保代码的质量和可靠性。而 Jest 是一个流行的 JavaScript 测试框架,它具有简单易学、快速运行、可扩展等优点。

    1 年前
  • ES8 新特性学习笔记

    1. 异步函数 异步函数是 ES8 中最引人注目的新特性之一。它使得异步操作更加简单、易读,并且避免了回调地狱(Callback hell)。 1.1 异步函数的基本用法 异步函数使用 async 关...

    1 年前
  • TypeScript 中如何处理异步文件读写操作

    TypeScript 是一种 JavaScript 的超集,可以在编写 JavaScript 代码时添加类型,并且可以编译成 JavaScript 代码。在前端开发中,TypeScript 能够提高代...

    1 年前
  • 如何在 Express.js 中使用 GraphQL

    什么是 GraphQL GraphQL 是一种用于 API 的查询语言,它可以替代或补充传统的 REST 架构。GraphQL 的主要优点包括: 可以减少网络请求次数,提高性能 可以根据需要请求数据...

    1 年前
  • ECMAScript 2019 中的字符串模板:使用 `${}` 实现变量替换

    在 JavaScript 的历史上,字符串拼接一直都是一项非常常见的操作。在早期的版本中,我们通常使用加号 (+) 对多个字符串进行拼接,例如: --- ---- - ------ --- --- -...

    1 年前
  • RxJS 实战:如何使用 zip 操作符合并多个 Observable?

    概述 RxJS 是一个基于观察者模式的 JavaScript 库,用于处理异步数据流。其核心思想是将数据流视为一个可观察的序列,并通过一系列操作符对序列进行操作和变换。

    1 年前
  • 如何在 Next.js 中使用 React Context?

    React Context 是一个在组件之间共享数据的深度传递技术。使用 React Context,我们可以在应用程序中消除深度传递数据所带来的繁琐问题。在本文中,我们将探讨如何在 Next.js ...

    1 年前
  • Kubernetes 通过 NodeIP 访问 Service 的问题解决

    在 Kubernetes 中,一般通过 Service 来访问 Pod,然而当 ClusterIP 不能满足我们的需求时,有时需要通过 NodeIP 访问 Service。

    1 年前
  • 使用 PM2 启动应用时出现“Module not found”错误的解决方案

    背景 PM2 是一个跨平台的进程管理器,可以帮助我们启动、停止、重启、监控应用程序。然而,在使用 PM2 启动应用时,有时会出现“Module not found”错误,导致应用无法启动。

    1 年前
  • Sequelize 中如何更新多条记录数据

    Sequelize 是一个基于 Node.js 的 ORM 框架,可以方便地将 JavaScript 对象映射到数据库中的关系表。在实际的开发中,我们经常需要更新多条记录数据。

    1 年前
  • Angular 中如何使用 ng-bootstrap 和 ngx-bootstrap

    在 Angular 开发中,ui 库扮演着重要的角色,它们可以让开发者更加高效地构建应用,减少样式的开发量。在 ui 库之中,Bootstrap 是颇受欢迎的一种 ui 库,而 ng-bootstra...

    1 年前
  • Vue.js 中使用 transition 过渡动画效果及注意事项

    在使用 Vue.js 构建Web应用程序时,过渡动画效果是一个非常重要的组成部分。Vue.js提供了一个transition组件,使我们可以很容易地为我们的应用程序添加简单的过渡动画效果。

    1 年前
  • ES12 之后的变化:可选的链式调用操作符 (Optional Chaining) 和 Nullish 合并操作符 (Nullish Coalescing Operator)

    介绍 ES12 引入了两个新的操作符,可选的链式调用操作符 (Optional Chaining) 和 Nullish 合并操作符 (Nullish Coalescing Operator)。

    1 年前

相关推荐

    暂无文章