一。路由的默认原则
保存文档时,文档会通过一个公式路由到一个索引中的一个分片上。默认的公式如下:
shard_num = hash(_routing) % num_primary_shards
默认情况下时通过_routing字段进行路由的,这个字段的值默认时等于文档_id字段的。
二。自定义路由的优势
自定义路由比较简单,如下,一旦设置routing参数将替换_id字段路由文档。
PUT my_index/my_type/1?routing=user1&refresh=true { "title": "This is a document" } GET my_index/my_type/1?routing=user1
如果不设置路由,每个一个查询都会去搜索索引中的全部分片,所以如果自定义路由可以提高搜索性能(只搜索路由指定的分片)。在索引的时候只能指定一个路由,但搜索的时候可以指定一个或多个路由,这样可以大大提高搜索的灵魂性,如下:
GET my_index/_search?routing=user1,user2 { "query": { "match": { "title": "document" } } }
三。强CRUD操作携带routing参数
自定义路由后,CRUD操作最好都要带上routing参数,要不可能导致一个文档被保存到多个分片上,可以通过设置强制所有CRUD操作必须带routing参数,设置如下:
PUT my_index2 { "mappings": { "my_type": { "_routing": { "required": true } } } }
一旦设置后,不带routing的操作将会报错(throws a routing_missing_exception
.)
四。注意保证_id字段的唯一性
设置了自定义路由,索引中_id字段,的唯一性将得不到保障,即在不同的分片上可能会存在_id相同的文档,所以,一点自定义路由,最好通过自定义_id的方式,保证_id的唯一性。
五。优化路由的单点查询问题
自定义路由可能会导致索引分配不均,大量的索引路由到一个分片上,导致这个分片的索引和查询性能降低。为了解决这个问题,可以设置 routing_partition_size 参数。(注意这是一个索引级别的设置,只能在创建索引的时候设置。)这样routing将路由到一组分片,然后_id字段在决定文档保存到那一个分片上。由于这个原因。routing_partition_size的值必须是一个大于1但是小于number_of_shards设置的分片数量的一个整数。具体公式如下:
shard_num = (hash(_routing) + hash(_id) % routing_partition_size) % num_primary_shards
注意:索引一旦设置了routing_partition_size 后,join field将不能被创建了,同时索引中的所有mapping必须设置_routing为required的。