在 GraphQL 服务器设置中何时使用 Redis 以及何时使用 DataLoader
Posted
技术标签:
【中文标题】在 GraphQL 服务器设置中何时使用 Redis 以及何时使用 DataLoader【英文标题】:When to use Redis and when to use DataLoader in a GraphQL server setup 【发布时间】:2019-12-22 04:13:36 【问题描述】:我已经在 GraphQL 服务器上工作了一段时间,虽然我了解大部分方面,但我似乎无法掌握缓存。
谈到缓存,我看到提到的 DataLoader 和 Redis 都提到了,但我不清楚什么时候应该使用它们以及应该如何使用它们。
我认为 DataLoader 更多地用于字段级别来解决 n+1 问题?那我猜Redis的水平更高了?
如果有人能对此有所了解,我将不胜感激。
谢谢。
【问题讨论】:
【参考方案1】:DataLoader主要是一种将请求批处理到某个数据源的方法。但是,它确实可以选择基于每个请求 使用缓存。这意味着,在执行相同的 GraphQL 查询时,您只能获取一次特定实体。例如,我们可以同时调用load(1)
和load(2)
,它们将被批处理到一个请求中以获取两个匹配这些id 的实体。如果稍后在执行同一个请求时另一个字段调用load(1)
,那么该调用将简单地返回我们之前获取的ID为1
的实体,而不向我们的数据源发出另一个请求。
DataLoader 的缓存特定于单个请求。即使同时处理两个请求,它们也不会共享一个缓存。 DataLoader 的缓存没有过期时间——也没有必要,因为一旦请求完成,缓存就会被删除。
Redis 是一种键值对存储,用于缓存、队列、PubSub 等。我们可以使用它来提供response caching,这将让我们有效地绕过一个或多个字段的解析器并使用缓存值代替(直到它过期或失效)。我们可以将其用作 GraphQL 与数据库、API 或其他数据源之间的缓存层——例如,RESTDataSource 就是这样做的。在实现订阅时,我们可以将其用作a PubSub implementation 的一部分。
DataLoader 是一个小型库,用于解决特定问题,即向数据源生成过多请求。使用 DataLoader 的替代方法是在根级别获取您需要的所有内容(基于请求的字段),然后让默认解析器逻辑处理其余部分。 Redis 是一种具有多种用途的键值对存储。您是否需要其中之一,或两者都需要,取决于您的特定业务案例。
【讨论】:
数据加载器确实有缓存失效机制。查看官方文档中的.clear(id)
、clearAll()
api。
我看到了你的其他回复,我明白你所说的“个人请求”是什么意思。在一个单一的查询中可能会有突变,我想这是你使用clear
api的时候。但我想知道你不能也将数据加载器缓存用于多个请求吗?它可能具有与 redis 缓存类似的缓存效果(我知道 redis 缓存了整个响应。但主要瓶颈是从 db 中获取数据,这些数据都缓存在数据加载器中。它也更灵活。如果请求发生轻微变化,请使用 redis重新获取)
@SihoonKim 感谢您指出这些方法,我已经更新了答案。请参阅this issue 以了解有关您所指内容的更多讨论。正如我在原始答案中所说,Redis 并非专门用于响应缓存——它只是一个键值存储,这意味着它可以用于许多事情。如果您想要一种缓存单个查询结果的方法,您也可以使用它。底线是 DataLoader 不打算在多个请求中使用。你能做到吗?当然。但是,它不会很好地扩展。以上是关于在 GraphQL 服务器设置中何时使用 Redis 以及何时使用 DataLoader的主要内容,如果未能解决你的问题,请参考以下文章
使用 Express-GraphQL 和 React-Apollo 订阅 GraphQL
redis.conf中bind绑定IP不对,redis集群创建节点的时候,报错|redi群集密码设置