Elasticsearch 指定特定分片进行存储或者查询

  Elasticsearch 项目中使用到Es的父子结构、在数据填充之后,查看每个节点的数据分布情况,发现有的节点数据多,有的节点少的情况,在未使用Es父级结构之前,每个节点的数据分布还算平均,如下图:

  左边的数据是未使用父子结构之前每个节点的数据分布数量,右边的是使用了父子结构之后的数据节点分布数量,最下面一行红色的数字是节点平均数量,可以看出,左边的数据与平均值相差不大,右边的数据与平均值最大相差400万,这个差距还是蛮大的,为什么会有这么大的差距呢?围绕着这个问题,进行了一番研究,今天就来学习学习下Elasticsearch 的路由机制。

  首先,Es的路由机制与其分片机制有着直接的关系,Es的路由机制是通过哈希算法,将具有相同哈希值的文档放置在同一分片中的,通过这个哈希算法来进行负载均衡的效果,这个就是为什么左侧图中的每个节点的数据都与平均值相差不大的原因。

  计算公式是:

shard = hash(routing) % number_of_primary_shards

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

  所以,每一条数据在写入的时候,是放在分片1上,还是分片2上,不是瞎蒙的,是通过计算得来的。这也解释了为什么主分片的数量只能在创建索引时定义且不能修改:如果主分片的数量在未来改变了,所有先前的路由值就失效了,文档也就永远找不到了。

  上面解释清楚了,在来解释下,为什么我使用了Es父子结构之后,每个节点的数据发生了那么大的差距呢?

  解释这个之前,先来看下Es父子结构情况下,写入子数据的写法(怎么创建父子结构这里就不赘述了):

PUT /company/employee/1?parent=london
{
  "name":  "Alice Smith",
  "dob":   "1970-10-24",
  "hobby": "hiking"
}

  在创建子文档的时候你必须指出他们的父文档的id,为什么要指定父文档的ID呢?这是因为Es在存储子数据的时候,会用父文档的ID去计算存放在那个分片,它会把父文档相同的数据都存放在同一个分片上面;

  举个例子,如果父文档1,下面子文档有10个,存储在A分片;

  分文档2,下面子文档有500个,存储在B分片上;

这样,随着每个父文档对应的子文档数据分布不均,节点的数据量就会越来越不均衡,这就说明了为什么使用了Es父子结构之后,节点数据差距较大的情况了。

  问题来了,那么怎么解决分布不均的问题呢?

  可以通过指定个性化路由来处理,所有的文档API(get,index,delete,update和mget)都能接收一个routing参数,可以用来形成个性化文档分片映射。一个个性化的routing值可以确保相关的文档存储到同样的分片上。

  

  参考:https://www.cnblogs.com/bonelee/p/6055340.html

  

  

原文地址:https://www.cnblogs.com/Rawls/p/10269192.html

时间: 2024-12-20 13:03:47

Elasticsearch 指定特定分片进行存储或者查询的相关文章

ElasticSearch评分分析 explian 解释和一些查询理解

