路由文档到分片

当你索引一个文档,它被存储在单独一个主分片上。Elasticsearch是如何知道文档属于哪个分片的呢?当你创建一个新文档,它是如何知道是应该存储在分片1还是分片2上的呢?

进程不能是随机的,因为我们将来要检索文档。事实上,它根据一个简单的算法决定:

shard = hash(routing) % number_of_primary_shards

routing值是一个任意字符串,它默认是_id但也可以自定义。这个routing字符串通过哈希函数生成一个数字,然后除以主切片的数量得到一个余数(remainder),余数的范围永远是0number_of_primary_shards - 1,这个数字就是特定文档所在的分片。

这也解释了为什么主分片的数量只能在创建索引时定义且不能修改:如果主分片的数量在未来改变了,所有先前的路由值就失效了,文档也就永远找不到了。

有时用户认为固定数量的主分片会让之后的扩展变得很困难。现实中,有些技术会在你需要的时候让扩展变得容易。

所有的文档API(getindexdeletebulkupdatemget)都接收一个routing参数,它用来自定义文档到分片的映射。自定义路由值可以确保所有相关文档——例如属于同一个人的文档——被保存在同一分片上。我们将在《扩展》章节说明你为什么需要这么做。

参考: http://es.xiaoleilu.com/040_Distributed_CRUD/05_Routing.html

而我们为什么会需要自定义的Routing模式呢?首先默认的Routing模式在很多情况下都是能满足我们的需求的——平均的数据分布、对我们来说是透明的、多数时候性能也不是问题。但是在我们更深入地理解我们的数据的特征之后,使用自定义的Routing模式可能会给我们带来更好的性能。

通常情况下,ElasticSearch是如何把数据分发到各个分片中,哪个分片存储哪一类的文档等细节并不重要。因为查询时,将查询命令分发到每个分片 就OK了。唯一的关键点在于算法,将数据均等地分配到各个分片的算法。在删除或者更新文档时,情况就会变得有点复杂了。实际上,这也不是什么大问题。只要 保证分片算法在处理文档时,对于相同的文档标识生成相同的映射值就可以了。如果我们有这样的分片算法,ElasticSearch就知道在处理文档时,如 何定位到正确的分片。但是,在选择文档的存储分片时,采用一个更加智能的办法不就更省事儿了吗?比如,把某一特定类型的书籍存储到特定的分片上去,这样在 搜索这一类书籍的时候就可以避免搜索其它的分片,也就避免了多个分片搜索结果的合并。这就是路由功能(routing)的用武之地。路由功能向 ElasticSearch提供一种信息来决定哪些分片用于存储和查询。同一个路由值将映射到同一个分片。这基本上就是在说:“通过使用用户提供的路由值,就可以做到定向存储,定向搜索。”

假设你有一个100个分片的索引。当一个请求在集群上执行时会发生什么呢?

1. 这个搜索的请求会被发送到一个节点

2. 接收到这个请求的节点,将这个查询广播到这个索引的每个分片上(可能是主分片,也可能是复制分片)

3. 每个分片执行这个搜索查询并返回结果

4. 结果在通道节点上合并、排序并返回给用户

因为默认情况下,Elasticsearch使用文档的ID(类似于关系数据库中的自增ID,当然,如果不指定ID的 话,Elasticsearch使用的是随机值)将文档平均的分布于所有的分片上,这导致了Elasticsearch不能确定文档的位置,所以它必须将 这个请求广播到所有的100个分片上去执行。这同时也解释了为什么主分片的数量在索引创建的时候是固定下来的,并且永远不能改变。因为如果分片的数量改变 了,所有先前的路由值就会变成非法了,文档相当于丢失了。

原来的查询语句:“请告诉我,USER1的文档数量一共有多少”

使用自定义Routing(在USESR ID上)后的查询语句:“请告诉我,USER1的文档数量一共有多少,它就在第三个分片上,其它的分片就不要去扫描了”

指定个性化路由

所有的文档API(get,index,delete,update和mget)都能接收一个routing参数,可以用来形成个性化文档分片映射。一个个性化的routing值可以确保相关的文档存储到同样的分片上——比如,所有属于同一个用户的文档。

第一种方法,也是比较直观的方法就是直接在请求的URL中指定routing参数:

    curl -XPOST 'http://localhost:9200/store/order?routing=user123' -d '  {  "productName": "sample",  "customerID": "user123"  }'  

这样我们就按照用户的customerID的值将具有相同customerID的文档置于同一分片上了。

第二种方法就是直接从文档中提取到对应的路由值:

    curl -XPUT 'http://localhost:9200/store/order/_mapping' -d '  {  "order": {  "_routing": {  "required": true,  "path": "customerID"  }  }  }'  

这样的方法和第一种方法在效果上一样的,但是有一点需要注意,相比于第一种方法这种方法的效率稍低,因为第一种方法直接就在请求的参数中确定了路由的值,而第二种方法中,首先需要将文档读入之后,再从中提取到对应的路由值。

利用路由机制的查询

利用路由机制的查询也是非常简单明了的,只需要在查询中指定对应的路由值即可:

    curl -XGET 'http://localhost:9200/store/order/_search?routing=user123' -d '  {  "query": {  "filtered": {  "query": {  "match_all": {}  },  "filter": {  "term": {  "userID": "user123"  }  }  }  }  }'  

通过指定的路由值,我们就可以直接定位到user123的文档所在的分片,而不用一股脑的向索引的所有节点都发送请求。这样的话,会大大减少系统资源的浪费。

