Elasticsearch核心技术与实战-学习笔记

Elasticsearch

  • es 提供了四种级别的倒排索引配置 ,可以控制倒排索引记录的内容,docs 记录docid ,freqs记录doc id 和term frequencies ,positions记录 docid,term frequencies, term positions, offset 记录 dicid,term frequencies, term positions, character offset

  • null_value 实现对 null的搜索

  • 多字段特性

  • index template 在索引创建时生效,修改template不会影响已经创建的索引,可以指定多个template,按照指定的order 合并在一起

    • 1、应用Elasticsearch默认的mappings和settings
    • 2、应用order 比较低的template
    • 3、应用order 比较高的template
    • 4、应用创建索引时指定的template
  • dynamic Template 是定义在某个具体的索引的Mapping中,template有一个名称,匹配规则是一个数组,为匹配到的字段设置mapping

  • 自我测试题

    • update 一个doc 需要使用post,而非put ,put 只能index和create,index和create的区别?
    • match_phrase的slop是什么意思
    • text字段类型设置not index时也不能被搜索到
  • 相关度算法

    • TF-IDF
    • BM25
  • 结构化查询 term 是包含而不是一个精确的相等

    • query 中boost和boosting查询,query context和filter context
  • 分词器

    • 哈工大标准
    • HanLP
    • 查字典
      • 北航梁南园教授
      • 哈工大-王晓龙,最小词数分词理论
    • 基于统计学模型(解决二异性词)清华郭进
    • 基于统计的机器学习算法
  • TMDB数据库

  • search template解耦搜索和dsl语言,使开发、搜索、性能工程师各司其职,类似数据库的存储过程的思想

  • 7版本以上不用设置min_master_number

  • 不设置副本分片会导致不能进行故障转移(提高读能力),主分片过小会导致,数据量增大后,不能水平扩展。主分片过打,导致每个分片数据量小,一个节点上的shard过多,也会影响性能。

  • 倒排索引的不可变性,一旦生成不能修改,好处:1、不用并发写,不会产生锁 2、便于加入内存,一旦加入内存,就留在哪里(内存足够大),提高缓存命中率 3、便于维护和压缩 坏处:1、需要重新建立,才能保证被搜索到(?建立segment就行吧)

  • refresh ,把index buffer写入segment(文件系统缓存),默认一秒一次。flush 把内存中的segment写入磁盘(调用fsync),默认30分钟。

  • index buffer默认10% JVM的大小,transaction log 默认大小512M, 满了后会触发对应的refresh和flush操作

  • merage 会自动合并磁盘上的segmen文件(多合并一个,真正的删除)

  • es的搜索分为两个阶段:query then fetch,query阶段各data节点会返回(from+size)doc id 和sort值,到协调节点,协调节点重新排序后,在通过muti-get获取到真正的doc,返回给调用者。

  • 排序

    • 默认,不能对text,进行排序。对text进行排序需要在mapping中该字段的fielddata设置成ture
    • 默认用,_scroe评分排序,用sort排序后, _scroe为null
    • 排序是对索引原文进行排序的,所以不能使用倒排索引,要使用正排索引
    • doc values 是正排索引,同时是列存数据,用来排序和聚合分析,在index时和倒排索引同时建立,占用磁盘空间,占用index时间,是ES2.x后默认使用的排序方式。不排序不聚合可以关闭掉。
    • field data是正排索引,是查询时才建立,不占用磁盘空间和index时间,但是占用java heap,数据量大时会引起OOM,ES 1.X的默认排序实现,现在已经不推荐使用。除非text排序和聚合分析用。
  • 分页

    • _search?scroll=5m 会建立一个查询时的快照,后插入的文档查询不到,5m应该时快照的存活时间,快照占用磁盘空间么?
  • 版本并发控制

    • 内部版本控制:if_seq_no+if_primary_term (原来的内部version 已经被废除了?)
    • 使用外部版本:version+version_type=external
  • 聚合分析

    • terms, 需要字段打开field data, keyword默认打开,text字段默认关闭field data ?
    • terms 可以通过设置mapping中字段的参数,使字段进行预计算,提高terms桶的性能
    • 聚合分析的作用域:query查询出来的结果集合,aggs中的filter,post_filter,global也可以从不同的方面影响聚合的结果集
  • 聚合分析的准确性:

    • 分布式大数据计算平台:数据量、准确性、实时性(等边三角形的顶点),只能满足两个。大数据量和准确性=hadoop离线计算平台
    • ES 计算不准确的原因是协调节点无法看到数据的全貌,解决方法(对terms聚合):
      • 数据量不大时,用一个主分片,数据是准确的
      • 设置shard_size,每个shard上多获取数据,来提高准确性,默认的shard_size=size*1.5+10
  • Elasticsearch的建模

    • 关系型数据库范式化设计的主要目的:减少不必要的更新。完全范式化面临查询缓慢的问题,join增多。
    • Elasticsearch主要考虑反范式化设计,嵌套对象和数组兑现的区别。嵌套对象的查询和聚合分析需要指定 nested path, 嵌套对象是存储在两个Lucence中
    • ES7中的父文档和子文档也是索引在一个索引中的,存储在一个分片(shard)中。和ES5.x中的type本质上没区别,嵌套对象和父子文档的区别
  • Elasticsearch重建索引

    • 场景:mappings 发生改变,settings主分片发生改变,集群内和集群间做迁移
    • 方法:
      • update by query :现有索引做重建
      • reindex:在其他索引上重建
        • _source 必须是enable
        • 必须先建立dest index的_setting,_mappings等
  • ingest node

    • ingest可以对index,_bulk 进入的es的数据进行预处理,想当于logstash的功能,默认每个节点都是ingest角色
  • painless script

    • 5.x引入,6.x之后只能用painless
    • 扩展了java语法,支持所有的java类型和API,支持动态定义类型
    • 用于对文档字段的加工处理
      • 更新删除字段,处理聚合,script filed,function score
      • ingest pipleline中执行
      • reindex,update_by_query中对数据进行处理
    • 编译开销想当大,默认缓存100个编译后的脚本,可以调整缓存大小和编译频率,缓存超时等
  • 数据建模

    • 数据建模的一般过程 概念模型-》逻辑模型-》数据模型(第三范式),考虑功能需求和性能需求

    • 字段类型选择-》是否全文检索-》是否聚合排序-》是否额外存储

      • _source enable为false结合store为true使用,一般不建议关闭_source,不能reindex和update
      • term 查询在query 和 filter 上下文中表现是否一致
    • 建模建议

      • 文档关系: object=>nested=>父子关系;

        • kibana对nested和父子关系支持不好,做数据可视化需要作出取舍
      • 一个文档中字段不要过多,mappings保存在cluster state中,字段过多会造成性能问题

        • mapping中字段默认不能超过1000,
        • 字段过多通常是由于 dynamic mapping 开启造成的,可以使用nested object和key/value的方法解决
      • 避免正则查询

        • 解决方法:冗余或拆分字段,用空间换时间
      • 避免null值导致聚合不准确

      • 为mapping加入meta信息进行版本管理(结合git)

  • 第二部分总结

    • term 查询和 match查询的区别
      • term是精确(不论是text还是keyword)
      • match对text是会做分词查询,对keyword会自动转换成term查询
    • filter context和query context的区别(不理解)
      • filter 避免算分且利用缓存
      • bool中filter和must not 都是filter
  • 集群安全

    • server host:0.0.0.0 四个零代表什么?
    • 可以通过tls和ca证书来保护9300端口在节点间的信息传输,防止未经认证的节点加入集群和传输泄密
  • 集群部署

    • 节点角色

      • master eligible node

        • 主备节点:管理集群状态,负责index的创建、分片管理、、mapping元数据等
        • 机器配置:低cpu\低内存\低磁盘
      • data node

        • 负责数据的存储、搜索和聚合计算
        • 机器配置:高cpu\高内存\高磁盘
      • ingest node

        • 负责数据处理
        • 机器配置:高cpu/高内存/低磁盘
      • coordinate node(协调节点)

        • 扮演loadbance 角色。降低master和node的负载,负责搜索查询结果的聚合和reduce
        • 机器配置:高cpu\高内存\低磁盘
      • marching learning node

    • 部署方式

      • 协调节点:数据节点:master节点
      • 读写分离方式 协调节点|ingest节点:数据节点:master节点
      • 可以通过设置节点属性来实现hot/warm和不同机架分布
    • 环境参数检查

      • jvm 参数:
        • xms 和 xmx 设置一样,避免resize时造成停顿
        • jvm 有swapping 的功能么?
      • 集群参数设置的四种范式和优先级
        • transient settings
        • persistent settings
        • command-line settings
        • config file settings
      • os参数设定的要求
    • 集群监控

      • 有_cluster|_nodes /stats和index/_stats 三个级别的状态监控
      • _tasks和_cluster/_pending_tasks查看任务
      • _nodes/thread_pool和_nodes/stats/thread_pool 和 _cat/thread_pool 和_nodes/hot_threads 可以查看集群相关的信息
    • 集群健康状态

      • 分片健康、索引健康、集群健康,可以通过api查看三个级别的健康状况
      • 分片为分配的原因,可以通过_cluster/allocation/explan 查看
      • 分片没有分配的其他原因
        • 新建索引有短暂的变红
        • 集群重启阶段
        • index_reopen
        • Dangling_index_reimported ,一个节点离开集群期间,有索引被删除,这个节点再回来时会导致dangling问题,再删除一次索引可以解决
    • 提高集群的写入

      • bluk api/线程数量,查看是否返回429,需要自动重试和调整线程数量
      • 使用es自己生成的doc id,用自己的id时,es在index时会先有get操作
      • 减少不必要的cpu和存储开销(不必要的分词、doc values,文档字段顺序相同,提高压缩率)
      • 最重要的是高质量的数据建模
      • 关闭不必要的功能
        • 只聚合不搜索:index 设置成false
        • 不需要算分 norms设置成false
        • 不要对字符串使用默认的dynamic mappings
        • index_options 控制倒排索引的内容,可以节约一定量的cpu
        • 关闭_source(使用于指标型数据,影响reindex和update)
      • 调整写入过程参数
        • refresh
          • refresh_interval和静态参数indices.memory.index_buffer_size一同调节
        • translog
          • index.translog.durability,默认request(每次请求落盘),async 实现异步写入
          • index.translog.sync_interval设置60s,每分钟写一次
          • index.translog.flush_threshod_size:512mb,超过后也会出发flush
        • flush
          • es自动完成,可调整内容不多
    • 提高集群的读性能

      • 尽可能的反规范化
        • nested 会慢几倍
        • parent/children 会慢几百倍
      • 尽量先计算,避免script
      • 尽量使用filter context,利用缓存减少不必要的算分
      • 结合profile和explan api 查找原因
        • 严禁使用* 开头的通配符查询,严重影响集群性能
      • force-merge read-only 索引
  • Elasticsearch测试

    • ES官方的开源测试工具Elastic Rally
    • Elasticsearch 段合并优化
      • es 的一个shard = Luence的一个index
        • Lucence的一个index 包含多个 segment,segment commits 记录一个index的所有 segment
      • 优化方法
        • 一、降低segment 产生的数量和频率
          • refresh interval和indices.memory.index_buffer_size
          • 减少更新
        • 二、避免大段参与合并
          • 设置segment段的最大大小
            • index.merge.policy.max_merged.segment
            • index.merge.policy.segments_per_tier 什么含义呢?
    • Elasticsearch 缓存
      • 分类
        • node query cache: 每个节点都有,所有shard共享,缓存 filter context查询,segment合并失效
        • shard query cache:shard 所有,缓存agg查询,refresh时失效
        • field data cache,缓存text 分词后做聚合查询用,默认无限制,默认不释放,需要设置大小和断路器
      • 断路器的分类和设置
    • 索引管理
      • shrink 和 reindex api的区别
        • shrink 比 reindex 性能更好,shrink是通过segment硬连接的方式,链接到统一索引,性能比较好
        • shrink 限制比较多
          • 源shard数据,必须是目标shard数的倍数,如果源是素数,目标必须是1
          • 源shard必须在同一个node上
          • 分片只读,集群绿色等
      • split 和 reindex api的区别
        • 性能更好
        • 限制更多
          • 目标shard数是源shard 数的倍数
          • 分片只读
          • 不要求分片在同一个node上
      • rollover api 可以实现索引的滚动新建立
        • 当索引存活超过一定时间、超过设定文档数、超过设定大小会重新建立索引(log4j的appender)
        • 但是不会自动触发,需要结合索引管理使用
posted @ 2020-05-01 16:52  wangzhen3798  阅读(459)  评论(0编辑  收藏  举报