学习

如何使用 Redis 进行写后缓存

Prasan Kumar
作者
Prasan Kumar, Redis 技术解决方案开发人员
Will Johnston
作者
Will Johnston, 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

什么是写后缓存?#

假设您构建了一个电影流媒体应用程序。您使用 MongoDB 作为数据存储,并且在需要扩展时,您使用 Redis 实施了缓存。这使您可以大幅提高读取速度。但是,现在您在写入 MongoDB 时遇到速度缓慢的问题。

例如,您可能希望允许用户从上次停止的位置继续观看电影。这要求您存储用户在决定暂停电影时的时间戳。对于数百万用户来说,当您的需求达到峰值时,这会导致 MongoDB 速度变慢。

您需要一种方法来平滑需求峰值,让您可以快速写入数据,并在需求下降时将其持久保存到 MongoDB。您需要的是所谓的“写后模式”。

该模式很简单,您的应用程序将数据写入 Redis,然后异步地将数据写入 MongoDB。写操作排队,以便应用程序可以快速继续,并且缓存可以随着时间的推移赶上。但是,这意味着缓存和记录系统之间的数据在短时间内是不一致的。

以下是该应用程序写后模式的示意图

该模式的工作原理如下

  1. 1.应用程序读取和写入 Redis 中的数据。
  2. 2.Redis 异步地将任何更改后的数据同步到 MongoDB 数据库。

存在两种相关的写入模式,它们之间的主要区别如下

了解有关 写通模式

为什么要将 Redis 用于写后缓存?#

当您需要时,请考虑使用 Redis 和此模式

  1. 1.平滑需求峰值:在压力下,应用程序可能需要快速写入数据。如果您的应用程序需要以高速执行大量的写入操作,请考虑 Redis。Redis 的可编程性功能确保存储在缓存中的数据与数据库同步。
  2. 2.批量写入多个数据:有时频繁写入数据库会很昂贵(例如,日志记录)。在这些情况下,使用 Redis 对数据库写入进行批处理以使数据以间隔同步可能更具成本效益。
  3. 3.卸载主数据库:当大量写入操作在 Redis 上运行时,数据库负载会降低,因此我们可以在应用程序使用高峰期间将写入分散以提高性能。

使用 RedisGears 进行写后缓存的 Redis 可编程性#

提示

如果您已经熟悉 RedisGears,则可以跳过此部分。

什么是 RedisGears?#

RedisGears 是一个可编程的无服务器引擎,用于事务、批处理和事件驱动的數據處理,允许用户在存储在 Redis 中的数据上编写和运行自己的函数。

函数可以使用不同的语言实现,包括 Python 和 C,并且可以以两种方式之一由 RedisGears 引擎执行

  1. 1.批处理:由 Run 操作触发,执行是立即的,并且在现有数据上执行
  2. 2.事件:由 Register 操作触发,执行由新事件触发,并在其数据上执行

RedisGears 可以执行一些批处理类型操作

  • 对 KeySpace 中的所有键或与特定模式匹配的键运行操作,例如:
    • 使用 person: 作为前缀为所有 KeyName 添加前缀
    • 删除其值为负数的所有键
    • 将所有以 person: 开头的 KeyName 写入集合中
  • 对所有(或匹配的)键运行一组操作,其中一个操作的输出是另一个操作的输入,例如
    • 查找所有以 person: 为前缀的键(假设它们都是哈希类型)
    • 将用户的 days_old 增加 1,然后按年龄组(10-20、20-30 等)对它们求和
    • 将今天的统计数据添加到每个客户端的排序集合中,计算过去 7 天的平均值并将计算结果保存到字符串中

RedisGears 可以执行一些事件类型操作

  • RedisGears 还可以注册事件监听器,每当观察到的键发生变化时,这些监听器将触发函数执行,例如
    • 监听所有键上的所有操作,并在 KeySpace 中保存所有 KeyName 的列表
    • 监听以 I-AM-IMPORTANT: 为前缀的键的 DEL 操作,并异步地将它们转储到“已删除的键”日志文件中
    • 监听以 player: 为前缀的键的得分元素的所有 HINCRBY 操作,并在得分达到 1000 时同步更新用户的等级

如何使用 RedisGears?#

运行 Docker 容器

docker run -p 6379:6379 redislabs/redisgears:latest

对于一个非常简单的示例,它列出了 Redis 数据库中所有以 person: 为前缀的键,请创建以下 Python 脚本并将其命名为 hello_gears.py

gb = GearsBuilder() gb.run('person:*')

执行您的函数

docker exec -i redisgears redis-cli RG.PYEXECUTE "`cat hello_gears.py`"

使用 gears-cli#

gears-cli 工具提供了一种更轻松的方式来执行 RedisGears 函数,尤其是当您需要传递一些参数时。

它用 Python 编写,可以使用 pip 安装。

