首页 > 其他分享 >14.ElasticSearch系列之分布式特性及分布式搜索机制(三)

14.ElasticSearch系列之分布式特性及分布式搜索机制(三)

时间:2022-10-20 21:25:38浏览次数:69  
标签:search 14 文档 分片 ElasticSearch desc 排序 order 分布式

1. 刨析分布式查询及相关性算分

1.1 分布式搜索的运行机制
  • ElasticSearch的搜索,会分为两阶段进行
    • 第一阶段 Query
    • 第二阶段 Fetch
  • Query Then Fetch
1.2 Query阶段
  • 用户发出搜索请求到ES节点。节点收到请求后,会已Coordinating节点的身份,在6个主副中随机选择3个分片,发送查询请求
  • 被选中的分片执行查询,进行排序。然后,每个分片都会返回FROM + Size个排序后的文档ID和排序值给Coordinating节点
1.3 Fetch阶段
  • Coordinating节点会将Query阶段,从每个分片获取的排序后的文档ID列表,重新进行排序。选取From到From+Size个文档的ID
  • 以multi get请求的方式,到响应的分片上获取详细的文档数据
1.4 Query Then Fetch潜在的问题
  • 性能问题
    • 每个分片上需要差的文档个数=from+size
    • 最终协调节点需要处理: number_of_shard*(from+size)
    • 深度分页
  • 相关性算分
    • 每个分片都基于自己分片上的数据进行相关性算分。这回导致打分偏离的情况,特别是数据量很少时。相关性算分在分片之间相互独立。当文档总数很少的情况下,如果主分片大于1,主分片数越多,相关性算分会越不准。

解决算分不准的方法

  • 数据量不大的时候,可以将主分片数设置为1
    • 当数据量足够大时候,只要保证文档均匀分散在各个分片上,结果一般就不会出现偏差
  • 使用DFS Query Then Fetch
    • 搜索的URL中指定参数_search?search_type=dfs_query_then_fetch
    • 会到每个分片把各分片的词频和文档频率进行搜集,然后完整的进行一次相关性算分,耗费更加多的CPU和内存,执行性能低下,一般不建议使用

2. 排序与Doc Values&FieldData

2.1 代码实操
# 按日期排序,可以发现_score为null
POST /kibana_sample_data_ecommerce/_search
{
  "size": 5,
  "query": {
    "match_all": {

    }
  },
  "sort": [
    {"order_date": {"order": "desc"}}
  ]
}
# 多字段排序
POST /kibana_sample_data_ecommerce/_search
{
  "size": 5,
  "query": {
    "match_all": {

    }
  },
  "sort": [
    {"order_date": {"order": "desc"}},
    {"_doc":{"order": "asc"}},
    {"_score":{ "order": "desc"}}
  ]
}
# 对 text 字段进行排序。默认会报错,需打开fielddata
POST /kibana_sample_data_ecommerce/_search
{
  "size": 5,
  "query": {
    "match_all": {

    }
  },
  "sort": [
    {"customer_full_name": {"order": "desc"}}
  ]
}
# 打开 text的 fielddata,然后再次执行上述查询
PUT kibana_sample_data_ecommerce/_mapping
{
  "properties": {
    "customer_full_name" : {
          "type" : "text",
          "fielddata": true,
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        }
  }
}
# 关闭 keyword的 doc values
PUT test_keyword
PUT test_keyword/_mapping
{
  "properties": {
    "user_name":{
      "type": "keyword",
      "doc_values":false
    }
  }
}

PUT temp_users
PUT temp_users/_mapping
{
  "properties": {
    "name":{"type": "text","fielddata": true},
    "desc":{"type": "text","fielddata": true}
  }
}
POST temp_users/_doc
{"name":"Jack","desc":"Jack is a good boy!","age":10}

