学习

如何使用 Redis 实现缓存预取策略

Will Johnston
作者
Will Johnston, Redis 开发者增长经理
Prasan Kumar
作者
Prasan Kumar, Redis 技术解决方案开发者
GITHUB 代码

以下是用于克隆本教程中使用的应用程序源代码(前端和后端)的命令

git clone https://github.com/redis-developer/ebook-speed-mern-frontend.git

git clone https://github.com/redis-developer/ebook-speed-mern-backend.git

什么是缓存预取?#

缓存预取是数据库管理系统 (DBMS) 中使用的一种技术,通过在查询明确请求数据之前预测并从存储子系统获取数据,从而提高查询性能。

缓存预取主要有三种策略

  1. 1.顺序预取:这种方法预测数据将按顺序访问,例如扫描表或索引时。它会预取序列中的下一组数据块或页面,以确保在需要时它们在缓存中可用。
  2. 2.基于查询模式的预取:一些数据库系统可以分析过去的查询模式,预测未来可能访问哪些数据。通过分析这些模式,DBMS 可以预取相关数据,并在执行类似查询时将其在缓存中准备好。
  3. 3.基于数据访问模式的预取:在某些情况下,数据访问模式可以从应用程序逻辑或模式设计中推导出来。通过理解这些模式,数据库系统可以预取很快可能被访问的数据。

本教程将介绍第三种策略,即 基于数据访问模式的预取

想象您正在构建一个电影流媒体平台。您需要能够为用户提供一个仪表盘,让他们能够快速找到想看的电影。您有一个庞大的电影数据库,并按原产国、类型、语言等进行分类。这些数据变化不频繁,并且在您的应用程序中以及其他数据中经常被引用。这种生命周期长、变化不频繁的数据称为“主数据”。

开发者面临的一个持续挑战是快速创建、读取、更新和删除主数据。您可以将主数据存储在记录系统(如 SQL 数据库或文档数据库)中,然后使用 Redis 作为缓存来加速这些数据的查找。这样,当应用程序请求主数据时,主数据将不再来自记录系统,而是从 Redis 提供。这被称为“主数据查找”模式。

从开发者的角度来看,“主数据查找”是指在业务事务、应用程序设置以及软件检索信息的任何其他方式中访问主数据的过程。主数据查找的示例包括获取用户界面 (UI) 元素的数据(如下拉对话框、选择值、多语言标签)、获取常量、用户访问控制、主题以及其他产品配置。

下图展示了使用 Redis 并以 MongoDB 作为记录系统来预取主数据的数据流图。

获取数据的步骤如下

  1. 1.在应用程序启动时从 MongoDB 读取主数据,并将数据副本存储在 Redis 中。这会预先缓存数据,以便快速检索。使用脚本或 cron 作业定期将最新的主数据复制到 Redis。
  2. 2.应用程序请求主数据。
  3. 3.主数据将从 Redis 而非 MongoDB 提供。

为什么应该使用 Redis 进行缓存预取#

  1. 1.高速提供预取数据:顾名思义,几乎每个应用程序都需要访问主数据或其他常用数据。使用 Redis 预先缓存这些频繁访问的数据,可以高速将其提供给用户。
  2. 2.支持海量表:主表通常有数百万条记录。在其上进行搜索可能会导致性能瓶颈。使用 Redis 对大型表执行实时搜索,以亚毫秒级响应提高性能。
  3. 3.推迟昂贵的硬件和软件投资:通过使用 Redis,推迟昂贵的基础设施增强。无需请财务总监批准,即可获得性能和扩展优势。
提示

如果您使用 Redis Cloud,由于其对 JSON 和搜索的支持,缓存预取会更容易。您还可以获得实时性能、高可扩展性、弹性和容错等附加功能。您还可以利用高可用性功能,例如 Active-Active 地理冗余。

在 Node.js 应用程序中使用 Redis 和 MongoDB 进行缓存预取#

演示应用程序#

本教程其余部分使用的演示应用程序展示了一个具有基本增删改查 (CRUD) 操作的电影应用程序。

电影应用程序仪表盘顶部有一个搜索部分,中间是电影卡片列表。浮动的加号图标在用户选中时会显示一个弹窗,允许用户输入新的电影详细信息。搜索部分有一个文本搜索栏以及文本搜索和基本(即表单式)搜索之间的切换链接。每张电影卡片都有编辑和删除图标,当鼠标悬停在卡片上时会显示这些图标。

GITHUB 代码

以下是用于克隆本教程中使用的应用程序源代码(前端和后端)的命令

git clone https://github.com/redis-developer/ebook-speed-mern-frontend.git

git clone https://github.com/redis-developer/ebook-speed-mern-backend.git

演示应用程序中使用的某些字段用作主数据,包括电影语言、国家、类型和评分。它们是主数据,因为几乎每个应用程序事务都需要它们。例如,当想要添加新电影的用户点击电影应用程序的加号图标时出现的弹窗(如下所示)。该弹窗包含国家和语言的下拉菜单。在这种情况下,Redis 存储并提供这些值。

使用 Redis 和 MongoDB 预取数据#

下面的代码片段使用 Redis OM for Node.js 库预取 MongoDB JSON 文档并将其存储在 Redis 中(以 JSON 格式)。

async function insertMasterCategoriesToRedis() {
  ...
  const _dataArr = await getMasterCategories(); //from MongoDb
  const repository = MasterCategoryRepo.getRepository();

  if (repository && _dataArr && _dataArr.length) {
    for (const record of _dataArr) {
      const entity = repository.createEntity(record);
      entity.categoryTag = [entity.category]; //for tag search
      //adds JSON to Redis
      await repository.save(entity);
    }
  }
  ...
}

async function getMasterCategories() {
  //fetching data from MongoDb
  ...
  db.collection("masterCategories").find({
    statusCode: {
      $gt: 0,
    },
    category: {
      $in: ["COUNTRY", "LANGUAGE"],
    },
  });
  ...
}

您还可以查看 RedisInsight 来验证 JSON 数据是否已插入,如下所示:

提示

RedisInsight 是用于查看 Redis 中数据的免费 Redis GUI。 点击此处下载。

从 Redis 查询预取数据#

在使用 Redis 进行预取之前,应用程序通过搜索静态数据库 (MongoDB) 来检索电影的国家和语言值。随着越来越多的人开始使用该应用程序,数据库因查询过多而过载。应用程序变得缓慢且无响应。为了解决这个问题,应用程序被修改为使用 Redis 存储主数据。下面的代码片段展示了应用程序如何从 Redis 查询主数据,特别是下拉菜单的国家和语言值。

*** With Redis ***
*** Redis OM Node query ***
function getMasterCategories() {
  ...
  masterCategoriesRepository
    .search()
    .where("statusCode")
    .gt(0)
    .and("categoryTag")
    .containOneOf("COUNTRY", "LANGUAGE");
  ...
}

准备好使用 Redis 进行缓存预取了吗?#

在本教程中,您学习了如何通过“主数据查找”示例使用 Redis 进行缓存预取。虽然这是 Redis 在应用程序中的一种使用方式,但也可以根据需要在需要的地方逐步采用 Redis 以及其他缓存策略/模式。有关缓存主题的更多资源,请查看以下链接

附加资源#

使用 Redis 进行缓存

通用