Elasticsearch索引设计

时间:2015-04-11 17:42:37

标签: performance elasticsearch

我正在维护多年的用户活动,包括浏览,购买数据。浏览/购买中的每个条目都是一个json对象:{item_id:id1,item_name,name1,category:c1,brand:b1,event_time:t1}。

我想撰写不同的查询,例如让所有浏览项目A的客户和/或在时间范围t1到t2内购买项目B.有数千万客户。

我目前的设计是为每个客户使用嵌套对象:

customer1:
       customer_id,id1,
       name: name1,
       country: US,
       browse: [{browseentry1_json},{browseentry2_json},...],
       purchase: [{purchase entry1_json},{purchase entry2_json},...]

通过这种设计,我可以使用嵌套查询轻松编写各种查询。唯一的问题是旧的浏览/购买数据很难过期:我只想保留,例如,多年的浏览/购买数据。在这个设计中,我将不得不在某个时刻读取整个索引,删除过期的浏览/购买数据,然后将其写回。

另一种设计是使用父/子结构。 type:user是浏览和购买类型的父级。 类型browse将包含每个浏览条目。 虽然通过查询删除来删除旧数据似乎更容易,但对于上述查询,我​​将不得不执行多个和/或has_child查询,并且性能要低得多。事实上,最初我使用的是父/子结构,但查询时间似乎很长。我因此放弃了它,并试图切换到嵌套对象。

我也在考虑使用嵌套对象,但是将数据分成不同的索引(比如每月索引),以便我可以轻松地使旧数据过期。这种方法的问题在于我必须查询这些多个索引,并对其进行聚合以获得不同的用户,我认为这将慢得多。(已经尝试过)。这个项目的一个要求是能够在可接受的时间范围内给出查询的计数。(比如秒),我担心这种方法可能是不可接受的。

ES群集是7台机器,每个8核和32G内存。 有什么建议?

提前致谢! 陈

1 个答案:

答案 0 :(得分:0)

我会创建一个"浏览"而不是创建客户索引。指数(指数)和"采购"由时间跨度分隔的指数(EG:每月,正如您在上一段中提到的)。 在每个结构中,我将添加客户字段。现在您面临两种不同的方法: 1.您只能添加对客户的引用(例如id)并进行另一个查询以获取其详细信息。 2.如果您没有任何存储问题,可以在每个结构中保留所有客户的数据。

如果这对性能不够,可以将其与"路由"并在同一个分片上保存所有特定用户的数据。并且Elasticsearch不需要在分片之间获取数据(您可以在Shay Benon解释"用户数据流")的情况下观看this video

和合