ElasticSearch

3、ElasticSearch简介

ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便

优点:
	* 分布式实时文件存储,并将每一个字段都编入索引,使其可以被搜索。
	* 实时分析的分布式搜索引擎。
	* 可以扩展到上百台服务器,处理PB级别的结构化或非结构化数据。
	* Elasticsearch是分布式的。不需要其他组件,分发是实时的,被叫做”Push replication”。
	* 各节点组成对等的网络结构,某些节点出现故障时会自动分配其他节点代替其进行工作。

3.2. Lucene与Solr

3.2.1. Lucene

Lucene不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引 引擎,部分文本分析引擎。想要使用它,你必须使用Java来作为开发语言并将其直接集成到你的应用 中,更糟糕的是,Lucene非常复杂,你需要深入了解检索的相关知识来理解它是如何工作的。

3.2.2. Solr

Solr是Apache Lucene项目的开源企业搜索平台。其主要功能包括全文检索、命中标示、分面搜索、 动态聚类、数据库集成,以及富文本(如Word、PDF)的处理。Solr是高度可扩展的,并提供了分布式 搜索和索引复制。Solr是最流行的企业级搜索引擎,Solr4 还增加了NoSQL支持。 当单纯的对已有数据进行搜索时,Solr更快。

当实时建立索引时, Solr会产生io阻塞,查询性能较差, Elasticsearch具有明显的优势。

随着数据量的增加,Solr的搜索效率会变得更低,而Elasticsearch却没有明显的变化。

综上所述,Solr的架构不适合实时搜索的应用

4、ES安装

ElasticSearch安装,ES-head,IK,kibana安装.

5、ES数据存储结构

  • 从ElasticSearch6.X开始,官方准备废弃Type了
ElasticSearchIndex 索引Document 文档Field 字段mapping 字段定义
数据库行记录列字段表结构定义–映射关系

在这里插入图片描述

5.1. 索引 Index

  • 索引是文档(Document)的容器,是一类文档的集合
  • 类比传统的关系型数据库领域来说,索引相当于SQL中的一个数据库(Database)
  • 索引ElasticSearch 使用了一个叫做 倒排索引 的结构来达到相同的目的。

5.2. 类型 Type

  • 从6.0.0开始单个索引中只能有一个类型,7.0.0以后将将不建议使用,8.0.0 以后完全不支持。
  • 索引和文档中间还有个类型的概念,每个索引下可以建立多个类型,文档存储时需要指定index和 type。
  • 弃用原因
    • 如 果在SQL中,Table 之前相互独立,同名的字段在两个表中毫无关系。
    • 但是在ES中,同一个 Index 下不同的 Type 如果有同名的字段,他们会被 Luecence 当作同一个字段 ,并且他们的定义必须相同。
    • 所以我觉得Index现在更像一个表,而Type字段并没有多少意义。
    • 目前Type 已经被Deprecated,在7.0开始,一个索引只能建一个Type为_doc

5.3. 文档 Document

  • Document Index 里面单条的记录称为Document(文档)等同于关系型数据库表中的行
_index 文档所属索引名称。
_type 文档所属类型名。
_id Doc的主键。在写入的时候,可以指定该Doc的ID值,如果不指定,则系统自动生成一个唯一的UUID值。
_version 文档的版本信息。Elasticsearch通过使用version来保证对文档的变更能以正确的顺序执行,避免乱序造成的数据丢失。

_seq_no 严格递增的顺序号,每个文档一个,Shard级别严格递增,保证后写入的Doc的
_seq_no大于先写入的Doc的_seq_no。

primary_term primary_term也和_seq_no一样是一个整数,每当Primary Shard发生重新分配时,比如重启,Primary选举等,_primary_term会递增1

found 查询的ID正确那么ture, 如果 Id 不正确,就查不到数据,found字段就是false。

_source 文档的原始JSON数据。

5.4. 字段Field

  • 一行数据中心包含很多的字段,类似于关系数据库的列Column

6、ES的基本命令

先了解下restful中 GET/PUT/POST/DELETE 格式

POST /uri #创建
DELETE /uri/xxx #删除
PUT /uri/xxx #更新或创建
GET /uri/xxx #查看
在ES中,如果不确定文档的ID,那么就需要用POST,它可以自己生成唯一的文档ID。如果确定文档的ID,那
么就可以用PUT,当然也可以用POST,它们都可以创建或修改文档
PUT、GET、DELETE是幂等的,而POST并不一定是幂等。

6.1. 集群相关命令

  • /_cat/nodes #查看所有节点信息
    • curl -X GET "192.168.88.101:9200/_cat/nodes?v&pretty"
  • /_cat/shards #查看各shard的详细情况
    • curl -X GET "localhost:9200/_cat/shards?v&pretty"
  • /_cat/indices #查看集群中所有index的详细信息
    • curl -X GET "localhost:9200/_cat/indices?v&pretty"

