NoSQL数据库中最好的文档存储策略是什么?< / h1 >



像Couchbase这样的NoSQL数据库确实在内存中保存了大量文档,因此它们的速度非常快,但它也对运行它的服务器的内存大小提出了更高的要求。

我正在寻找在NoSQL数据库中存储文档的几种相反策略之间的最佳策略。这些都是:

  • 优化速度

将整个信息放入一个(大)文档的好处是,使用单个GET可以从内存或磁盘(如果之前已从内存中清除)检索信息。对于无模式的NoSQL数据库,这几乎是可以实现的。但最终文档会变得太大,占用大量内存,总内存中能够保存的文档会变少

  • 优化内存

将所有文档拆分为几个文档(例如使用复合键,如在这个问题中所描述的):为面向文档的数据库设计记录键-最佳实践,特别是当这些文档只保存特定读/更新操作所需的信息时,将允许更多(瞬时)文档保存在内存中。

我正在查看的用例是来自电信提供商的呼叫详细记录(CDR)。这些CDR通常每天都有数亿个。然而,这些用户中的许多人并不是每天都提供单一记录(我关注的是东南亚市场,那里的预付费市场占主导地位,数据饱和度更低)。这意味着通常大量的文档可能每隔一天有一次读取/更新,只有一小部分文档每天有几个读取/更新周期。

有人向我建议的一个解决方案是构建2个桶,将更多的RAM分配给更瞬态的桶,并将更少的RAM分配给保存更大文档的第二个桶。这将允许更快地访问更多的瞬时数据,而更慢地访问更大的文档,例如保存基本不变的配置文件/用户信息。我确实看到了这个提议的两个缺点,一个是你不能跨两个桶建立一个视图(Map/Reduce)(这是专门针对Couchbase的,其他NoSQL解决方案可能允许),第二个是随着用户群的增长,在密切管理两个桶的内存分配之间的平衡方面会有更多的开销。

有没有人受到这个问题的挑战,你是如何解决这个问题的?从你的角度来看,最好的策略是什么?为什么?显然,这是一种介于两者之间的策略,在我看来,只有一个文档或将一个大文档分成数百个文档都不是理想的解决方案。

编辑2014-9-14好吧,虽然这接近于回答我自己的问题,但到目前为止还没有任何提供的解决方案,下面是我现在计划如何组织我的数据的更多背景,试图在速度和内存消耗之间达到一个最佳点:

Mobile_No:概要

  • 保存来自表的配置文件信息,而不是直接来自CDR。不那么短暂的数据,比如年龄,性别和名字。密钥是由手机号码(MSISDN)和单词profile组成的复合密钥,用":">
  • 分隔。

Mobile_No:收入

  • 保存临时信息,如使用计数器和累积客户花费的总收入的变量。密钥也是一个复合密钥,由手机号码(MSISDN)和单词收入组成,中间用":">
  • 分隔。

Mobile_No: Optin

  • 保存有关客户何时选择加入该计划以及何时再次选择退出该计划的半瞬态信息。这可以发生多次,并通过数组处理。键还是一个复合键,由手机号码(MSISDN)和单词optin组成,中间用":">
  • 分隔。

Connection_Id

  • 此保存有关通过语音或视频呼叫或短信/彩信完成的特定a/B连接(发送方/接收方)的信息。关键字由两个连接的mobile_no组成。

在这些文档结构的变化之前,我把所有的个人资料,收入和选项信息在一个大文档中,始终保持connection_id作为一个单独的文档。这个新的文档存储策略给了我希望在速度和内存消耗之间更好的折衷,因为我将主文档分成几个文档,以便每个文档只有在应用程序的单个步骤中读取/更新的重要信息。

这也考虑到随着时间变化的不同速率,一些数据是非常短暂的(比如计数器和累计收入字段,随着每个CDR的到来而更新),而配置文件信息大部分是不变的。我确实希望这能让你更好地理解我正在努力实现的目标,欢迎评论和反馈。

感谢您更新您最初的问题。当您谈到在粗粒度文档与细粒度文档之间找到适当的平衡时,您是正确的。

文档的最终体系结构实际上属于您的特定业务领域需求。您必须在用例中识别作为一个整体需要的数据"块",然后以此为基础构建存储的文档形状。下面是设计文档结构时需要执行的一些高级步骤:

  1. 确定应用程序/服务的所有文档消费用例。(读、读写、可搜索项)
  2. 设计你的文档(很可能你最终会有几个小文档,而不是一个大文档,拥有一切)
  3. 为不同的文档类型设计可以共存于一个bucket中的文档键(例如,在键值中使用namespace)
  4. 针对您的用例对生成的模型进行"干运行",以查看您是否具有最优的(读/写)noSQL事务和所有事务
  5. 为您的用例运行性能测试(尝试模拟至少高2倍的预期负载)

注意:当你设计不同的文档时,有一些冗余是可以的(记住它不是具有规范化形式的RDBMS),把它看作是面向对象的设计。

注2:如果你有键之外的可搜索项(例如,根据姓氏"以开头"和其他一些动态搜索条件搜索客户),考虑使用ElasticSearch与CB集成,或者你也可以尝试CB3.0附带的N1QL查询语言。

似乎你走在一个正确的方向,通过一个MSISDN分成几个较小的文件,例如:MSISDN:profile, MSISDN:revenue, MSISDN:optin。我会特别注意你最后的文件类型"A/B"连接。这听起来可能会产生很大的体积,而且本质上是短暂的……所以你必须找出这些文档在Couchbase存储桶中需要保存多长时间。你可以指定TTL(生存时间),这样旧的文档将被自动清除。

我同意你关于有效利用资源的方法(如果资源有限的话)。但另一方面,这个系统可能会变得非常健谈。如果我理解正确的话,您的"连接"文档设计过于细粒度,可能会在网络上引入太多的I/o。根据我的经验,如果您正在设计一个做出实时决策的系统,那么这些网络I/o是非常昂贵的。你可以从数学上估计这些不同选择的影响,以平衡这些相反的力量:)

我确实认为,可扩展的大数据系统的精神是我们应该"少"担心资源的"约束"。这些no-sql数据库许可证不按CPU核划分。商品硬件很便宜。正如我们所讨论的,RAM越来越便宜了。同样,这些系统的投资回报也会影响架构决策。

最新更新