# 打开fielddata 后,查看 docvalue_fields数据
POST  temp_users/_search
{
  "docvalue_fields": [
    "name","desc"
    ]
}
# 查看整型字段的docvalues
POST  temp_users/_search
{
  "docvalue_fields": [
    "age"
    ]
}
2.2 排序的过程
  • 排序是针对字段原始内容进行。倒排索引无法发挥作用
  • 需要用到正排索引。通过文档ID和字段快速得到字段原始内容
  • ElasticSearch两种实现方法
    • Fielddata
    • Doc Values(列式存储,对Text类型无效)
2.3 Doc Values与Field Data对比
Doc Values Field Data
何时创建 索引时,和倒排索引一起创建 搜索时动态创建
创建位置 磁盘文件 JVM Heap
优点 避免大量内存占用 索引速度快,不占用额外磁盘空间
缺点 降低索引速度,占用额外磁盘空间 文档过多时,动态创建开销大,占用过多JVM Heap
2.3 关闭Doc Values
  • 默认启用,可以通过mapping设置关闭
    • 增加索引的速度 / 减少磁盘空间
  • 如果重新打开,需要重建索引
  • 当明确不需要做排序或聚合分析时可以关闭

欢迎关注公众号算法小生沈健的技术博客

标签:search,14,文档,分片,ElasticSearch,desc,排序,order,分布式
From: https://www.cnblogs.com/shenjian-online/p/16811335.html

相关文章

  • 16.ElasticSearch系列之深入聚合分析
    深入理解聚合分析原理及精确性问题1.MetricAggregation单值分析,只输出一个分析结果minmaxavgsumcardinality(类似distinctcount)多值分析,输出多个分析结......
  • 11.ElasticSearch系列之搜索相关性算分机制
    1.相关性和相关性算分1.1相关性搜索的相关性算分,描述了一个文档和查询语句匹配的程度。ES会对每个匹配查询条件的结果进行算分_score打分的本质是排序,需要把最符合用......
  • Hyperf使用ElasticSearch记录
    Hyperf安装Elasticsearch协程客户端hyperf/elasticsearch主要为elasticsearch-php进行了客户端对象创建的工厂类封装,elasticsearch-php默认使用GuzzleRing客户......
  • ARC145
    \(\mathcal{ARC}\mathsf{145}\)tasks$\color{Green}{★}\\$表示赛时做出。$\color{Yellow}{★}\\$表示赛后已补。$\color{Red}{★}\\$表示\(\mathcal{To\......
  • 分布式之计算高性能
    @目录一、计算高性能的概念二、PPC方案[懒加载]三、prefork方案[预先加载进程方案]四、TPC方案五、prethread方案六、线程池方案七、线程池--轮询方案八、多路复用-React......
  • ctfshow web147(create_function函数命令执行)
    if(isset($_POST['ctf'])){$ctfshow=$_POST['ctf'];if(!preg_match('/^[a-z0-9_]*$/isD',$ctfshow)){$ctfshow('',$_GET['show']);}}首先第......
  • ctfshow web145
    if(isset($_GET['v1'])&&isset($_GET['v2'])&&isset($_GET['v3'])){$v1=(String)$_GET['v1'];$v2=(String)$_GET['v2'];$v3=(String)$_GET['v3']......
  • 【Python】第3章-14 字符串字母大小写转换
    本题要求编写程序,对一个以“#”结束的字符串,将其小写字母全部转换成大写字母,把大写字母全部转换成小写字母,其他字符不变输出。输入格式:输入为一个以“#”结束的字符串(不......
  • P7914 括号序列
    \(\rmP7914\)[CSP2021]括号序列加深理解做题简记。这里觉得第一篇题解的做法是最优秀的,因为这才是真正的dp强调的不重不漏。这个做法只设了一个dp数组,应该跟其他设......
  • 漏洞分析:MS14-058(CVE-2014-4113)
    作者:selph漏洞分析:CVE-2014-4113漏洞介绍漏洞程序MicrosoftWindows是美国微软(Microsoft)公司发布的一系列操作系统。win32k.sys是Windows子系统的内核部分,是一个内核模......