当然,也可以同时指定多个路由值,方法也是显而易见的,只需要在查询参数中指定多个路由值即可:

    curl -XGET 'http://localhost:9200/forum/posts/?routing=Admin,Moderator' -d '{}'  

路由机制的总结

实际上,如果不明确指明使用路由机制,实际上路由机制也是在发挥作用的,只是默认的路由值是文档的id而已。而个性化路由的需求主要是和业务相关 的。默认的路由(如果是自动的生成的id)直观上会把所有的文档随机分配到一个分片上,而个性化的路由值就是和业务相关的了。这也会造成一些潜在的问题, 比如user123本身的文档就非常多,有数十万个,而其他大多数的用户只有几个文档,这样的话就会导致user123所在的分片较大,出现数据偏移的情 况,特别是多个这样的用户处于同一分片的时候,现象会更明显。具体的使用还是要结合实际的应用场景来选择的。

参考:http://blog.csdn.net/cnweike/article/details/38531997

转载于:https://www.cnblogs.com/bonelee/p/6055340.html

elasticsearch 路由文档到分片相关推荐

  1. 【elasticsearch】文档 CRUD 增删改查 以及 相关 参数

    1.概述 转载:https://mp.weixin.qq.com/s/aOZnZpAC4c_dYkVW8DfNPg 在Elasticsearch中,文档(document)是所有可搜索数据的最小单位. ...

  2. ElasticSearch创建文档

    ElasticSearch创建文档 创建文档有两种途径 直接在XcontentBuilder构建json数据,创建文档. // 描述json 数据/** {id:xxx, title:xxx, con ...

  3. 分布式搜索elasticsearch 索引文档的增删改查 入门

    分布式搜索elasticsearch 索引文档的增删改查 入门 1.RESTful接口使用方法 为了方便直观我们使用Head插件提供的接口进行演示,实际上内部调用的RESTful接口. RESTful ...

  4. elasticsearch 父子文档使用must not 正确姿势

    需求描述: 1.基于elasticsearch 父子文档进行子条件查询父文档 2.需要查询出子文档不存在的父文档 已知文档结构: 1.父文档clue_list 关联很多的子文档,我们用roam子文档做 ...

  5. elasticSearch -- (文档,类型,索引)

    问题:大规模数据如何检索 当系统数据量达到10亿,100亿级别的时候,我们系统该如何去解决这种问题. 数据库选择-mysql, sybase,oracle,mongodb,hbase- 单点故障如何解 ...

  6. ElasticSearch学习文档

    ElasticSearch 第一节 ElasticSearch概述 1.1ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全文搜索引擎,基于RESTfulw ...

  7. Elasticsearch之文档document入门

    6.1. 默认自带字段解析 {"_index" : "book","_type" : "_doc","_id& ...

  8. elasticsearch——海量文档高性能索引系统

    elasticsearch elasticsearch是一个高性能高扩展性的索引系统,底层基于apache lucene. 可结合kibana工具进行可视化. 概念: index 索引: 类似SQL中 ...

  9. 初识ElasticSearch(2) -文档查询之match查询 | 分词器

    1. 分词器: 2. match查询: 2.1. 数据准备 - 创建带分词器的索引映射 2.2. 数据准备 - 添加文档 2.3. 数据准备 - 查看文本分词 2.4. 查询 - 映射有分词器的字段查 ...

最新文章

  1. 【iOS UI】iOS 9 GUI 资源分享
  2. HighNewTech:带你解读云计算、雾计算(Fog Computing)、边缘计算(Edge Computing)的前世今生
  3. 在區塊鏈上建立可更新的智慧合約(二)
  4. 信息系统服务器数量设置,《系统下服务器设置与优化.doc
  5. hpm128无法共享打印_打印机共享后不能打印的解决方法,文末有难题有高手能解决的?...
  6. SAP Commerce的extensioninfo.xml
  7. 运行在Docker里的SpringBoot应用,如何查看记录在文件系统的日志
  8. java之Synchronized(锁住对象和锁住代码)
  9. 上海交大MBA学费与资助
  10. KyLin的网页界面使用
  11. php去除html标签 空白,php使用strip_tags()去除html标签仍有空白的解决方法
  12. Android+usb+spi,Android设备如何使用USB的硬件接口
  13. 【智慧城市】-GIS数据获取SHP建筑数据获取总结
  14. android x5全屏白色,x5webview 自定义全屏界面(示例代码)
  15. mysql有mdf文件和ldf文件吗_mdf与ldf文件格式
  16. 【MATLAB基础】数据作图--imagesc
  17. 解决一例:“无法删除文件,无法读源文件或磁盘”
  18. 百度3D地图API的调用以及适应过程
  19. vue axios封装以及API统一管理
  20. 让你的 Mac 用上最美的屏保,Aerial 使用教程

热门文章

  1. linux http 配置文件,Linux http配置文件解析
  2. java 对象 方法_java——类、对象、方法
  3. 计算机主键盘的布局,计算机键盘的布局,结构和布置
  4. android 多个dialog 交替显示,Android如何在一个AlertDialog中一个接一个地显示两个ListViews...
  5. linux开终端失败,Linux:终端提示符 (prompt) 不如期生效原因
  6. react骨架屏自动生成_用纯 DOM 的方式结合 Puppeteer 自动生成网页骨架屏
  7. php上传图片到非项目目录,前端页面的读取问题
  8. react native 的赋值比较,空字符串以及undefined
  9. 介绍java常用的两种注释类型,全网独家首发!
  10. 机器学习(MACHINE LEARNING)MATLAB中微分方程的求解