草庐IT

.net - 无架构数据缓存:NoSQL或其他替代方案?

coder 2023-11-01 原文

我正在评估一些nosql实现(目前是ravendb和mongodb),作为解决涉及存储/检索无模式数据的特定需求集的一种方法。我想得到一些关于nosql是否是我应该关注的方向的反馈,或者是否还有其他(可能更简单的)选项。
本质上,我们有一个软件产品,它(除其他外)定义了一个基本的领域模型,这个模型由几个相关的实体组成,每个实体都有许多属性(键/值)。当我们发布给客户时,我们与他们一起设置属性和值,这本质上是系统的配置。这是相当简单的,因为设计是预先知道的,所以我们不需要任何动态的东西来实现这一点并使其执行(我们将使用RDBMS)。属性不是预先知道的,但是这不是一个问题,因为系统的这一部分基本上是围绕一个属性模型。
问题是,对于不同的客户,在我们发布并投入生产之后,我们发现我们需要查询在编译和发布代码时(以及在为客户配置属性之前)一无所知的特定属性数据集。d从属性映射生成数据,我们可以存储(我们不知道前面的结构),然后以我们无法预料的方式查询存储的数据。现在的想法是,我们可以创建钩子,在处理过程中被击中,并允许我们插入库(可能通过m它创建数据以便存储,然后在需要时查询(不用于报告——通常用于创建其他数据/属性)。
(请注意,创建钩子和插件库是一个单独的问题,不打算成为这个问题的一部分。)
一个常见的场景可能是:“我想知道xxx在过去的10天内发生了多少次”;“所以我会创建一个可以识别xxx已经发生的插件,并用日期/时间将其写入一个数据存储中。;“然后我会创建另一个插件(可能在同一个dll中),它将执行查询,并向模型添加一个名为“countofxxxinlast10days”的属性。
γ
另一种情况可能是创建可配置的查找。因此,我可能有一个在启动时运行的插件来创建/更新可以将一个属性值转换为另一个属性值的查找数据表,或者(更可能)将转换为查找值的值范围。因此转换插件可能会添加一个包含以下列的表:bottom_value、top_value、multiplier,查询插件会使用一个属性值来查询该表,比如“从表中选择multiplier,其中[attribute_value]位于bottom_value和top_value之间”。乘法器”。
在某些情况下,旧数据可以在指定的时间段后清除。在上面描述的第一个场景中,可能需要从存储/缓存中删除超过10天的数据。
在其他情况下,数据需要永久保存,就像上面的第二个场景一样。有可能这些数据只是在启动时重新创建,而不是保存在永久存储中。
附加要求:
可以备份数据存储/缓存
并在联机时恢复
可以从
发生故障时的最后一次备份
数据可以在诸如machine之类的事件中生存
重新启动
经验证/生产测试的技术
我们现在非常致力于.NET平台,因此任何选项都必须有一个可靠的.NET客户机/API。

最佳答案

有三种可能的选择,各有利弊。
重用rdbms
您已经将实体存储在关系数据库中。您可以将未定义的属性存储在一个额外的表中,该表有一个KeyValue列,以及一个EntityId列,该列引用属性所属的实体。基本上,您将使用数据库的一部分作为键值存储。
优势:
所有数据都存储在一个数据库中,这意味着:
您可以在单个查询中检索实体及其所有属性,
您的应用程序不那么复杂,因为它只需要与单个数据库交互。
您可以获得关系数据库的所有acid优势。
缺点:
关系数据库不是为关键值存储而构建的,因此您可能会遇到性能问题。但是,我希望性能影响最小,除非您计划存储非常大量的属性。
使用键值存储
键值存储(如RedisRiak或更高级的Apache Cassandra)是为存储键值对而优化的(这并不奇怪…)。您可以在rdbms旁边使用一个键值存储,专用于存储属性,同时将实体保存在rdbms中。
优势:
比rdbms的性能更好,特别是对于大量数据。
更易于扩展,因为它们不受酸性物质的限制。
缺点:
没有保证的acid属性,而是所谓的eventual consistency,这意味着存储的数据在服务器之间可能并不总是一致的。不过,如果你要扩大规模,你只需要处理这个问题。此外,大多数关键值存储允许您调整其对一致性的严格性,以帮助解决此问题。
应用程序将在两个独立的数据库上运行,这会增加应用程序的复杂性。
使用文档数据库
您可以使用文档数据库仅存储属性。但您也可以冒险将所有内容存储在文档数据库中,包括实体。
优势:
所有数据都存储在一个数据库中,这意味着:
您可以在单个操作中检索实体及其所有属性,就像将整个实体(包括其属性)存储在单个文档中一样。
您的应用程序不那么复杂,因为它只需要与单个数据库交互。
更易于扩展,因为它们不受酸性物质的限制。
文档数据库不仅限于键值,所以如果您需要存储更复杂的属性,您已经可以使用了。
缺点:
没有acid保证,就像键值存储一样。不过,大多数文档数据库都可以调整以克服一致性问题。
不理解实体之间的关系,如在关系数据库管理系统中。关系模型是规范化的,而文档是非规范化的,以克服有许多关系。这可能是也可能不是一个很大的缺点,这取决于您的确切域模型。
成熟的文档数据库技术
Apache CouchDB使用它并从堆栈溢出社区接收quite a list of applications。它有一些positive feedback,但我不能告诉你这些司机有多成熟。
MongoDB有一个相当令人印象深刻的drivers for .NET。有三个主要的list of production employments可用,它们似乎都是drivers for .NET的。
RavenDB对.NET的支持非常好,因为它是为.NET平台设计的。但是,我还没有找到运行在ravendb上的大型生产环境的示例。不过,我认为这绝对值得一探究竟。
我对它们在生产环境中的任何一个都没有多少实际操作经验,所以我不知道它们到底有多容易备份/恢复。但是,考虑到这些nosql系统没有rdbms系统那么死板,我想它们应该比rdbms更容易在不停机的情况下进行备份/恢复。

关于.net - 无架构数据缓存:NoSQL或其他替代方案?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3478703/

有关.net - 无架构数据缓存:NoSQL或其他替代方案?的更多相关文章

  1. ruby - 其他文件中的 Rake 任务 - 2

    我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时

  2. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

    作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

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

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

  4. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  5. ruby - 在 jRuby 中使用 'fork' 生成进程的替代方案? - 2

    在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',

  6. ruby - 如何模拟 Net::HTTP::Post? - 2

    是的,我知道最好使用webmock,但我想知道如何在RSpec中模拟此方法:defmethod_to_testurl=URI.parseurireq=Net::HTTP::Post.newurl.pathres=Net::HTTP.start(url.host,url.port)do|http|http.requestreq,foo:1endresend这是RSpec:let(:uri){'http://example.com'}specify'HTTPcall'dohttp=mock:httpNet::HTTP.stub!(:start).and_yieldhttphttp.shou

  7. ruby - Ruby 有 `Pair` 数据类型吗? - 2

    有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳

  8. ruby - 如何在 Ubuntu 中清除 Ruby Phusion Passenger 的缓存? - 2

    我试过重新启动apache,缓存的页面仍然出现,所以一定有一个文件夹在某个地方。我没有“公共(public)/缓存”,那么我还应该查看哪些其他地方?是否有一个URL标志也可以触发此效果? 最佳答案 您需要触摸一个文件才能清除phusion,例如:touch/webapps/mycook/tmp/restart.txt参见docs 关于ruby-如何在Ubuntu中清除RubyPhusionPassenger的缓存?,我们在StackOverflow上找到一个类似的问题:

  9. ruby-on-rails - 更好的替代方法 try( :output). try( :data). try( :name)? - 2

    “输出”是一个序列化的OpenStruct。定义标题try(:output).try(:data).try(:title)结束什么会更好?:) 最佳答案 或者只是这样:deftitleoutput.data.titlerescuenilend 关于ruby-on-rails-更好的替代方法try(:output).try(:data).try(:name)?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.c

  10. ruby-on-rails - Ruby on Rails 计数器缓存错误 - 2

    尝试在我的RoR应用程序中实现计数器缓存列时出现错误Unknownkey(s):counter_cache。我在这个问题中实现了模型关联:Modelassociationquestion这是我的迁移:classAddVideoVotesCountToVideos0Video.reset_column_informationVideo.find(:all).eachdo|p|p.update_attributes:videos_votes_count,p.video_votes.lengthendenddefself.downremove_column:videos,:video_vot

随机推荐