Node.js 与GraphQL数据加载器一起实现内存缓存
我正在研究向我的应用程序中添加内存缓存,比如redis,我在理解如何将它们结合在一起时遇到了一些问题Node.js 与GraphQL数据加载器一起实现内存缓存,node.js,graphql,dataloader,Node.js,Graphql,Dataloader,我正在研究向我的应用程序中添加内存缓存,比如redis,我在理解如何将它们结合在一起时遇到了一些问题 constpostloader=newdataloader(异步键=>{ //…通过ID获取多篇文章的sql代码 }) 常量postRepository={ 异步获取(id){ let post=等待cachingImplementation.get(“post:+id”) 如果(!post){ post=等待postLoader.load(id) } 回程站 } } 我理解对数据库进行批量查
constpostloader=newdataloader(异步键=>{
//…通过ID获取多篇文章的sql代码
})
常量postRepository={
异步获取(id){
let post=等待cachingImplementation.get(“post:+id”)
如果(!post){
post=等待postLoader.load(id)
}
回程站
}
}
我理解对数据库进行批量查询的必要性,但对redis服务器的查询是否也适用同样的原则
在这种情况下,如果我在同一时间内运行postRepository.get
方法10次,我将不得不向redis服务器发出10个不同的请求
这是个问题吗?我是否应该将实际的获取源(缓存或数据库)移动到dataloader解析器中,以便它不直接执行sql代码,而是首先查看缓存,然后查看数据库
比如说
cache = {
1: ...,
2: ...
}
如果我请求id为1,2,3的帖子,缓存中只有两个。因此,我必须过滤掉现有的id并在数据库中查询其余的id,或者只检查请求的id是否与返回的行长度匹配,如果不匹配,则查询数据库中的所有内容
这两种方法的缺点是什么?有更好的解决方案吗
const memo = (type, loadData) => {
return async (keys) => {
{ cacheData, notFoundKeys } = loadFromRedis(type, keys);
let data = cacheData;
if (notFoundKeys.length > 0) {
loadedData = await loadData(notFoundKeys);
populateCache(type, notFoundKeys, data);
data = addLoadedData(cacheData, loadedData);
}
return data;
}
}
const postLoaderMemoized = memo('post', async keys => {
// ... sql code to get multiple posts by ids
})
const postLoader = new DataLoader(postLoaderMemoized)
我确实浏览了Apollo文档的缓存,但是除了超时之外,它们似乎没有提供过期机制。我正在开发的应用程序允许用户创建帖子和其他实体,并对其进行编辑,因此基于时间的过期不太合适,至少乍一看不合适。我有必要手动使缓存因某些突变而无效。他们是否恰好提供了一个我错过的API?因此,Redis(数据加载器)缓存可能是一个不错的选择(我上面的解决方案是针对Redis缓存的)。我刚才提到Apollo缓存,因为它有时更适合某些应用程序。我仍然认为,除了缓存失效之外,您还需要使用Redis expirations。在ReDIS中存储所有被查看的帖子可能会很快填充你的机器内存,除非你的帖子数量有限。是的,我将使用过期超时,但是它们通常比我考虑的阿波罗缓存要长。您是否知道有哪些模式允许将“关注点”分开一点,因为我不太喜欢将缓存查询与数据库查询混合在一起,它们似乎耦合得太紧密。我们在数据访问层发出数据库请求,我们的平台(应用程序)层功能然后调用数据层访问数据库,最后,我们从API聚合层(数据加载器)调用平台层函数,最后API层调用数据加载器(有时直接调用平台层)。您可以将Redis缓存放在这些层之前,但我喜欢使用高阶函数的API聚合层缓存(在您的例子中)。我还建议您看看是否正在使用SQL,是否需要一个更有组织的数据访问层。