6.2. 映射Mapping

  • 从7.x开始,一个Mapping只属于一个索引的type 默认type 为:_doc
  • ES 字段类型主要有:核心类型、复杂类型、地理类型以及特殊类型

在这里插入图片描述

6.2.1. 核心类型

字符串类型

  • text
    • 类型适用于需要被全文检索的字段,例如新闻正文、邮件内容等比较长的文字,text类型会被 Lucene 分词器(Analyzer)处理为一个个词项,并使用 Lucene 倒排索引存储,text 字段不能被用于排序,如果需要使用该类型的字段只需要在定义映射时指定 JSON 中对应字段的 type 为 text。
    • 非结构化的文本数据。
  • keyword
    • 不会被分词,适合简短、结构化字符串,例如主机名、姓名、商品名称等,可以用于过 滤、排序、聚合检索
    • 也可以用于精确查询。 包括数字、日期、具体的字符串(如“192.168.0.1”)

6.3. Dynamic Mapping

动态映射时Elasticsearch的一个重要特性:

  • 不需要提前创建index、定义mapping信息和type类型,
  • 可以 直接向ES中插入文档数据时, ES会根据每个新field可能的数据类型, 自动为其配置type等 mapping信息
  • 这个过程就是动态映射(dynamic mapping).

约束策略

  • dynamic设为true时,新增字段的文档写入时,Mapping同时被更新
  • dynamic设为false时,Mapping不会被更新,新增字段的数据无法被索引,但是会出现在 _source中
  • dynamic设为strict,文档将写入失败

6.4. 索引CRUD命令

  • 创建是命名全部小写,不能使用_开头,中间不能使用,
  • 创建Index
    • curl -XPUT http://192.168.88.101:9200/lucky?pretty
  • 获取索引
    • curl -XGET http://192.168.88.101:9200/lucky?pretty
  • 删除索引
    • curl -XDELETE http://192.168.88.101:9200/lucky?pretty

8、分片与备份

  • 分片分为两种,主分片和副本:

    • 主分片用于解决数据水平扩展的问题,通过分片,可以将数据分布到集群内的所有节点之上
      • 一个分片是一个运行的ES实例
      • 分片数在索引创建时指定,后续不允许修改,除非Reindex
    • 副本用以解决数据高可用的问题,副本是主分片的拷贝
      • 副本分片数,可以动态调整
      • 增加副本数,还可以在一定程度上提高服务的可用性(读取的吞吐)
  • 分片的设定

    • 分片数设置过大
      • 导致后续无法增加节点实现水平扩展
      • 单个分片数据量过大,导致数据重新分片耗时
    • 分片数设置过小,7.0之后,默认主分片是1,解决了over-sharding的问题
      • 影响搜索结果的相关性打分,影响统计结果的准确性
      • 单个节点上过多分片,会导致资源浪费,同时会影响性能

9、ES数据架构

9.1. 基本概念

  • Index: 一个ES集群中可以按需创建任意数目的索引。
  • Document:文档是索引和搜索的原子单位,它是包含了一个或多个域(Field)的容器。
  • Node:集群是由一个或者多个拥有相同cluster.name配置的节点组成
    • 主节点:负责管理集群范围内的所有变更 (写操作)
    • 数据节点:存储数据和其对应的倒排索引。默认每一个节点都是数据节点(包括主节 点)
    • 协调节点:如果node.master和node.data属性均为false,此节点称为协调节点,用来 响应客户请求,均衡每个节点的负载。
  • Shard:一个索引中的数据保存在多个分片中,相当于水平分表。
    • 分片是数据的容器,文档保存在分片内,分片又被分配到集群内的各个节点里
    • 索引建立的时候就已经确定了主分片数(默认5分片),但是副本分片数可以随时修改。
  • Replaction
    1. 一个分片可以是主分片或者副本分片
    2. 主分片可以用来写入和读取数据
    3. 副本分片负责读取数据 主分片和副本分片的状态决定了集群的健康状态,相同的副本分片不会存在于同一个节点中

9.2. ES数据Write流程

