开屏暴击: 1. 什么是全文检索?什么是ES?
Before: 之前用什么? 数据量少的时候用mysql的like %小张%
表越来越大,内容越来越多。 分库分表。
增加了运维工作,数据迁移问题对于大数据的搜索,仍然存在效率问题,很慢
Then: 出现了 Lucene,全文检索工具。但是lucene对外暴露出的可用接口对于开发人员来说,操作是非常的复杂,而且没有效率的;于是在lucene的基础上进一步的封装
End: Es框架出现了,同样是以lucene为基础,并且吸收了前两代的教训而开发出的分布式多用户能力的全文搜索引擎
提供restful web接口,操作方便集群部署,易于处理支持PB级别数据,接近实时搜索能力,自动发现节点 副本机制保障可用性 2. ES核心概念介绍
index:索引, 3中意思
名词,类似于mysql的database。 一个索引就是一个拥有几分相似特征的文档的集合。动词,保存一个文档到索引中的过程, 类似 insert 语句倒排索引, mysql中使用 b+树索引到指定的列上,提升查询速度。 es使用倒排索引 来达到目的
type: 类似于 table。 从6.0.0版本后 一个index只能有一个type
document: index里面的一条记录称为 文档, 类似mysql中的行
field
mapping
cluster: 集群
节点node: 5中节点类型
分片shard和副本replicas
3. ES基本操作索引的增、删
文档的 增、 删、 改、 查
4. 索引操作时候的分片交互过程参考: https://blog.csdn.net/ZGL_cyy/article/details/120804713
5. es 写入数据的工作原理是什么啊?es 查询数据的工作原理是什么啊?底层的 lucene 介绍一下呗?倒排索引了解吗?写入过程:
客户端请求发给一个node,coordinating node(协调节点)
协调节点对document计算路由, 转发给 data-node(有primary-shard)
primary处理完成后,同步给 replica node
所有节点都处理完成后,返回success
读数据过程:
可以通过 doc id 来查询,会根据 doc id 进行 hash,判断出来当时把 doc id 分配到了哪个 shard 上面去,从那个 shard 去查询。
客户端发送请求到任意 一个 node,成为 coordinate node。coordinate node 对 doc id 进行哈希路由,将请求转发到对应的 node,此时会使用 round-robin 随机轮询算法 ,在 primary shard 以及其所有 replica 中随机选择一个,让读请求负载均衡。接收请求的 node 返回 document 给 coordinate node。coordinate node 返回 document 给客户端。
搜索数据过程:
es 最强大的是做全文检索,根据关键词搜索
- 客户端发送请求到一个 coordinate node。协调节点将搜索请求转发到所有 的 shard 对应的 primary shard 或 replica shard,都可以。query phase:每个 shard 将自己的搜索结果(其实就是一些 doc id)返回给协调节点,由协调节点进行数据的合并、排序、分页等操作,产出最终结果。fetch phase:接着由协调节点根据 doc id 去各个节点上拉取实际 的 document 数据,最终返回给客户端。
https://cloud.tencent.com/developer/article/1779104
6. 为什么要用ES? 集群选举算法? 脑裂问题的成因和解决办法? 7. 是否了解字典树?https://blog.csdn.net/yangxuefeng09/article/details/47699645
8. ES中的倒排索引是什么https://blog.csdn.net/qq_15270521/article/details/123011338
1、Lucene 几个概念
- ES底层基于Lucene实现, 是apache基金的一个开源子项目,一套全文检索引擎架构倒排索引:Inverted Index, 根据属性值确定记录,搜索引擎的关键是建立倒排索引。 频度和位置
获取文档:即数据采集过程, 指要索引和搜索的原始内容
构建文档对象: 根据文档内容构建文档对象document,每个文档包含唯一id,多个Field
如field_name 文档名称,field_path 文档路径, field_size文档大小, field_path(文档路径)等
Field属性配置如下:
tokenized(是否分词),如果要对field进行查询,要开启分词Indexd(是否索引): 只有经过索引的Field才能被搜索Stored(是否存储):是否将field值存储在文档中,只有存储在文档中的field才可以从文档中获取
分析文档
主要对原始文档执行提取单词、大小写转换、去除标点符号、去除停用词等操作,最终生成语汇单元
example:原文档: Lucene is a Java Full-text search engine
分析后得到的语汇单元: lucene、java、full、search、engine
单元中每个单词都被叫做 Term, 不同field拆分出来的相同单词是不同的Term。 一个Term包含field的名称,另一部分包含单词的内容
创建索引
对所有文档分析的Term都进行索引并记录该 Term 在每个document中出现的次数的过过程。
查询接口:搜索界面搜索关键字或者关键字的提交
创建查询:
执行搜索之前,先构建一个查询对象,可以指定搜索的文档Field、关键字等。查询对象会生成具体的查询语法。(如 " fieldName:Lucene")
执行查询
根据查询语法在倒排索引词典表中分别找出对应搜索词的索引,从而找到对应的文档链表。
搜索过程为:在索引中查找field为fieldName且关键字为lucene的Term,然后根据Term找到对应的文档id
结果返回:返回文档id列表
- 高容量: es支持pb级数据存储和查询高吞吐:支持对海量数据实时处理高可用:基于副本机制支持部分服务宕机后仍可正常运行和使用支持多维度数据分析和处理: 支持全文检索, 支持基于单字的精确查询,多字段联合查询api简单易用: 支持rest api, 还支持java, python等多种客户端
- 全文检索,类似百度百科分布式数据库:为大数据和云计算提供数据存储和查询,电商平台主要用于商品检索和管理日志分析: 通过 Logstash等日志采集组件,es可实现复杂的日志存储分析和查询,常用ELK运维监控:运维平台可基于es实现大规模服务的监控和管理BI系统: ES广泛应用于 BI(business intelligence, 商业智能)系统。
主要由 Index(索引)、Type(类型)、document(文档)组成
- Index: 一组具有共同特征的文档集合
MasterNode(主节点): 集群节点状态的维护,索引的创建删除,数据的Rebalance,分片的分配DataNode(数据节点)IngestNode(提取节点)CoordinatingNode(协调节点)TribeNode(部落节点) 2. 集群选举原理
时机:集群启动、集群重启 和 master失效后会触发集群选主操作
2.1 Bully算法ES主要采用 Bully算法选举
2.2 集群脑裂问题 2.3 选举原则- 每个节点计算已知的最小的节点id,并向其投票如果一个节点获取足够多的票,并且自己也给自己投票,那么它将成为leader,开始发布集群状态es所有节点都会参与选举和投票,但是只有对角色为master的节点投票才有效
3种, green, yellow,red
green: 所有主分片、副本分片正常yellow:所有主分片正常,部分副本分片异常。 仍然可以正常对外服务,但是高可用性不如greenred:至少一个主分片运行异常。这时候集群搜索只能返回一部分数据,请求到这个主分片上的写入请求会返回异常 4. 路由规则
路由什么,文档存储在哪个索引(index)的哪个分片(shard)上
shard =hash(routing) % number_of_primary_shards
routing默认为id,可以自定义指定
5. 文档分片和副本策略这也是为什么 ElasticSearch 索引的主分片数量在确 定后就不能再修改的原因,因为如果主分片数量发生变化,则之前路由的所有分片都会失效 。
文档分片:
- ES中每个索引都由一个或者多个分片组成,文档根据路由规则分配到不同的分片上每个分片对应一个 lucene实例, 一个分片只能存放 Integer.MAX_VALUE - 128 个文档分片主要用于数据横向分布,ES中的分片会被尽可能平均分配到不同节点,有新的节点加入后,ES会自动感知,并执行 relocation 操作
副本策略
- primary shard 和 relica shard,每个document只会存在于某一个primary shard以及其对应的replica shard中,不可能存在于多个primary shard中replica shard 是primary shard 的副本,负责容错,以及承担读请求的负载均衡primary shard在创建索引的时候就固定了,relica shard的数量可以随时更改primary shard 和 它对应的replica shard 不能放在同一台机器上,不然起不了容错的作用
写入
ElasticSearch 首先会在主分片上执行写操作,当主分片上执行成功时,根据集群的数据一致性要求,将在其他副本分片上执行写操作,只有达到一致性要求的节点都执行成功后才向客户端发送成功响应 。
当向 ElasticSearch 发送请求时,可以将请求发送到集群中的任 一节点 。 ElasticSearch 集群中的每个节点都有能力处理任意请求 。 每个节点都知道集群中任 一 文挡的位置。接 收请求的节点被称为协调节点 。
写的时候,找到任意一个协调节点,然后找到索引的主分片,先写主分片,然后同步副本分片,等到达到设置的节点要求的时候,才会向客户端返回成功。
( 1 )客户端向 Node-I(协调节点) 发送新建 、查询或者删除文档的请求。节点根据文档的 id 为1确定文档属于分片 1。
(2)因为分片 1 的主分片 P-1 被分配在 Node-3 上,所以请求会被转发到 Node-3。
( 3 )在 Node-3 的主分片上执行请求,如果执行成功,则将请求同时转发到 Node-1 和 Node-2 的副本分片 R-1 上执行。
( 4) 当所有副本分片都报告执行成功时. Node-3 才向协调节点报告执行成功 。
( 5 )协调节点向客户端报告成功。当客户端收到成功响应时,文档更新已经在主分片和所有副本分片上都执行成功。
写入一致性 Consistency, 三种级别
one : 仅主分片all : 主分片和所有副本分片quorum(默认的): 大部分分片 。 初始设置的 分片数/2 +1 7 ES读取过程
读的时候,协调节点在每次收到客户端请求的时候都会通过轮询所有副本分片来达到负载均衡 。
如果主分片有数据,副本分片还没有,而请求到了副本分片,那么先查副本分片,然后返回到协调节点,协调节点再要求请求其他节点,知道所有的都返回没有,才会告诉客户端没有。
(1) 客户端向Node-l发送文档读取请求。
( 2 )协调节点 Node-I 根据文档的 地 来确定文裆属于分片 l。 分片 l 的文档数据存 在所有 3 个节点上 。 在这种情况下 , 它将请求转发到 Node-2。
( 3 ) Node-2 在本地执行查询操作并将查询结果返回到 Node-I。
( 4 ) Node-l ( 此时 Node-I 为 CoordinatingNode 角色)接收 Node-2 的查询结果,如 果查询到请求对应的文挡 ,则将 该文裆返回客户端 。 如果在 Node-2 上未查询到对应的文 档数据,则 Node-I 会继续向其他节点发送文挡读取请求,直到查询到文档对应的数据后 才返回 。 如果要读取的文挡在所有节点上都不存在,则向客户端报告文挡不存在 。
4. ES事务, TranslogES事务的日志文件为 Translog,记录所有与更新相关的事务操作日志。
每个分片都有Translog
Translog 提供了数据没有被刷盘的一个持久化存储纪录,主要用来恢复数据当 ElasticSearch 重启时,它会在磁盘 中使用 最后一个提交点( Commit Point )去 恢复已知的段数据,并且会重放 Translog 中所有在最后一次提交后发生的变更操作 。
ES数据更新和Translog操作流程( 1 )当 ElasticSearch 写数据时并没有直接将数据落盘,而是为了提高写入的效率将数据同时写入内存和 Translog文件。
( 2 )在 refresh 时间过后,将内存缓冲区的数据 写人 Lucene的 Segment,同时清空内 存缓冲区 。 refresh 时间通过在 Mapping 的 Setting 中设置 refresh interval 来实现 。
( 3 )在文件系统的 fsync 操作完成后,向磁盘里写入 Commit Point 信息。
( 4 )删除 Translog 对应的日志。
5. ES段合并此处遗留问题,什么是段,感觉理解不准确
elasticsearch 中每个索引都会创建一个到多个分片和零个到多个副本,这些分片或副本实质上都是lucene索引。
lucene索引是基于多个索引段创建,索引文件中绝大部分数据都是只写一次,读多次,而只有用于保存文档删除信息的文件才会被多次更改
在某些时刻,当某种条件满足时,多个索引段会被拷贝合并到一个更大的索引段,而那些旧的索引段会被抛弃并从磁盘中删除,这操作叫做段合并
在 ElasticSearch 中,每一个段都会消耗文件句柄 、 内存和 CPU 运行周期 。 同时,每个搜索请求都必须轮流检查每个段;因此段越多 , 搜索也就越慢 。
在段合并的时候会将那些旧的已删除文档从文件系统中消除 。 被删除的文档(或被 更新文挡的旧版本)不会被复制到新的大段中。段合并在进行索引和搜索日才会自动进行 。
段合并流程将两个提交了的段和一个未提交的段合并到一个更大的段,其流程如图主要分为3个阶段。
- 在索引的时候,Refresh 操作会创建新的段并将段打开以供攫索使用 。合并进程选择一小部分大小相近的段,在后台将他们合并到更大的段中,该操作并不会巾断索引和搜索 。
( 3 )在合并结束后,老的段被删除,新的段被 Flush 到磁盘 ( 写入一个包含新段且排 除旧段和较小段的新提交点),再打开新的段对外提供搜索,删除老的段数据 。
合并大的段需要消耗大量的 IO 和 CPU 资源, ElasticSearch 对合并流程进行资源限 制,以保障搜索仍然有足够的资源被正常地执行 。
6. ES集群扩容两种扩容方式:
- 水平扩容: 集群中添加一个新的节点(一般与当前节点配置相同)。垂直扩容: 加大现有节点的配置, 内存、CPU 和 磁盘资源
实践证明,在集群总体资源一定的情况下,使用内存容量小 、 性能相对较低 、节点较多的部署方案 ,其性能往往优于使用内存容量大、性能相对较高 、节点较少的部署方案。
ES有集群发现机制
ES是一种p2p(peer to peer)的分布式架构设计,集群中的每个节点都可以与其他任意节点进行通讯。这是不同于hadoop的master-slave的分布式系统。 使用了 gossip协议
4、ES的应用大数据存储、日志分析、运维监控等多种场景。 支持单机部署、集群部署。
4.1 安装,启动等 4.2 ES配置和性能调优 1. JVM性能调优ES使用java实现, 默认使用堆内存为1GB
//设置jvm堆内存 vim config/jvm.options
如果操作系统32G内存,建议将JVM 堆内存, 最大值和最小值都设置为 16G
-Xms:16gb -Xmx: 16gb
这里将堆内存最小值 (Xms) 与最大值 (Xmx) 设置相间,防止在 ElasticSearch 运 行过程中 JVM改变堆内存大小,引起 JVM 内存震荡。
java 项目 jvm调优也是这个规则,最大和最小堆设置一致
需要注意的是, ElasticScarch除了使用 JVM堆内存,其内部 Lucene还需要使用大量非堆内存 。 ElasticSearch 内部使用 Lucene 实现全文检索 。 Lucene 的段分别存储在单个文件中,因为段是不可变的,对缓存友好的,所以在使用段数据时操作系统会把这些段文件缓存起来,以便更快地访问。 同时, Lucene 可以利用操作系统底层机制来缓存内存数据,加速查询效率 。
上面操作系统剩下的16G内存预留给 lucene 和操作系统的,不能太少,否则lucene运行中性能会下降
2. 操作系统的调优设置文件句柄: Linux默认文件句柄是1024,对于服务器来说太小,一般设置为 65535
设置虚拟内存: max_map_count 定义了进程能拥有的最多内存区域,一般建议设置为102 400
sysctl -w vm.rnax rnap count=102400
关闭swap: swap空间是一块磁盘空间,操作系统使用这块空间保存从内存中交互换出的操作系统不常用的Page数据, 这样可以分配出更多的内存做Page Cache。通过Swap可以提升系统的吞吐量和 IO 性能, 但 ElasticSearch需要一个所有内存操作都能够被快速执行的环境, 服务一旦使用到了 Swap内存, 就会大大降低数据的存取效率,严重影响性能 。 关闭设置 的命令如下。
echo "vrn.swappiness 0">> /etc/sysctl.conf
开启mlockall: 打开配置文件中的 mlockall开关。它的作用是允许 JVM锁住内存,禁止操作系统将内存交换 出 去。 elasticsearch.yml 文件中的 设置 如 下 。
bootstrap.rnlockall : true
有两种api:
java apirest api两种



