Es5.x版本研究

Posted wingooom

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Es5.x版本研究相关的知识,希望对你有一定的参考价值。

概述

Elasticsearch 5.0.0 GA, 基于Lucene 6.2.0。Elasticsearch 5.0.0 带来了大量的改进和新功能,与之前的版本相比更快、更安全、更具有弹性,也更容易使用。

本文主要分为两部分。第一部分从整体上,了解Es5.x版本的新特性及进行这些改变的初衷。第二部分从具体功能细节了解新版本的改变。

新的数据结构

block k-d tree

Lucene 6.x针对 numeric and geo-point 字段添加了新的点型数据结构 ——dimensional points Fields,多维浮点字段。该数据结构使用基于k-d树的地理空间数据结构来提供快速的单维或多维数值范围和地理空间点的过滤。

数据结构采用的是改进的k-d树——block k-d tree 。block k-d tree 对IO效率做了特殊处理,使得大部分数据结构驻留在磁盘块上,在搜索时,使用小的堆内二叉树索引结构来定位块。

这意味着最终能够使用Lucene来有效地索引和范围过滤任何可以被编码为固定长度,有序字节的东西,比如IPv6 InetAddress,BigInteger,BigDecimal等,以及2D和3D或更高维度的地理空间索引和时间序列值。

对于数值型(IP,时间,数值)和geo_point的性能有很大的提高。

half_float 和 scaled_float

添加了两个新的数值字段类型 half_float 和 scaled_float

  • half_float : 16位的半精度浮点型。
  • scaled_float:固定比例的浮点型。内部存储为long。该字段类型需要指定比例因子scaling_factor。
PUT my_index

  "mappings": 
    "my_type": 
      "properties": 
        "number_of_bytes": 
          "type": "integer"
        ,
        "time_in_seconds": 
          "type": "half_float"
        ,
        "price": 
          "type": "scaled_float",
          "scaling_factor": 100
        
      
    
  

例如:
scaled_float 若比例因子为10,则2.34 会存储为23 ,所有的搜索操作(queries, aggregations, sorting) 会匹配文档中的2.3。 高的比例因子scaling_factor会提高精度,但是也会增加存储负担。

text和keyword类型

string类型移除,被Text和Keyword两种类型代替。

  • text 类型的数据用于全文检索(analyzed string)
  • keyword类型的用于关键词完全匹配搜索(not_analyzed string )。

    新的默认类型

索引如下内容:


  "foo": "bar"

新的默认创建的mapping如下:


  "foo": 
    "type" "text",
    "fields": 
      "keyword": 
        "type": "keyword",
        "ignore_above": 256
      
    
  

既可以对foo字段全文检索, 也可以对foo.keyword实现关键词搜索和聚合。

可以通过指定string类型或动态模板(dynamic template )来禁用这个功能。
通过如下的动态模板来存储es2.x中的dynamic mappings


  "match_mapping_type": "string",
  "mapping": 
    "type": "text"
  

原string类型迁移

原_1:


  "foo": 
    "type" "string",
    "index": "analyzed"
  

新_1:


  "foo": 
    "type" "text",
    "index": true
  

原_2


  "foo": 
    "type" "string",
    "index": "not_analyzed"
  

新_2


  "foo": 
    "type" "keyword",
    "index": true
  

注意:string类型暂时还在,es6.0会移除

dots-in-fieldnames

重新支持dots-in-fieldnames。

foo.bar 表示字段bar内嵌在字段foo中.

索引性能

通过采用更好的新的数值型数据结构,减少同一文档并发更新时竞争锁的冲突,同步(fsyncing )事务日志时,减少锁的使用,优化GET操作接口等改变,使得索引吞吐量有了很大的提升。

根据不同的案例,索引吞吐量有25% - 80%的性能提升。

预处理节点(Ingest Node)

Ingest 节点是 Elasticsearch 5.0 新增的节点类型和功能。其开启方式为:在 elasticsearch.yml 中定义:

node.ingest: true

Ingest 节点的基础原理,是:节点接收到数据之后,根据请求参数中指定的管道流 id,找到对应的已注册管道流,对数据进行处理,然后将处理过后的数据,按照 Elasticsearch 标准的 indexing 流程继续运行。

管道Pipeline

管道定义包括一个描述description和可有多个处理器组合的processors。处理器的执行顺序即为定义的顺序。

管道添加:put

PUT _ingest/pipeline/my-pipeline-id

  "description" : "describe pipeline",
  "processors" : [
    
      "convert" : 
        "field": "foo",
        "type": "integer"
      
    
  ]

相应的有对管道查看Get,删除Delete,仿真测试Simulate操作的API。

处理器Processer

Es5.0内置有20个处理器,包括常用的grok, date, gsub, removerenameconvert,lowercase/uppercase,。

以及三个以插件性质单独发布的处理器 attachementgeoipuser-agent 。原因应该是这 3 个处理器需要额外数据模块,而且处理性能一般,担心拖累 ES 集群。

它们可以和其他普通 ES 插件一样安装:

sudo bin/elasticsearch-plugin install ingest-geoip

