Elasticsearch笔记

语雀完整版:

https://www.yuque.com/g/mingrun/embiys/sk87rd/collaborator/join?token=c7eWdXniQNPJCBYC&source=doc_collaborator# 《Elasticsearch》

尚硅谷Elasticsearch

第1章 Elasticsearch概述

  1. 概述
    主要是为了全文搜索
  1. es和solor
    • 他俩都是基于 Lucene
    • 后者更易使用 且是分布式的,在日志、监控系统中用的比较多
    • 前者更成熟

第2章 Elasticsearch入门

安装

  1. doker、windows

基本操作

  1. 数据格式
    其中 es的type6中只能创建一个,7中已被删除,而且他这个接口 和mogo的差别 就只在 mogo对应的数据库结构是 collection(集合)

  1. Http操作
    • 索引:增删查
    • 文档:增删改查,修改字段
    • 映射(相当于表结构):创建、查看、与索引关联
    • 高级查询
  1. Java Api操作
    • 引入依赖 elasticsearchelasticsearch-rest-high-level-client
    • 索引操作
    • 文档操作(这里看到了 创建文档要指定一个索引)
    • 高级查询

第3章 Elasticsearch环境

  1. 相关概念
    • 节点:一个节点就是一个服务器,他作为集群的一部分,它存储数据,参与集群的索引与搜索功能
  1. windows集群
  1. linux集群

第4章 Elasticsearch进阶

核心概念

  1. 索引(Index)
    能更快,像书籍的目录
  1. 类型(Type)
    为什么type类型被取缔了:原本是想着 索引对应数据库,type对应表,文档对应行,字段对应列,但是索引是可以直接关联数据的,所以就不应该存在type
  1. 文档(Document)
    一条数据,json格式
  1. 字段(Field)
    一个字段
  1. 映射(Mapping)
    处理数据的方式和规则
  1. 分片(Shards)
    • 就是单个节点不可能放太多数据,这就类似于mysql中的分表,需要把数据 分散到多个节点上,每个节点上的数据 叫分片,合在一块才构成完整数据
  1. 副本(Replicas)
    对每一份数据多一份拷贝,而且我还可以在副本上查询,这样就提高了吞吐量
  1. 分配(Allocation)
    将分片分配个某个节点的过程

系统架构

这里的主节点作用没搞明白

分布式集群

  1. 单节点集群
    • 主分片在创建索引的时候就已经确定了,不可更改
    • 如果主分片和副本在同一台服务器上,那么就有数据丢失的风险

       

  1. 故障转移
    启动第二个节点,备份数据就会移到这个节点上

  1. 水平扩容
    • 为了让运行中的程序按需扩容,可以启动第三个节点,分片就会重新分配

    • 节点如何扩容?
      主分片节点不可修改,它是在创建索引的时候创建的,但可以修改副本分片的数量

    • 上面修改副本分片数量 并不能提高性能,同时还要增加节点数量(服务器)才行
  1. 故障转移
    停掉一个节点,会发现,节点二提升为主节点,会丢失副本,原来丢掉的主分片的副本 会提升为主分片

路由计算

如下所示,它是用与计算 文档写入的时候,写到哪个分片上,这也解释了 为什么索引创建后,主分片数量就不能再改了

分片控制

  1. 处理请求的节点叫做 协调节点,每个节点都知道集群中任一文档的位置
  1. 写流程
    • 收到客户端的请求后,在集群内部,也就是一个协调节点,通过路由确定分片,主分片写入后,再同步给副本节点,然后再给客户端一个反馈

    • 上面主节点同步给副本节点又多个策略
      • 主节点写入后就反馈给客户端
      • 全部副本都要写入
      • 大部分副本要写入(默认)
  1. 读流程

  1. 更新流程

  1. 批量操作

分片原理

  1. 倒排索引
    • 分片是es中的最小工作单元,向分片写入数据的过程 会建立倒排索引
    • 正向索引,它是 id对应着不同的不同的关键词

    • 倒排索引,它是关键词对应着不同的id

      • 词条:文档拆分成的单独的词
  1. 动态更新索引
    看不懂 反正就是分段了

  1. 近实时搜索
  1. 持久化变更
  1. 段合并
    上面这仨 看儒袁的总结下
  1. 文档分析(ik)
  1. 文档冲突处理
    通过 cas的version号来处理
  1. kibanan

第5章 Elasticsearch集成

继承springdata、spark Streaming、Flink

第6章 Elasticsearch优化

硬件、分片策略、路由选择、写入速度优化、内存设置、重要配置

