我正在计划一个策略,用于按日期和用户方向查询数百万个文档。
使用布线或索引有什么区别或优点?
tvokkenx1#
Shay Banon @ Elasticsearch recommends的设计模式之一是:按时间范围索引,按用户路由并使用别名。为每一天(或一个日期范围)创建一个索引,并在user字段上路由文档,这样您就可以“退休”旧日志,并且不需要在所有碎片上执行查询:
user
$ curl -XPOST localhost:9200/user_logs_20140418 -d '{ "mappings" : { "user_log" : { "_routing": { "required": true, "path": "user" }, "properties" : { "user" : { "type" : "string" }, "log_time": { "type": "date" } } } } }'
创建一个alias来过滤和route用户,这样您就可以查询user_foo的文档:
user_foo
$ curl -XPOST localhost:9200/_aliases -d '{ "actions": [{ "add": { "alias": "user_foo", "filter": {"term": {"user": "foo"}}, "routing": "foo" } }] }'
为时间窗口创建别名,以便可以查询文档this_week:
this_week
$ curl -XPOST localhost:9200/_aliases -d '{ "actions": [{ "add": { "index": ["user_logs_20140418", "user_logs_20140417", "user_logs_20140416", "user_logs_20140415", "user_logs_20140414"], "alias": "this_week" }, "remove": { "index": ["user_logs_20140413", "user_logs_20140412", "user_logs_20140411", "user_logs_20140410", "user_logs_20140409", "user_logs_20140408", "user_logs_20140407"], "alias": "this_week" } }] }'
这种方法的一些优点是:
8aqjt8rx2#
索引是解析你索引过的文档的过程,就像一本教科书的附录。当索引数据超过一个服务器限制时,请添加另一个服务器并与它们共享数据,而不是升级服务器配置。此过程称为分片。如果我们搜索,它将在所有碎片中搜索,并执行map reduce和返回结果。如果我们将相似的数据分组在一起,并在特定数据中搜索一些数据,这意味着它降低了处理能力,提高了速度。
路由用于将数据组存储在特定碎片中。选择路由字段。该字段应存在于所有文档中,字段不应包含不同的值。注意:路由应该在多个分片环境中使用[而不是在单个节点中]。如果我们在单个节点中使用路由。则没有使用它。
kpbwa7wx3#
让我们先定义一下术语。
索引在Elasticsearch的上下文中可以表示许多含义:*为文档编制索引:向Elasticsearch写入新文档*索引字段:将Map(方案)中的字段定义为已索引。需要对搜索的所有字段进行索引(默认情况下,对所有字段进行索引)*ElasticSearch索引:这是一个配置单元(例如模式/Map)和数据单元(例如磁盘上的一些文件)。从文档被写入索引的意义上说,它类似于数据库。当你搜索时,你可以访问一个或多个索引*Lucene索引:一个Elasticsearch索引可以被分成N个碎片。2一个碎片就是一个Lucene索引。3当你索引一个文档时,这个文档被路由到其中一个碎片。4当你在索引中搜索时,搜索被广播到每个碎片的副本。5每个碎片用它所知道的内容回复,然后结果被聚合并发送回客户端
根据上下文判断,“按用户索引”和“按日期索引”指的是每个用户一个索引或每个日期间隔(例如天)一个索引。
Routing指的是将文档发送到shards,正如我前面所描述的,默认情况下,这是随机完成的:散列范围除以碎片的数量,当一个文档进入时,Elasticsearch散列它的_id,散列福尔斯其中一个碎片的散列范围==〉,这就是文档要去的地方。
_id
您可以使用自定义路由对此进行控制:Elasticsearch可以散列一个路由值(例如用户名),而不是散列_id。因此,具有相同路由值(即相同用户)的所有文档都位于同一个碎片上。然后,可以在查询时使用路由,以便Elasticsearch只查询一个碎片(每个索引),而不是N个。这可以带来massive query performance gains(请特别查看幻灯片24)。回到手头的问题,我认为“当按索引或使用路由分解数据时有什么区别或优势?”为了回答这个问题,该战略应考虑到:
*如何建立索引建立索引(写入).如果建立索引的工作量很大,则需要确保所有节点都参与(即在相同数量的碎片上写入类似数量的数据),否则将出现瓶颈*如何查询数据.如果查询经常引用单个用户的数据,那么将数据按用户细分(按用户索引或按用户路由)是很有用的*碎片总数。碎片、节点和字段越多,群集状态就越大。如果群集状态的大小变大(例如,大于数十MB),就很难在所有节点上保持同步,从而导致群集不稳定。根据经验,您希望单个Elasticsearch群集中的碎片数量保持在数千个碎片中的数十个以内
在实践中,我看到了以下设计:1.每个固定时间间隔一个索引。您将在日志中看到这一点(例如,默认情况下Logstash写入每日索引)1.每个时间间隔一个索引,按大小循环。这样即使写入吞吐量变化,索引大小也保持不变1.每个用户一个索引“series”(1.或2.)。如果用户很少,这很好用,因为它消除了过滤。但是如果用户很多,它就不起作用了,因为你有太多的碎片1.每个时间间隔一个索引(1.或2.),有大量的碎片,并按用户路由。如果用户很多,这很好用。正如Mahesh指出的,如果一些用户有大量数据,就会出现问题,导致碎片不均匀。在这种情况下,需要一种方法将大用户reindex到他们自己的索引中(参见3.),并且可以使用别名向应用程序隐藏此逻辑。我还没有看到每个用户一个索引和按日期间隔路由的设计。这里的主要缺点是您可能***一次写入一个碎片***(包含今天哈希的碎片)。这将限制您的写入吞吐量和平衡写入的能力。但这种设计可能适用于大量但不是很大的用户(例如1 K),在有限的时间间隔内写入很少,查询很多。顺便说一句,如果你想了解更多这方面的东西,我们有一个Elasticsearch Operations training,在那里我们讨论了很多关于架构,权衡,ElasticSearch如何在引擎盖下工作。我讲授这门课)
3条答案
按热度按时间tvokkenx1#
Shay Banon @ Elasticsearch recommends的设计模式之一是:按时间范围索引,按用户路由并使用别名。
为每一天(或一个日期范围)创建一个索引,并在
user
字段上路由文档,这样您就可以“退休”旧日志,并且不需要在所有碎片上执行查询:创建一个alias来过滤和route用户,这样您就可以查询
user_foo
的文档:为时间窗口创建别名,以便可以查询文档
this_week
:这种方法的一些优点是:
8aqjt8rx2#
索引是解析你索引过的文档的过程,就像一本教科书的附录。
当索引数据超过一个服务器限制时,请添加另一个服务器并与它们共享数据,而不是升级服务器配置。此过程称为分片。
如果我们搜索,它将在所有碎片中搜索,并执行map reduce和返回结果。如果我们将相似的数据分组在一起,并在特定数据中搜索一些数据,这意味着它降低了处理能力,提高了速度。
路由用于将数据组存储在特定碎片中。选择路由字段。该字段应存在于所有文档中,字段不应包含不同的值。
注意:路由应该在多个分片环境中使用[而不是在单个节点中]。如果我们在单个节点中使用路由。则没有使用它。
kpbwa7wx3#
让我们先定义一下术语。
索引在Elasticsearch的上下文中可以表示许多含义:
*为文档编制索引:向Elasticsearch写入新文档
*索引字段:将Map(方案)中的字段定义为已索引。需要对搜索的所有字段进行索引(默认情况下,对所有字段进行索引)
*ElasticSearch索引:这是一个配置单元(例如模式/Map)和数据单元(例如磁盘上的一些文件)。从文档被写入索引的意义上说,它类似于数据库。当你搜索时,你可以访问一个或多个索引
*Lucene索引:一个Elasticsearch索引可以被分成N个碎片。2一个碎片就是一个Lucene索引。3当你索引一个文档时,这个文档被路由到其中一个碎片。4当你在索引中搜索时,搜索被广播到每个碎片的副本。5每个碎片用它所知道的内容回复,然后结果被聚合并发送回客户端
根据上下文判断,“按用户索引”和“按日期索引”指的是每个用户一个索引或每个日期间隔(例如天)一个索引。
Routing指的是将文档发送到shards,正如我前面所描述的,默认情况下,这是随机完成的:散列范围除以碎片的数量,当一个文档进入时,Elasticsearch散列它的
_id
,散列福尔斯其中一个碎片的散列范围==〉,这就是文档要去的地方。您可以使用自定义路由对此进行控制:Elasticsearch可以散列一个路由值(例如用户名),而不是散列
_id
。因此,具有相同路由值(即相同用户)的所有文档都位于同一个碎片上。然后,可以在查询时使用路由,以便Elasticsearch只查询一个碎片(每个索引),而不是N个。这可以带来massive query performance gains(请特别查看幻灯片24)。回到手头的问题,我认为“当按索引或使用路由分解数据时有什么区别或优势?”
为了回答这个问题,该战略应考虑到:
*如何建立索引建立索引(写入).如果建立索引的工作量很大,则需要确保所有节点都参与(即在相同数量的碎片上写入类似数量的数据),否则将出现瓶颈
*如何查询数据.如果查询经常引用单个用户的数据,那么将数据按用户细分(按用户索引或按用户路由)是很有用的
*碎片总数。碎片、节点和字段越多,群集状态就越大。如果群集状态的大小变大(例如,大于数十MB),就很难在所有节点上保持同步,从而导致群集不稳定。根据经验,您希望单个Elasticsearch群集中的碎片数量保持在数千个碎片中的数十个以内
在实践中,我看到了以下设计:
1.每个固定时间间隔一个索引。您将在日志中看到这一点(例如,默认情况下Logstash写入每日索引)
1.每个时间间隔一个索引,按大小循环。这样即使写入吞吐量变化,索引大小也保持不变
1.每个用户一个索引“series”(1.或2.)。如果用户很少,这很好用,因为它消除了过滤。但是如果用户很多,它就不起作用了,因为你有太多的碎片
1.每个时间间隔一个索引(1.或2.),有大量的碎片,并按用户路由。如果用户很多,这很好用。正如Mahesh指出的,如果一些用户有大量数据,就会出现问题,导致碎片不均匀。在这种情况下,需要一种方法将大用户reindex到他们自己的索引中(参见3.),并且可以使用别名向应用程序隐藏此逻辑。
我还没有看到每个用户一个索引和按日期间隔路由的设计。这里的主要缺点是您可能***一次写入一个碎片***(包含今天哈希的碎片)。这将限制您的写入吞吐量和平衡写入的能力。但这种设计可能适用于大量但不是很大的用户(例如1 K),在有限的时间间隔内写入很少,查询很多。
顺便说一句,如果你想了解更多这方面的东西,我们有一个Elasticsearch Operations training,在那里我们讨论了很多关于架构,权衡,ElasticSearch如何在引擎盖下工作。我讲授这门课)