ElasticSearch评分分析 explian 解释和一些查询理解 按照es-ik分析器安装了ik分词器.然后创建了一个索引用来演示,创建索引:PUT /index_ik_test.索引的结构如下: GET index_ik_test/_mapping { "index_ik_test": { "mappings": { "fulltext": { "properties": { "content":

ES 22 - Elasticsearch中如何进行日期(数值)范围查询

目录 1 范围查询的符号 2 数值范围查询 3 时间范围查询 3.1 简单查询示例 3.2 关于时间的数学表达式(date-math) 3.3 关于时间的四舍五入 4 日期格式化范围查询(format) 5 时区范围查询(time_zone) 1 范围查询的符号 符号 含义 gte greater-than or equal to, 大于或等于 gt greater-than, 大于 lte less-than or equal to, 小于或等于 lt less-than, 小于 2 数值范围

MongoDB分片环境下的查询路由

根据2015-01-14官方文档快照翻译(v2.6.7 & v2.8.0-rc4) 翻译 shingo([email protected]) 在分片集群环境中,MongoDB通过 mongos实例来路由读写操作.从应用的角度来说,mongos 是访问集群的唯一入口,应用程序不能直接连接集群环境中的分片节点. 通过缓存config节点的元数据信息, mongos 可以跟踪到数据在哪个分片上.mongos 利用这些元数据信息将应用和客户端的操作路由到具体的mongod 实例.mongos 不提供持久

Elasticsearch+Mongo亿级别数据导入及查询实践

数据方案: 在Elasticsearch中通过code及time字段查询对应doc的mongo_id字段获得mongodb中的主键_id 通过获得id再进入mongodb进行查询   1,数据情况: 全部为股票及指数的分钟K线数据(股票代码区分度较高) Elasticsearch及mongodb都未分片且未优化参数配置 mongodb数据量: Elasticsearch数据量: 2,将数据从mongo源库导入Elasticsearch import time from pymongo impor

[Elasticsearch] 关于字段重复值的常用查询和操作总结

1. 取得某个索引中某个字段中的所有出现过的值 这种操作类似于使用SQL的SELECT UNIQUE语句.当需要获取某个字段上的所有可用值时,可以使用terms聚合查询完成: GET /index_streets/_search?search_type=count { "aggs": { "street_values": { "terms": { "field": "name.raw", "siz

每日学习心得:SharePoint 为列表中的文件夹添加子项(文件夹)、新增指定内容类型的子项、查询列表中指定的文件夹下的内容

前言: 这里主要是针对列表中的文件下新增子项的操作,同时在新建子项时,可以为子项指定特定的内容类型,在某些时候需要查询指定的文件夹下的内容,针对这些场景都一一给力示例和说明,都是一些很小的知识点,希望能够对大家有所帮助. 1.   在列表中为列表项添加子项 为列表添加子项大家都很熟悉,但是如何为列表项添加子项呢?例如列表项是一个文件夹,如何为该文件夹添加子项呢?这里就用到了List.AddItem()方法,具体示例如下: 首先我们要获取列表中的子项: SPListItem root_item=l

非结构化数据的存储与查询

当今信息化时代充斥着大量的数据.海量数据存储是一个必然的趋势.然而数据如何的存储和查询,尤其是当今非结构化数据的快速增长,对其数据的存储,处理,查询.使得如今的 关系数据库存储带来了巨大的挑战.分布存储技术是云计算的基础,主要研究如何存储.组织和管理数据中心上的大规模海量数据.由于面临的数据规模和用户规模更加庞大,在可扩展性.容错性以及成本控制方面面临着更加严峻的挑战[1]. 对于大量的半结构化数据(semi-structure data)和非结构化数据,对其存储和并发计算以及扩展能力而设计出了

为什么Elasticsearch不适合做数据存储?(转学习使用)

一.问题描述 公司想尝试使用Elasticsearch来存一部分数据,以此缓解数据增长带来的对数据库的压力.在研究了一段时间后,发现Elasticsearch不适合作为数据存储使用. 二.理由如下 1.mapping不可改,不能改index属性.Elasticsearch中以定义的mapping不能修改名字和属性,无法修改名字勉强能接受,但无法需要改属性. 官方文档中介绍了几种修改mapping的方法.一个是新建一个字段,程序中所有地方修改名字,这对于复杂的项目容易出错,而且无法保留原来的数据:

编写高质量代码改善C#程序的157个建议——建议26:使用匿名类型存储LINQ查询结果

建议26:使用匿名类型存储LINQ查询结果 从.NET3.0开始,C#开始支持一个新特性:匿名类型.匿名类型有var.赋值运算符和一个非空初始值(或以new开头的初始化项)组成.匿名类型有如下基本特性: 即支持简单类型也指出复杂类型.简单类型必须是一个非空初始值,复杂类型则是一个以new开头的初始化项. 匿名类型的属性是只读的,没有属性设置器,它一旦被初始化就不可更改. 如果两个匿名类型的属性值相同,那么就认为这两个匿名类型相等. 匿名类型可以再循环中用作初始化器. 匿名类型支持智能感知. 匿名