在这里插入图片描述

  • 名词类比HBase

    • Shard ---- Region
    • Lucene ----- buffer ---- 系统缓存
    • Segment ----- MemStore
    • 写出Segment ---- stroefile
    • TransLog ---- Hlog
  • Shard和Replicaion的路由规则

    • 每个Index由多个Shard组成,每个Shard有一个主节点和多个副本节点,副本个数可配。
    • 每次写入的时候,写入请求会先根据 _routing 规则选择发给哪个Shard
      • Index Request中可以设置使用哪个Filed的值作为路由参数。
      • Index设置 > Mapping配置 > id的Hash值 —> 选出 Primary Shard
    • 请求会发数据送给Primary Shard,在Primary Shard上执行成功后,再从Primary Shard上将请求同时发送给多个Replica Shard
  • 数据安全策略

    • Elasticsearch里为了减少磁盘IO保证读写性能,一般是每隔一段时间才会把Lucene的 Segment写入磁盘持久化
    • Elasticsearch学习了数据库中的处理方式:增加CommitLog模块,Elasticsearch中叫 TransLog
    • 写入请求到达Shard后,先写buffer文件,创建好索引,此时索引还在内存里面,接着去写 TransLog
    • 写完TransLog后,刷新TransLog数据到磁盘上,写磁盘成功后,请求返回给用户
  1. 写buffer后,文档并不是可被搜索的,需要通过Refresh把内存的对象转成完整的Segment后,然后再次reopen后才能被搜索 。发生断电,则这些文档可能会丢失。
  2. 一般这个时间设置为1秒钟,导致写入Elasticsearch的文档,最快要1秒钟才可被从搜索到。
  3. 每隔一秒将生成一个新的segment,而translog文件将越来越大。
  4. 每隔30分钟或者translog文件变得很大,则执行一次fsync操作。此时所有在文件系统 缓存中的segment将被写入磁盘,而translog将被删除

在这里插入图片描述

9.3. ES写入数据完整流程

在这里插入图片描述

  • 红色:Client Node(协调节点)
  • 绿色:Primary Node(主分片节点)
  • 蓝色:Replica Node(副本分片节点)

9.4. ES数据Update流程

  • ES的索引是不能修改的,因此更新和删除操作并不是直接在原索引上直接执行。
  • update —》 delect+add
  • 收到Update请求后,从Segment或者TransLog中读取同id的完整Doc,记录版本号为V1 = 345
  • 将版本V1的全量Doc和请求中的部分字段Doc合并为一个完整的Doc,同时更新内存中的 VersionMap 。
  • 获取到完整Doc后,Update请求就变成了Post/Put请求。
  • 加锁。 再次从versionMap中读取该id的最大版本号V2 = 346
  • 检查版本是否冲突(V1==V2),如果冲突,则回退到开始的“Update doc”阶段,重新执行。如果不冲 突,则执行最新的Add请求。
  • 在Index Doc阶段,首先将Version + 1得到V3,再将Doc加入到Lucene中去,Lucene中会先删同 id下的已存在doc id,然后再增加新Doc。写入Lucene成功后,将当前V3更新到versionMap中。
  • 释放锁,部分更新的流程就结束了。

在这里插入图片描述

9.5. ES数据Delete流程

如果是删除请求的话,提交的时候会生成一个.del文件,里面将某个doc标识为 deleted状态,那么搜索的时候根据.del文件就知道这个doc被删除了,客户端搜索的时候,发现数据在.del文件中标志为删除就不会搜索出来了。

合并刷出segment到磁盘上时才会正删除文件

9.6. ES数据Read流程

  • 查询的过程大体上分为查询(query)和取回(fetch)两个阶段
    • 这个节点的任务是广播查询请求到所有相关分片,并将它们的响应整合成全局排序后的结果集合, 这个结果集合会返回给客户端
  • 查询过程
    1. 当一个节点接收到一个搜索请求,则这个节点就变成了协调节点。 如果客户端要求返回结果排序中从第from名开始的数量为size的结果集,则每个节点都需要生成一个from+size大小的结果集
    2. 分片仅会返回一个轻量级的结果给协调节点,包含结果集中的每一个文档的ID和进行排序所需要的信息
    3. 协调节点会将所有分片的结果汇总,并进行全局排序,得到最终的查询排序结果
  • 取回过程
    1. 协调节点会确定实际需要返回的文档,并向含有该文档的分片发送get请求;
    2. 分片获取文档返回给协调节点;协调节点将结果返回给客户端。
  • 相关性计算
    1. 判别文档与搜索条件的相关程度
    2. TFIDF
    3. BM25评分算法

9.7. 实时性

​ Elasticsearch的主要应用场景就是实时,但Elasticsearch本身并非实时而是near-real-time(近实 时)。Index的实时性是由refresh控制的,默认是1s,最快可到100ms,那么也就意味着Index doc成功后,需要等待一秒钟后才可以被搜索到。

​ 一般这个时间设置为1秒钟,导致写入Elasticsearch的文档最快要1秒钟才可被从搜索到,所以 Elasticsearch在搜索方面是NRT(Near Real Time)近实时的系统

9.8. 可靠性

  • 搜索系统对可靠性要求都不高,丢失数据通过备份找回。
  • 通过设置TransLog的Flush频率可以控制可靠性,要么是按请求,每次请求都 Flush;要么是按时间,每隔一段时间Flush一次。
  • 一般为了性能考虑,会设置为每隔5秒或者1分钟Flush一次,Flush间隔时间越长,可靠性就会越 低。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值