使用和其他处理器一样。

Painless 脚本

开发了新的脚本语言Painless scripting。该脚本语言对es来说更快更安全。也作为新的默认的脚本,而不再使用Groovy,javascript, 和Python作为默认的脚本语言。

Painless是一个与Groovy相似的动态脚本语言。支持Java的lambda表达式。

Getting Started with Painless

检索和聚合(Search and Aggregations)

优化时间查询时的聚合操作。若查询条件不变,聚合操作会返回缓存的结果。若是查询时间变化,则会重新计算聚合操作。比如统计时间为前30天的数据。

 "gte": "now-30d", "lte": "now" 

当now发生变化时,之前的版本会重新计算聚合结果。而优化后,now会被重写为具体的值,每个shard会根据自己的数据的范围来重写查询为 match_all或者是match_none查询,所以现在的查询能够被有效的缓存。并且只有个别数据有变化的Shard才需要重新计算,大大提升查询速度。

另外,

  • 直方图的聚合(histogram aggregations)支持小数的buckets ,能正确的处理负数的取整操作。
  • 词的聚合(terms aggregations)可以更有效计算以避免合并爆炸(combinatorial explosion)的风险。
  • Profile API 支持了聚合aggregations操作。
  • 相关性得分从TF/IDF ,改为更先进的BM25.
  • 通过search_after实现高效的深度分页查询。

通过将Scroll请求,可以分成多个Slice请求,各Slice独立并行,可并发来进行数据遍历。

GET /twitter/tweet/_search?scroll=1m

    "slice": 
        "id": 0, 
        "max": 2 
    ,
    "query": 
        "match" : 
            "title" : "elasticsearch"
        
    

GET /twitter/tweet/_search?scroll=1m

    "slice": 
        "id": 1,
        "max": 2
    ,
    "query": 
        "match" : 
            "title" : "elasticsearch"
        
    

Java REST client

发布了Java Low Level REST Client。基于java 7,有更少的依赖和依赖冲突,性能与transport client相似

用户友好性

rollover and shrink APIs

Shrink API 允许缩减一个索引的分片为它的因子数。如原索引有15个分片,则可以收缩为5或3或1个分片的索引。

缩减分片数之前,必须保证索引是只读的,并且索引中每个分片的副本必须在同一个节点上,以及集群的健康为绿色。可通过以下命令实现:

PUT /my_source_index/_settings

  "settings": 
    "index.routing.allocation.require._name": "shrink_node_name", 
    "index.blocks.write": true 
  

应用场景:
在写入压力非常大的收集阶段,设置足够多的索引,充分利用shard的并行写能力,索引写完之后收缩成更少的shard,提高查询性能,减少存储负担

Rollover API,若存在的索引(该索引有一个别名,且该别名只指向一个索引)满足一定条件——超过一定时间或者文档数量超过设定阈值,则会自动创建一个新的索引,并且将该别名指向新的索引。

索引管理更友好

  • 创建索引更容易,不必等待集群健康为绿色 wait_for_status=green
  • 创建索引的请求只有在索引准备好使用了后才返回响应。
  • 新创建的索引不会再使集群健康变为红色,不会因为这个卡死集群,使得系统管理员在夜里可以安心睡眠。

如果分片分配出现问题,es不再无限制的尝试分配分片,从而导致日志不断增加,磁盘被占满。而是在尝试5次后,等待被人工处理。
增加了 Cluster Allocation Explain API,方便管理员去找到分片未成功分配的原因。

弃用日志deprecation logging ,启用该日志功能后,若正在调用的接口是已经要被废弃的功能,则会记录下日志。

健壮性(Resiliency)

  • 为了避免命名冲突,索引使用UUID作为数据物理路径名,而不是索引名字
  • 集群状态的改变现在会和所有节点进行确认
  • Shard的一个副本如果失败了,Primary标记失败的时候会和Master节点确认完毕再返回
  • 为了避免配置错误而导致集群不稳定,Es5.x会执行启动检查( bootstrap checks )。开发者模式下,启动检查到的错误信息会作为告警记录在日志中;正式产品模式下,启动检查失败会导致启动失败。
  • 添加了请求中的熔断器(The in flight requests circuit breaker),允许Elasticsearch限制在传输或HTTP级别上的所有当前活动的传入请求的内存使用超过节点上的一定量的内存。 内存使用是基于请求本身的内容长度。
  • 添加了很多软限制(soft limit)来保护系统的稳定性。比如默认的搜索超时,限制一个mapping中的字段的数量,在text字段禁用字段数据(fielddata )的加载,限制单个搜索请求的分片数量

迁移助手(Migration Helper)

es插件

帮助从Elasticsearch 2.3.x/2.4.x 迁移升级到 Elasticsearch 5.0。

注意,该助手只适用于 2.3.x and 2.4.x。

助手安装说明

./bin/plugin install https://github.com/elastic/elasticsearch-migration/releases/download/v2.0.4/elasticsearch-migration-2.0.4.zip

系统升级说明

Es5.x重大改变

