像 Couchbase 这样的 NoSQL 数据库确实在内存中保存了大量文档,因此速度很快,但也对其运行的服务器的内存大小提出了更高的要求。
我正在寻找在 NoSQL 数据库中存储文档的几种相反策略之间的最佳策略。这些都是:
将整个信息放入一个(大)文档中的优点是,通过一次 GET 即可从内存或磁盘中检索信息(如果之前已从内存中清除)。对于无模式 NoSQL 数据库,这几乎是我们所希望的。但最终文档会变得太大并占用大量内存,总共能够保存在内存中的文档会减少
将所有文档拆分为多个文档(例如,使用复合键,如本问题中所述:为面向文档的数据库设计记录键 - 最佳实践特别是当这些文档仅保存特定读取/更新操作所需的信息时,将允许在内存中保存更多(临时)文档。
我正在查看的用例是来自电信提供商的呼叫详细记录 (CDR)。这些 CDR 通常每天都会达到数亿个。然而,这些客户中的许多人并没有在每一天提供单一记录(我正在研究预付费占主导地位且数据饱和度较低的东南亚市场)。这意味着通常大量文档可能每隔一天进行一次读取/更新,只有一小部分文档每天有几次读取/更新周期。
向我建议的一种解决方案是构建 2 个存储桶,将更多 RAM 分配给更临时的存储桶,将更少的 RAM 分配给保存较大文档的第二个存储桶。这将允许更快地访问更瞬态的数据,并更慢地访问更大的文档,例如保存根本不改变的配置文件/用户信息。不过,我确实看到了这个提议的两个缺点,一是你无法跨两个存储桶构建视图(Map/Reduce)(这是专门针对 Couchbase 的,其他 NoSQL 解决方案可能允许这样做),第二个会带来更多开销随着用户群的增长,密切管理两个存储桶的内存分配之间的平衡。
还有其他人受到过这个挑战吗?您对此问题的解决方案是什么?从您的角度来看,最好的策略是什么?为什么?显然,这最可能是两种策略的中间部分,在我看来,只有一个文档或将一个大文档分成数百个文档并不是理想的解决方案。
编辑2014-9-14
好吧,虽然这接近回答我自己的问题,但到目前为止还没有任何提供的解决方案,下面的评论是我现在计划如何组织数据的更多背景知识,试图在速度和内存消耗之间实现最佳平衡点:
手机号码:个人资料
- 它保存来自表的配置文件信息,而不是直接来自 CDR。这里输入的数据较少,例如年龄、性别和姓名。该密钥是由手机号码(MSISDN)和单词配置文件组成的复合密钥,以“:”分隔
手机号码:收入
- 它保存瞬时信息,例如使用计数器和累积客户支出总收入的变量。该密钥又是一个复合密钥,由移动号码 (MSISDN) 和单词 Revenue 组成,并用“:”分隔。
手机号码:选择
- 这保存了有关客户何时选择加入该计划以及何时再次选择退出该计划的半临时信息。这可能会发生多次,并通过数组进行处理。该密钥又是一个复合密钥,由移动号码 (MSISDN) 和单词 optin 组成,并用“:”分隔
连接 ID
- 它保存有关通过语音或视频通话或 SMS/MMS 完成的特定 A/B 连接(发送者/接收者)的信息。密钥由连接的两个 mobile_no 组成。
在文档结构发生这些变化之前,我将所有配置文件、收入和 optin 信息放入一个大文档中,始终将 connection_id 保留为单独的文档。这种新的文档存储策略有望在速度和内存消耗之间实现更好的折衷,因为我将主文档拆分为多个文档,以便每个文档仅包含在应用程序的单个步骤中读取/更新的重要信息。
这还考虑到了随着时间的推移而发生的不同变化率,其中一些数据非常短暂(例如随着每个 CDR 的到来而更新的计数器和累积收入字段),并且配置文件信息几乎没有变化。我确实希望这能让大家更好地理解我想要实现的目标,非常欢迎评论和反馈。