pip install gears-cli
gears-cli hello_gears.py REQUIREMENTS rgsync

用法

gears-cli --help
usage: gears-cli [-h] [--host HOST] [--port PORT]
[--requirements REQUIREMENTS] [--password PASSWORD] path [extra_args [extra_args ...]]

RedisGears 参考#

使用 Redis 和 MongoDB 在 NodeJS 应用程序中进行写后缓存#

演示应用程序#

本教程中剩余部分使用的演示应用程序展示了一个具有基本创建、读取、更新和删除 (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

为了使用电影应用程序演示这种模式,假设用户打开弹出窗口以添加新电影。

应用程序不是立即将数据存储在 MongoDB 中,而是将更改写入 Redis。在后台,RedisGears 会自动将数据与 MongoDB 数据库同步。

使用写后模式进行 Redis 编程#

在使用写后模式(将数据从 Redis 同步到 MongoDB)之前,开发人员需要将一些代码(例如我们示例中的 python)加载到 Redis 服务器。Redis 服务器有一个 RedisGears 模块,可以解释 python 代码并将数据从 Redis 同步到 MongoDB。

加载 Python 代码比听起来容易。只需替换 Python 文件中的数据库详细信息,然后将文件加载到 Redis 服务器即可。

创建 Python 文件(如下所示,以及在线可用)。然后更新 MongoDB 连接详细信息、数据库、集合和要同步的主键名称。

movies-write-behind.py
# Gears Recipe for a single write behind

# import redis gears & mongo db libs
from rgsync import RGJSONWriteBehind, RGJSONWriteThrough
from rgsync.Connectors import MongoConnector, MongoConnection

# change mongodb connection (admin)
# mongodb://usrAdmin:passwordAdmin@10.10.20.2:27017/dbSpeedMernDemo?authSource=admin
mongoUrl = 'mongodb://usrAdmin:passwordAdmin@10.10.20.2:27017/admin'

# MongoConnection(user, password, host, authSource?, fullConnectionUrl?)
connection = MongoConnection('', '', '', '', mongoUrl)

# change MongoDB database
db = 'dbSpeedMernDemo'

# change MongoDB collection & it's primary key
movieConnector = MongoConnector(connection, db, 'movies', 'movieId')

# change redis keys with prefix that must be synced with mongodb collection
RGJSONWriteBehind(GB,  keysPrefix='MovieEntity',
                  connector=movieConnector, name='MoviesWriteBehind',
                  version='99.99.99')
什么是 REDISGEARS 菜谱?

RedisGears 函数的集合以及它们可能具有的任何依赖项,这些依赖项实现高级功能目的被称为 菜谱。例如:上面 python 代码中的“RGJSONWriteBehind”函数

有两种方法可以将该 Python 文件加载到 Redis 服务器中

  1. 1.使用 gears 命令行界面 (CLI)

有关 Gears CLI 的更多信息,请参见gears-clirgsync

# install
pip install gears-cli
# If python file is located at “/users/tom/movies-write-behind.py”
gears-cli --host <redisHost> --port <redisPort> --password <redisPassword> run /users/tom/movies-write-behind.py REQUIREMENTS rgsync pymongo==3.12.0

2. 使用 Redis 命令行中的 RG.PYEXECUTE。

有关更多信息,请参见RG.PYEXECUTE

# Via redis cli
RG.PYEXECUTE 'pythonCode' REQUIREMENTS rgsync pymongo==3.12.0

RG.PYEXECUTE 命令也可以从 Node.js 代码执行(请咨询示例 Node 文件以获取更多详细信息)

Redis Gears 与 MongoDB 同步中查找更多示例。

使用 RedisInsight 验证写后模式#

提示

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

下一步是验证 RedisGears 是否正在 Redis 和 MongoDB 之间同步数据。

使用 Redis CLI 插入一个以前缀(在 Python 文件中指定)开头的键

接下来,确认 JSON 也已插入 MongoDB 中。

您也可以检查 RedisInsight 以验证数据是否通过流传输到其使用者(例如 RedisGears)。

所有这些如何与演示应用程序一起工作?下面是一段用于插入电影的代码片段。一旦数据被写入 Redis,RedisGears 就会自动将其同步到 MongoDB。

之前(使用 MongoDB)
...
//(Node mongo query)
if (movie) {
  //insert movie to MongoDB
  await db.collection("movies")
           .insertOne(movie);
}
...
之后(使用 Redis)
...
//(Redis OM Node query)
if (movie) {
  const entity = repository.createEntity(movie);
  //insert movie to Redis
  await moviesRepository.save(entity);
}
...

准备好使用 Redis 进行写后缓存?#

现在您知道如何使用 Redis 进行写后缓存。可以使用不同的策略/模式在需要的地方逐步采用 Redis。有关缓存主题的更多资源,请查看下面的链接

其他资源#