草庐IT

mongodb - 在CQRS中处理大量非规范化读取模型更新

coder 2023-10-30 原文

我正在设计一个cqrs事件源系统(不是我的第一个),其中我的读取模型是非规范化的,并存储在一个读取优化文档数据库(mongodb)中。没什么特别的。现在,这个特定的读取模型是一个文档,它包含一个用户id和一个潜在的大型组数组,用户是该组的成员:

{
  "userId": 1,
  "userName": "aaron",
  "groups": [
    {
      "groupId": 1,
      "name": "group 1"
    },
    {
      "groupId": 2,
      "name": "group 2"
    }
  ]
}

可能有10万个用户是一个组的成员(就像一个例子:假设每个工作人员都是一个组的成员)。
请记住,我首先使用cqr的原因是,我需要扩展我的读操作(或者更确切地说,考虑到避免大量连接的需要,以不同的方式处理我的读操作),并且我期望有大量的写操作。这不是我使用cqr和事件源的唯一原因,但它是一个主要的催化剂。
现在我遇到的问题是,当有人更新组名时(我预测这种情况会经常发生),我的read模型需要更新。这意味着对单个数据的单个用户修改,将导致我的read store中成千上万的更新。
我很清楚我可以应用的所有技术来处理发送更新以避免时间耦合,但是我关心每个用户修改将更新的文档数量。
我读过好几个这样的答案,问的正是这种类型的问题,而且大多数答案都表明要么你需要保持平衡,要么不担心大量的更新。但在我看来,这并不是一个真正的选择。在这种类型的读取模型中确实没有平衡(对文档的任何重新建模仍然需要组名出现同样多次,不管它是如何重新建模的),简单地接受大量的更新与超级快速读取存储,因为它现在将在严重的负载下,由于不断的更新,几乎总是要排队。从本质上讲,将要发生的是去规范化过程将成为瓶颈,队列将随着时间的推移而增长(直到用户更新组名有了一些喘息时间),并且读取将变得缓慢,这是一个副作用。
在有人跳到我身上问我是否知道这个瓶颈会发生之前,我的回答是“应该发生,但显然我不能确定”。但是,基于知道在我要替换的现有系统中进行了多少更改,并且记住这不是文档数据库中需要更新的唯一类型的模型,我有充分的理由担心。正如我所说,还有其他几种读取模型-它们可能没有相同数量的更新-但是仍然会增加读取存储中的写入负载。而且,读存储只能接受这么多写操作。
我可以想出两个解决方案(一个是愚蠢的,一个不是那么愚蠢的):
在每个文档中存储一个版本,而不更新读取
事件发生时建模。然后当某个特定的
文档,我检查是否过时,以及版本是否过时(由于
一个正在进行的命令),我对该文档应用最后的更改
在储存和归还之前。然而,我的直觉告诉我
最终每个文档都会被更新,不管
这只是增加了额外的读取开销。我也没有
了解版本控制的实际工作方式
使用关系读取模型并具有单个连接。这似乎是
最明智的选择,因为我只需要更新连接表,然后
很好。但是读起来不会那么快,只是感觉有点
比纯select*from tablename方法更差。
我的问题是:
有什么标准的技术来解决这类问题吗?我提供的第二个选择是我能期望的最好的吗?
老实说,我本以为这种问题会一直出现在cqrs事件源系统中,非规范化数据需要保持同步,但在社区中似乎缺少对它的讨论,这使我相信我错过了一个明显的解决方案,或者我的rEAD模型需要改进。

最佳答案

我认为当你期望一个用户成为成千上万个组的10个成员时,你选择的模型是错误的。您需要从用户文档中删除组列表,并坚持使用关系模型,只保留组id。假设您的组需要比名称更多的属性,您将再次面临相同的问题。一次又一次。

关于mongodb - 在CQRS中处理大量非规范化读取模型更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29939028/

有关mongodb - 在CQRS中处理大量非规范化读取模型更新的更多相关文章

  1. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  2. ruby-on-rails - Rails - 子类化模型的设计模式是什么? - 2

    我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co

  3. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  4. ruby - 如何指定 Rack 处理程序 - 2

    Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack

  5. ruby-on-rails - Rails - 一个 View 中的多个模型 - 2

    我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何

  6. ruby-on-rails - 在混合/模块中覆盖模型的属性访问器 - 2

    我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah

  7. ruby-on-rails - 如何验证非模型(甚至非对象)字段 - 2

    我有一个表单,其中有很多字段取自数组(而不是模型或对象)。我如何验证这些字段的存在?solve_problem_pathdo|f|%>... 最佳答案 创建一个简单的类来包装请求参数并使用ActiveModel::Validations。#definedsomewhere,atthesimplest:require'ostruct'classSolvetrue#youcouldevencheckthesolutionwithavalidatorvalidatedoerrors.add(:base,"WRONG!!!")unlesss

  8. ruby-on-rails - form_for 中不在模型中的自定义字段 - 2

    我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢

  9. Ruby 写入和读取对象到文件 - 2

    好的,所以我的目标是轻松地将一些数据保存到磁盘以备后用。您如何简单地写入然后读取一个对象?所以如果我有一个简单的类classCattr_accessor:a,:bdefinitialize(a,b)@a,@b=a,bendend所以如果我从中非常快地制作一个objobj=C.new("foo","bar")#justgaveitsomerandomvalues然后我可以把它变成一个kindaidstring=obj.to_s#whichreturns""我终于可以将此字符串打印到文件或其他内容中。我的问题是,我该如何再次将这个id变回一个对象?我知道我可以自己挑选信息并制作一个接受该信

  10. ruby-on-rails - 使用 rails 4 设计而不更新用户 - 2

    我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它​​不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数

随机推荐