学习

加速 MEAN 和 MERN 堆栈应用的 3 种设计模式

以下是电子书的摘录。 点击此处下载完整电子书。

引言#

如果在设计和构建软件时不关注性能,您的应用在投入生产时可能会遇到严重的瓶颈。

随着时间的推移,开发社区已经学习了许多常见技术,它们可以作为可靠的设计模式来解决常见问题,包括应用性能问题。

那么什么是设计模式?它们是解决软件系统中重复出现的设计问题的推荐实践。设计模式包含四个部分:名称、问题描述(模式适用的特定条件集)、解决方案(解决问题的最佳通用策略)和一系列结果。

MEAN 堆栈和 MERN 堆栈是构建 Node.js 应用的两种流行开发堆栈。MEAN 堆栈由 MongoDB 数据库、Express 和 Angular.js 框架以及 Node.js 组成。它是一个纯 JavaScript 堆栈,帮助开发者创建网站或应用的每个部分。相比之下,MERN 堆栈由 MongoDB、Express 和 ReactJS 框架以及 Node.js 组成。

这两种堆栈都能很好地工作,这也是它们受欢迎的原因。但这并不意味着生成的软件能够尽可能快地运行——或者达到所需的运行速度。

在这篇文章中,我们分享了一种开发者与 Redis 结合使用来提升 MEAN 和 MERN 堆栈应用性能的流行设计模式:主数据查找模式 (master data-lookup pattern)。我们将详细解释这种模式,并提供概览、典型用例和代码示例。我们的目的是帮助您理解何时以及如何在自己的软件开发中使用这种特定模式。电子书还包含其他模式,例如缓存旁路模式 (The cache-aside pattern) 和写后模式 (The write-behind pattern)

构建电影应用#

本教程其余部分使用的演示应用展示了一个电影应用,包含基本的创建、读取、更新和删除 (CRUD) 操作。

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

本教程使用了一个通过以下工具构建的 GitHub 示例演示

  • 前端: ReactJS (18.2.0)
  • 后端: Node.js (16.17.0)
  • 数据库: MongoDB
  • 缓存和数据库: Redis stack (使用 Docker)
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

主数据查找模式 (master data-lookup pattern)#

要从 Redis 提供主数据,请从 MongoDB 预加载数据。

  1. 1.在应用启动时从 MongoDB 读取主数据,并在 Redis 中存储一份副本。这会预缓存数据以便快速检索。使用脚本或 cron 作业重复将主数据复制到 Redis。
  2. 2.应用请求主数据。
  3. 3.主数据将从 Redis 提供,而不是由 MongoDB 提供。

用例#

在需要以下情况时考虑此模式:

  • 高速提供主数据:根据定义,几乎每个应用都需要访问主数据。使用 Redis 预缓存主数据可以高速将其交付给用户。
  • 支持海量主表:主表通常包含数百万条记录。在其中搜索可能导致性能瓶颈。使用 Redis 对主数据执行实时搜索,以亚毫秒级的响应提升性能。
  • 推迟昂贵的硬件和软件投资:通过使用 Redis 推迟成本高昂的基础设施升级。在不增加财务支出的情况下获得性能和扩展优势。

演示#

下图展示了一种适用于主数据查找的典型 UI 界面。负责此应用的开发者会将某些字段视为主数据,包括电影语言、国家/地区、类型和评分,因为这些字段是常见应用事务所需的。

考虑一下当用户想添加新电影并点击电影应用加号图标时弹出的对话框。该弹出窗口包含国家/地区和语言的下拉菜单。在此演示中,Redis 加载了这些值。

代码#

下面的两个代码块展示了从 MongoDB 和 Redis 中获取主数据(用于加载国家/地区和语言下拉值)的查询。

以前,如果应用使用 MongoDB,它会搜索静态数据库来检索电影的国家/地区和语言值。如果从持久存储中读取,这可能会耗时,而且如果信息是静态的,效率也很低。

*** BEFORE (MongoDB)***
*** MongoDB regular search query ***
function getMasterCategories() {
  ...
  db.collection("masterCategories").find({
    statusCode: {
      $gt: 0,
    },
    category: {
      $in: ["COUNTRY", "LANGUAGE"],
    },
  });
  ...
}

相反,代码块中的“之后”视图显示,只需几行代码即可访问主数据——且响应时间快得多。

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

下载电子书#

注意到这里的模式了吗?主数据查找模式并不是唯一可以用来提升应用性能的设计模式。

我相信您一定渴望了解更多,所以点击此处下载完整电子书。