MongoDB和Redis作为缓存层架构

 sanesTT 发布于 2023-01-07 16:04

假设我们有一个社交网络应用程序(使用NodeJS,Express)和MongoDB作为主数据库引擎.

在大多数来自客户端的API调用(移动应用程序,Web应用程序等)中,我不想为每个请求进行复杂的查询.例如,可以从缓存层(Redis)中回复这些类型的请求.

但我的问题是如何/何时更新缓存层,因为所有写操作都在MongoDB数据库中执行,而不是在缓存层(Redis)中执行.解决这个问题的正确方法/架构是什么?

3 个回答
  • Idel方法是回写缓存方式.你可以先编写mongodb,然后写入redis.这是最常见的方式.

    另一种选择是,您可以先写redis并使用redis发送异步消息(如Q)某些线程可以使用该消息并读取它,将其写入mongoDB.

    第一个选项更容易实现.第二个选项可以支持大量的写入事务.据我所知,mongodb锁定问题尚未解决(已从全局锁定修复到数据库级别锁定)第二个选项可能相当大,以减少此类锁定争用.

    2023-01-07 16:05 回答
  • 这已经在MongoDB 开源项目的名为"Socialite"的参考架构中实现,虽然它是在Java而不是node.js所以我的答案是基于我的经验压力和负载测试代码.

    从状态源的实现中可以看出,feed有选项fanoutOnWrite缓存,它将为活动用户创建缓存(有限大小的文档),限制缓存文档中最新条目的数量(该数量是可配置的).

    该实现的关键原则是内容要求实际上与时间线高速缓存要求不同,并且对内容数据库的写入首先是所有内容的记录系统,然后更新高速缓存(如果存在).如果需要,可以异步完成此部分.该更新利用"上限数组",即更新$ slice功能,以原子方式将新值/内容推送到阵列,同时关闭最旧的一个.

    如果用户尚不存在,请不要为其创建缓存(如果他们从未登录,那么您就是在浪费精力).(可选)您可以根据某些TTL参数使缓存过期.

    当用户在登录时为其读取缓存并且不在那里时,请回到"fanoutOnRead"(即查询他们关注的所有用户内容),然后根据该结果构建缓存.

    Socialite项目将MongoDB用于所有后端,但在对其进行基准测试时,我们发现时间线缓存不需要复制或持久化,因此其MongoDB服务器仅配置为"内存"(没有日志,没有复制,没有磁盘)冲洗)这类似于你的Redis使用.如果丢失了缓存,它将"永久内容数据库""按需"重建.

    2023-01-07 16:05 回答
  • 这真的取决于你的需求,但这是一个相当普遍的:

    on_get_request
      if data_in_redis
        serve_data_from _redis
      else
        get_data_from_mongo
        set_data_in_redis
        set_expire_in_redis
        serve_data_from_memory
    

    数据有时会有点陈旧,但对大多数用例来说都没问题.在写入重要数据时,它与一些缓存失效相结合很有效:

    on_important_data
      delete_invalid_redis_keys
    

    但这一切都假定低写入,高读取和稳定的查询集.

    你的高负载用例是什么样的?

    2023-01-07 16:05 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有