如何使用 Redis 优化 Graphql

Posted

技术标签:

【中文标题】如何使用 Redis 优化 Graphql【英文标题】:how to optimize Graphql with Redis 【发布时间】:2018-05-24 03:47:14 【问题描述】:

目前我有 mongodb 的 graphql,现在我想添加 redis 层来优化服务器响应时间。

假设我有这样的架构:

type Query
  book(id: ID):Book

type Book
  # simple fields direct come from mongodb collection Book
  A
  B
  C

  # fields with values generated from simple fields
  X
  Y
  Z

  # fields with aggregated data from other db collections e.g avg/min/max
  L
  M
  N


问题来了:我应该在 Redis 中存储什么样的数据?

1) 来自 db 的字符串化原始文档,以 ID 为键

2) 将每个计算字段放入redis的hash值中,每个字段使用redis中的HGET

以下是我对上述选项的担忧:

1) ABC/XYZ 字段应该没问题,但 LMN 会导致额外的数据库访问

2) 查询 Book 的所有字段时,每个字段都会有一个 HGET,而且大多数只是简单的值,可能会浪费时间发起太多请求?

【问题讨论】:

您是否在 GraphQL 解析器方法中使用批处理和缓存?如果没有,那么您需要从那里开始 - 您将为此使用 Facebook 的 DataLoader 库。这是一个示例:github.com/kriasoft/nodejs-api-starter 请参阅 src/Context.js - 数据加载器列表,可以在解析函数中使用,如下所示:ctx.bookById.load(123) 【参考方案1】:

一般来说,缓存的想法是将数据以您想要的方式放置。但是,Redis 是在内存中的,而且内存并不便宜——所以我不会在序列化开销上浪费内存。话虽如此,只需将值放入 Redis 哈希(每个字段一个值)。

关于在请求上浪费时间(我假设您的意思是 Redis),这不是一个大问题。 Redis 的底层协议非常高效,你可以这样做(给定书籍 ID 'book1234'):

HGETALL book1234得到一切 HGET book1234 A B C X Y Z L M N(或您选择的字段)。 HGET 是可变参数(从 Redis 4 开始),因此您可以只提供所需的字段。

最后,如果您有能力安装 Redis 模块,您可能需要查看ReJSON,它允许对 JSON 数据进行本地处理 - 允许您从结构中挑选数据。这可能是两全其美。

【讨论】:

以上是关于如何使用 Redis 优化 Graphql的主要内容,如果未能解决你的问题,请参考以下文章

如何在 GraphQL 解析器中添加用于缓存的 redis 客户端

如何使用 apollo 服务器对 graphQl 中的数据进行排序?

如何在没有 useMutation 的情况下在 Next.js 中使用 GraphQL 突变

redis 如何做内存优化?

源码讲解Redis中内存优化的数据结构是如何设计的

源码讲解Redis中内存优化的数据结构是如何设计的