我正在构建一个应用程序,每个用户存储大量数据(可能以千兆字节为单位)。
类似于请求日志,所以假设您为每条记录都有以下字段:
customer_id
date
hostname
environment
pid
ip
user_agent
account_id
user_id
module
action
id
response code
response time (range)
可能还有一些。
好处是用法主要是只写,但有读时 我希望能够近乎实时地快速回答。
关于使用模式的另一个预测是大多数时候人们会查看最新的数据, 并且很少查询过去,聚合等,所以我的猜测是工作集会小得多 整个数据库,即大多数用户的最新数据和正在进行分析的一些用户的历史范围。 对于后一种情况,我认为第一次查询的确定要慢,直到它将范围放入内存。
但问题是我不太确定如何有效地索引数据。
索引的开头是明确的,其customer_id和日期。但其余的可以 以任何组合使用,我无法预测最常见的,至少没有任何确定性。
我们目前正在用mongo进行原型设计。有没有办法在mongo(存储/ cpu /成本)中有效地做到这一点?
唯一想到的是尝试预测几个频繁的查询并将它们编入索引,然后大量地对数据进行分片 并确保每个客户的数据均匀分布在分片上,以便对其余的“客户,日期”索引进行快速表扫描 查询。
P.S。我也对db替代方案的建议持开放态度。
答案 0 :(得分:1)
使用这些有限数量的字段,您可能只有每个字段的索引,或者可能与customer_id结合使用。 MongoDB非常聪明,可以为每种情况选择最快的索引。如果你可以将你的整个数据集放在内存中(几GB不是很多数据!),那么这一切都无所谓。
你说你的GB 每个用户,但这仍然意味着你可以在字段上有一个索引,因为只有十几个。有了那么多数据,你很快就会想要分片。
欢呼声, 德里克
答案 1 :(得分:1)
我认为,你的要求并没有真正融合在一起。您不能拥有大量数据和即时临时查询。
如果您使用大量索引,那么您的写入速度会很慢,并且您需要多更多的RAM。
我可以建议:
保留您的客户ID和日期索引,以便向用户提供最新数据,并将您的要求放宽到汇总查询的实时性或准确性。
如果牺牲准确性,您将每隔一段时间触发map-reduce作业以预先计算查询。然后,用户可能会看到稍微陈旧的数据(或者可能不是,毕竟这是历史不可变数据)。
如果你牺牲速度,那么你每次都会运行map-reduce(现在它是计算mongodb集群中聚合的唯一理智方式)。
希望这会有所帮助:)