2012-02-08 67 views
0

我正在构建一个存储每个用户大量数据的应用程序(可能以千兆字节为单位)。索引多个密钥用于不同密钥组合中的随机查询

像一个请求日志,所以让我们说,你有对每条记录以下字段:

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.我也接受有关数据库备选方案的建议。

回答

1

有了这个有限数量的字段,你可能只是在它们中的每一个上都有索引,或者可能与customer_id结合使用。 MongoDB非常聪明,可以为每种情况选择最快的索引。如果你可以将你的整个数据集放到内存中(几GB不是很多数据!),那么这一切都没有关系。

你说你有一个GB 每个用户,但这仍然意味着你可以在字段上有一个索引,因为只有大约十几个。有了这么多的数据,无论如何你很快就会在某个时刻分解。

欢呼声, 德里克

+0

几GB **每个用户**。我们不知道他会有多少用户。也许成千上万。这已经很多了。 – 2012-02-09 04:37:24

+0

没错,但你仍然可以在字段上有一个索引,因为只有大约一打。有了这么多的数据,无论如何你很快就会在某个时刻分解。 (添加到我的答案) – Derick 2012-02-09 09:22:31

1

我想,你的要求真的不一起拌匀。您不能拥有大量数据和即时即席查询。

如果你使用了很多索引,那么你的写入速度会很慢,而你需要更多的内存来更多的

愿我的建议是:

保持客户ID和日期索引最近的数据显示,投放给用户,放松要求,无论是实时性或聚集查询的准确性。

如果您牺牲准确性,您将每隔一段时间发射一次map-reduce作业以预先计算查询。用户可能会看到稍微陈旧的数据(或者可能不会,毕竟这是历史不变的数据)。

如果你牺牲速度,那么你会每次运行map-reduce(现在它是计算mongodb集群中聚合的唯一理智方式)。

希望这会有所帮助:)

+0

“他们会查询原始日志条目吗?看起来不像分析系统。”: 我们正在讨论请求日志。您想要“尾巴”并分页查看系统现在或某个时间点发生了什么。你想分割和分析它们,比如“来自这个IP的请求是什么”或者这个用户昨天在系统中做了什么。 – 2012-02-09 07:02:52

+0

@VitalyKushner:我明白了,谢谢。从答案中删除了该部分。 – 2012-02-09 07:05:40

+0

也“实时”可能是太多的需求。等待“分析”答案的几秒钟是可以的。半分钟不行。 – 2012-02-09 07:06:00