第7章 Elasticsearch面试题

  1. ES结构
    • 一个集群包含1个或多个节点:
    • 一个节点包含1个或多个索引;
    • 一个索引:类似Mysql中的数据库;
    • 每个索引又由一个或多个分片组成;
    • 每个分片都是一个 Lucene索实例,您可以将其视作一个独立的搜索引擎它能够对Elasticsearch
      集群中的数据子集进行索引并处理相关查询;
    • 每个分片包含多个segment (段)每一 个segment都是一 个倒排索引。
  1. 为什么要使用Elasticsearch?
    系统中的数据,随着业务的发展,时间的推移,将会非常多,而业务中往往采用模糊查询进行数据的搜索,而模糊查询会导致查询引擎放弃索引,导致系统查询数据时都是全表扫描,在百万级别的数据库中,查询效率是非常低下的,而我们使用ES做一个全文索引,将经常查询的系统功能的某些字段,比如说电商系统的商品表中商品名,描述、价格还有id这些字段我们放入ES索引库里,可以提高查询速度。
  1. Elasticsearch的master选举流程?
    • Elasticsearch的选主是ZenDiscovery模块负责的,主要包含Ping(节点之间通过这个RPC来发现彼此)和Unicast(单播模块包含一个主机列表以控制哪些节点需要ping通)这两部分
    • 对所有可以成为master的节点(node.master: true)根据nodeId字典排序,每次选举每个节点都把自己所知道节点排一次序,然后选出第一个(第0位)节点,暂且认为它是master节点。
    • 如果对某个节点的投票数达到一定的值(可以成为master节点数n/2+1)并且该节点自己也选举自己,那这个节点就是master。否则重新选举一直到满足上述条件。
    • master节点的职责主要包括集群、节点和索引的管理,不负责文档级别的管理;data节点可以关闭http功能。
  1. Elasticsearch集群脑裂问题?
    • “脑裂”问题可能的成因:
      • 网络问题:集群间的网络延迟导致一些节点访问不到master,认为master挂掉了从而选举出新的master,并对master上的分片和副本标红,分配新的主分片
      • 节点负载:主节点的角色既为master又为data,访问量较大时可能会导致ES停止响应造成大面积延迟,此时其他节点得不到主节点的响应认为主节点挂掉了,会重新选取主节点。
      • 内存回收:data节点上的ES进程占用的内存较大,引发JVM的大规模内存回收,造成ES进程失去响应。
      • 脑裂问题解决方案:
      • 减少误判:discovery.zen.ping_timeout节点状态的响应时间,默认为3s,可以适当调大,如果master在该响应时间的范围内没有做出响应应答,判断该节点已经挂掉了。调大参数(如6s,discovery.zen.ping_timeout:6),可适当减少误判。
      • 选举触发: discovery.zen.minimum_master_nodes:1
        该参数是用于控制选举行为发生的最小集群主节点数量。当备选主节点的个数大于等于该参数的值, 且备选主节点中有该参数个节点认为主节点挂了,进行选举。官方建议为(n/2)+1,n为主节点个数 (即有资格成为主节点的节点个数)
      • 角色分离:即master节点与data节点分离,限制角色
        主节点配置为:node.master: true node.data: false
        从节点配置为:node.master: false node.data: true
  1. Elasticsearch索引文档的流程?

    • 协调节点默认使用文档ID参与计算(也支持通过routing),以便为路由提供合适的分片:
      shard = hash(document_id) % (num_of_primary_shards)
    • 当分片所在的节点接收到来自协调节点的请求后,会将请求写入到Memory Buffer,然后定时(默认是每隔1秒)写入到Filesystem Cache,这个从Memory Buffer到Filesystem Cache的过程就叫做refresh;
    • 当然在某些情况下,存在Momery Buffer和Filesystem Cache的数据可能会丢失,ES是通过translog的机制来保证数据的可靠性的。其实现机制是接收到请求后,同时也会写入到translog中,当Filesystem cache中的数据写入到磁盘中时,才会清除掉,这个过程叫做flush;`
    • 在flush过程中,内存中的缓冲将被清除,内容被写入一个新段,段的fsync将创建一个新的提交点,并将内容刷新到磁盘,旧的translog将被删除并开始一个新的translog。
    • flush触发的时机是定时触发(默认30分钟)或者translog变得太大(默认为512M)时;
  1. Elasticsearch更新和删除文档的流程?
    • 删除和更新也都是写操作,但是Elasticsearch中的文档是不可变的,因此不能被删除或者改动以展示其变更;
    • 磁盘上的每个段都有一个相应的.del文件。当删除请求发送后,文档并没有真的被删除,而是在.del文件中被标记为删除。该文档依然能匹配查询,但是会在结果中被过滤掉。当段合并时,在.del文件中被标记为删除的文档将不会被写入新段。
    • 在新的文档被创建时,Elasticsearch会为该文档指定一个版本号,当执行更新时,旧版本的文档在.del文件中被标记为删除,新版本的文档被索引到一个新段。旧版本的文档依然能匹配查询,但是会在结果中被过滤掉。
  1. Elasticsearch搜索的流程?

    • 搜索被执行成一个两阶段过程,我们称之为 Query Then Fetch
    • 在初始查询阶段时,查询会广播到索引中每一个分片拷贝(主分片或者副本分片)。 每个分片在本地执行搜索并构建一个匹配文档的大小为 from + size 的优先队列。PS:在搜索的时候是会查询Filesystem Cache的,但是有部分数据还在Memory Buffer,所以搜索是近实时的。
    • 每个分片返回各自优先队列中 所有文档的 ID 和排序值 给协调节点,它合并这些值到自己的优先队列中来产生一个全局排序后的结果列表。
    • 接下来就是取回阶段,协调节点辨别出哪些文档需要被取回并向相关的分片提交多个 GET 请求。每个分片加载并丰富文档,如果有需要的话,接着返回文档给协调节点。一旦所有的文档都被取回了,协调节点返回结果给客户端。
    • Query Then Fetch的搜索类型在文档相关性打分的时候参考的是本分片的数据,这样在文档数量较少的时候可能不够准确,DFS Query Then Fetch增加了一个预查询的处理,询问Term和Document frequency,这个评分更准确,但是性能会变差。
  1. Elasticsearch 在部署时,对 Linux 的设置有哪些优化方法?
    • 64 GB 内存的机器是非常理想的, 但是32 GB 和16 GB 机器也是很常见的。少于8 GB 会适得其反。
    • 如果你要在更快的 CPUs 和更多的核心之间选择,选择更多的核心更好。多个内核提供的额外并发远胜过稍微快一点点的时钟频率。
    • 如果你负担得起 SSD,它将远远超出任何旋转介质。 基于 SSD 的节点,查询和索引性能都有提升。如果你负担得起,SSD 是一个好的选择。
    • 即使数据中心们近在咫尺,也要避免集群跨越多个数据中心。绝对要避免集群跨越大的地理距离。
    • 请确保运行你应用程序的 JVM 和服务器的 JVM 是完全一样的。 在 Elasticsearch 的几个地方,使用 Java 的本地序列化。
    • 通过设置gateway.recover_after_nodes、gateway.expected_nodes、gateway.recover_after_time可以在集群重启的时候避免过多的分片交换,这可能会让数据恢复从数个小时缩短为几秒钟。
    • Elasticsearch 默认被配置为使用单播发现,以防止节点无意中加入集群。只有在同一台机器上运行的节点才会自动组成集群。最好使用单播代替组播。
    • 不要随意修改垃圾回收器(CMS)和各个线程池的大小。
    • 把你的内存的(少于)一半给 Lucene(但不要超过 32 GB!),通过ES_HEAP_SIZE 环境变量设置。
    • 内存交换到磁盘对服务器性能来说是致命的。如果内存交换到磁盘上,一个 100 微秒的操作可能变成 10 毫秒。 再想想那么多 10 微秒的操作时延累加起来。 不难看出 swapping 对于性能是多么可怕。
    • Lucene 使用了大量的文件。同时,Elasticsearch 在节点和 HTTP 客户端之间进行通信也使用了大量的套接字。 所有这一切都需要足够的文件描述符。你应该增加你的文件描述符,设置一个很大的值,如 64,000。
      补充:索引阶段性能提升方法
      • 使用批量请求并调整其大小:每次批量数据 5–15 MB 大是个不错的起始点。
      • 存储:使用 SSD
      • 段和合并:Elasticsearch 默认值是 20 MB/s,对机械磁盘应该是个不错的设置。如果你用的是 SSD,可以考虑提高到 100–200 MB/s。如果你在做批量导入,完全不在意搜索,你可以彻底关掉合并限流。另外还可以增加 index.translog.flush_threshold_size 设置,从默认的 512 MB 到更大一些的值,比如 1 GB,这可以在一次清空触发的时候在事务日志里积累出更大的段。
      • 如果你的搜索结果不需要近实时的准确度,考虑把每个索引的index.refresh_interval 改到30s。
      • 如果你在做大批量导入,考虑通过设置index.number_of_replicas: 0 关闭副本。
  1. GC方面,在使用Elasticsearch时要注意什么?
    • 倒排词典的索引需要常驻内存,无法GC,需要监控data node上segment memory增长趋势。
    • 各类缓存,field cache, filter cache, indexing cache, bulk queue等等,要设置合理的大小,并且要应该根据最坏的情况来看heap是否够用,也就是各类缓存全部占满的时候,还有heap空间可以分配给其他任务吗?避免采用clear cache等“自欺欺人”的方式来释放内存。
    • 避免返回大量结果集的搜索与聚合。确实需要大量拉取数据的场景,可以采用scan & scroll api来实现。
    • cluster stats驻留内存并无法水平扩展,超大规模集群可以考虑分拆成多个集群通过tribe node连接。
    • 想知道heap够不够,必须结合实际应用场景,并对集群的heap使用情况做持续的监控。
  1. Elasticsearch对于大数据量(上亿量级)的聚合如何实现?
    Elasticsearch 提供的首个近似聚合是cardinality 度量。它提供一个字段的基数,即该字段的distinct或者unique值的数目。它是基于HLL算法的。HLL 会先对我们的输入作哈希运算,然后根据哈希运算的结果中的 bits 做概率估算从而得到基数。其特点是:可配置的精度,用来控制内存的使用(更精确 = 更多内存);小的数据集精度是非常高的;我们可以通过配置参数,来设置去重需要的固定内存使用量。无论数千还是数十亿的唯一值,内存使用量只与你配置的精确度相关
  1. 在并发情况下,Elasticsearch如果保证读写一致?
    • 可以通过版本号使用乐观并发控制,以确保新版本不会被旧版本覆盖,由应用层来处理具体的冲突;
    • 另外对于写操作,一致性级别支持quorum/one/all,默认为quorum,即只有当大多数分片可用时才允许写操作。但即使大多数可用,也可能存在因为网络等原因导致写入副本失败,这样该副本被认为故障,分片将会在一个不同的节点上重建。
    • 对于读操作,可以设置replication为sync(默认),这使得操作在主分片和副本分片都完成后才会返回;如果设置replication为async时,也可以通过设置搜索请求参数_preference为primary来查询主分片,确保文档是最新版本。
  1. 如何监控 Elasticsearch 集群状态?
    elasticsearch-head插件
    通过 Kibana 监控 Elasticsearch。你可以实时查看你的集群健康状态和性能,也可以分析过去的集群、索引和节点指标
  1. 是否了解字典树?
    • 常用字典数据结构如下所示

    • 字典树又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高。
    • Trie的核心思想是空间换时间,利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的。它有3个基本性质:
    • 根节点不包含字符,除根节点外每一个节点都只包含一个字符。
    • 从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串。
    • 每个节点的所有子节点包含的字符都不相同。
    • 对于中文的字典树,每个节点的子节点用一个哈希表存储,这样就不用浪费太大的空间,而且查询速度上可以保留哈希的复杂度O(1)。
  1. Elasticsearch中的集群、节点、索引、文档、类型是什么?
    • 集群是一个或多个节点(服务器)的集合,它们共同保存您的整个数据,并提供跨所有节点的联合索引和搜索功能。群集由唯一名称标识,默认情况下为“elasticsearch”。此名称很重要,因为如果节点设置为按名称加入群集,则该节点只能是群集的一部分。
    • 节点是属于集群一部分的单个服务器。它存储数据并参与群集索引和搜索功能。
    • 索引就像关系数据库中的“数据库”。它有一个定义多种类型的映射。索引是逻辑名称空间,映射到一个或多个主分片,并且可以有零个或多个副本分片。 MySQL =>数据库 Elasticsearch =>索引
    • 文档类似于关系数据库中的一行。不同之处在于索引中的每个文档可以具有不同的结构(字段),但是对于通用字段应该具有相同的数据类型。 MySQL => Databases => Tables => Columns / Rows Elasticsearch => Indices => Types =>具有属性的文档
    • 类型是索引的逻辑类别/分区,其语义完全取决于用户。
  1. Elasticsearch中的倒排索引是什么?
    倒排索引是搜索引擎的核心。搜索引擎的主要目标是在查找发生搜索条件的文档时提供快速搜索。ES中的倒排索引其实就是lucene的倒排索引,区别于传统的正向索引,倒排索引会再存储数据时将关键词和数据进行关联,保存到倒排表中,然后查询时,将查询内容进行分词后在倒排表中进行查询,最后匹配数据即可。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值