原文地址: https://www.elastic.co/guide/cn/elasticsearch/guide/current/shared-index.html, 版权归 www.elastic.co 所有
英文版地址: https://www.elastic.co/guide/en/elasticsearch/guide/current/shared-index.html
英文版地址: https://www.elastic.co/guide/en/elasticsearch/guide/current/shared-index.html
请注意:
本书基于 Elasticsearch 2.x 版本,有些内容可能已经过时。
本书基于 Elasticsearch 2.x 版本,有些内容可能已经过时。
共享索引 (Shared Index)edit
我们可以为许多的小论坛使用一个大的共享的索引, 将论坛标识索引进一个字段并且将它用作一个过滤器:
PUT /forums { "settings": { "number_of_shards": 10 }, "mappings": { "post": { "properties": { "forum_id": { "type": "string", "index": "not_analyzed" } } } } } PUT /forums/post/1 { "forum_id": "baking", "title": "Easy recipe for ginger nuts", ... }
我们可以把 forum_id
用作一个过滤器来针对单个论坛进行搜索。这个过滤器可以排除索引中绝大部分的数据(属于其它论坛的数据),缓存会保证快速的响应:
GET /forums/post/_search { "query": { "bool": { "must": { "match": { "title": "ginger nuts" } }, "filter": { "term": { "forum_id": { "baking" } } } } } }
这个办法行得通,但我们可以做得更好。 来自于同一个论坛的帖子可以简单地容纳于单个分片,但它们现在被打散到了这个索引的所有10个分片中。 这意味着每个搜索请求都必须被转发至所有10个分片的一个主分片或者副本分片。 保证同一个论坛的所有帖子都被存储在一个分片上会是个好想法。
在 路由一个文档到一个分片中,我们说过一个文档将通过使用如下公式来分配到一个指定分片:
shard = hash(routing) % number_of_primary_shards
路由(routing
) 的值默认为文档的_id
,但我们可以覆盖它并使用自定义的路由值,例如 forum_id
。
所有有着相同 routing
值的文档都将被存储于相同的分片:
PUT /forums/post/1?routing=baking { "forum_id": "baking", "title": "Easy recipe for ginger nuts", ... }
当我们搜索某一个论坛的帖子时,我们可以传递相同的 routing
值来保证搜索请求仅在存有我们文档的分片上执行:
GET /forums/post/_search?routing=baking { "query": { "bool": { "must": { "match": { "title": "ginger nuts" } }, "filter": { "term": { "forum_id": { "baking" } } } } } }
多个论坛可以通过传递一个逗号分隔的列表来指定 routing
值,然后将每个 forum_id
包含于一个 terms
查询:
GET /forums/post/_search?routing=baking,cooking,recipes { "query": { "bool": { "must": { "match": { "title": "ginger nuts" } }, "filter": { "terms": { "forum_id": { [ "baking", "cooking", "recipes" ] } } } } } }
这种方式从技术上来说比较高效,但是由于要为每一个查询或者索引写入请求指定 routing
和 terms
的值看起来有一点笨拙。
索引别名可以解决这个问题!