以下主要内容来自ApacheCN 开源组织,主要从具体细节介绍Es5.x版本的改变。官方文档原文地址

5.0重大改变

第一次Elasticsearch 5.0启动时,它将自动重命名索引文件夹以使用索引UUID而不是索引名称。如果对共享数据文件夹使用shadow replicas,请首先启动对所有数据文件夹具有访问权的单个节点,并在启动群集中的其他节点之前重命名所有索引文件夹。

搜索和查询DSL改变

  • search_type = count 被移除
  • search_type = scan 被移除
  • 在5.0中,Elasticsearch拒绝将查询超过1000个分片副本(初级或副本)的请求。可通过action.search.shard_count.limit设置更大的值
  • fields参数已替换为stored_fields。 stored_fields参数将只返回存储的字段 - 它将不再从_source中提取值
  • fielddata_fields已弃用,请改用参数docvalue_fields
  • search-exists API 已删除,有利于使用大小设置为0和terminate_after设置为1的搜索API
  • 已弃用的查询已删除,包括filtered,and,or(可通过bool中的filter、must、should代替),missing,limit(改用terminate_after)等
  • 默认的相似性计算方法改为BM25
  • 排序sort中,reverse参数被删除,可通过order指定明确的排序方式

映射改变

  • string字段替换为text / keyword 字段
  • 默认字符串映射改变

  "type": "text",
  "fields": 
    "keyword": 
      "type": "keyword",
      "ignore_above": 256
    
  

这允许对原始字段名称执行全文搜索,并在子关键字字段上对聚合进行排序和运行

  • 数字字段。数字字段现在用完全不同的数据结构(称为BKD树)索引,预期需要更少的磁盘空间,并且对于范围查询比之前索引数字的方式更快
  • _timestamp_ttl现在已删除
  • index 属性。index属性现在只接受true / false,而不接受not_analyzed / no。字符串字段仍接受analyze / not_analyzed / no
  • 当动态映射包含浮点数的字段时,该字段现在默认使用float而不是double
  • 为了防止映射爆炸,以下限制应用于在5.x中创建的索。索引中的最大字段数限制为1000,字段的最大深度(1加上对象或嵌套父对象的数量)限制为20,索引中嵌套字段的最大数量限制为50。
  • 在5.0之后不允许在映射中出现空字段名称

配置改变

  • 以前,ping超时有三个设置:discovery.zen.initial_ping_timeoutdiscovery.ze n.ping.timeoutdiscovery.zen.ping_timeout。前两个已被删除,并且ping超时的唯一设置键现在是discovery.zen.ping_timeout。 ping超时的默认值保持为3秒
  • node.client设置已删除。具有此设置集的节点将不会启动。相反,每个节点角色需要使用现有的node.masternode.datanode.ingest支持的静态设置分别设置
  • 具有netty中缀的所有设置已由其现有的传输同义词替换。例如transport.netty.bind_host不再受支持,应该由替代设置transport.bind_host替换
  • 禁用安全管理器security.manager.enabled的选项已删除。为了给予elasticsearch用户特殊权限,用户必须编辑本地Java安全策略
  • 不再支持index.translog.flush_threshold_ops设置。为了基于事务日志增长来控制刷新,请改用index.translog.flush_threshold_size
  • index.translog.interval has been removed
  • cluster.routing.allocation.concurrent_recoveries设置已替换为cluster.routing. allocation.node_concurrent_recoveries
  • index.memory.min_shard_index_buffer_sizeindices.memory.max_sha rd_index_buffer_size已删除,因为Elasticsearch现在允许任何一个分片使用堆的数量,只要所有分片中使用的总索引缓冲堆低于节点的indices.memory.index_buffer_size(默认值到JVM堆的10%)
  • 删除es.max打开文件
  • 删除对.properties配置文件的支持
  • 不能再通过设置系统属性来配置Elasticsearch,如不再支持通过ES_JAVA_OPTS环境变量设置
ES_JAVA_OPTS=$ES_JAVA_OPTS -Des.name.of.setting=value.of.setting

相反,应该使用-Ename.of.setting=value.of.setting

  • node.max_local_storage_nodes的默认值现在是一个
  • 设置bootstrap.mlockall已重命名为bootstrap.memory_lock

其他

  • update API和bulk API中,fields 已被弃用,应该使用_source从_source加载字段
  • 重新路由命令allocate已分为两个不同的命令allocate_replicaallocate_empty_primary
  • 在5.0之前,仅当设置http.compressed设置为true时,Elasticsearch才接受压缩的HTTP请求。 Elasticsearch现在接受压缩请求,但只有在http.compressed设置为true时,才会继续发送压缩响应
  • 切换默认脚本语言从Groovy到Painless

以上是关于Es5.x版本研究的主要内容,如果未能解决你的问题,请参考以下文章

上线必备 | 高性能ES5.X部署配置清单

ES5.x ElasticSearch使用一文全包含

无外网环境下ES5.x安装sql插件

使用链表堆栈的中缀到后缀转换器

计算器核心算法——中缀表达式转为后缀表达式

快速上手 Kotlin 开发系列之中缀表达式