《ElasticSearch实战与原理解析》—— 基础理论笔记

Elasticsearch 前传

介绍搜索技术发展史和基本知识以及搜索引擎基本原理

搜索技术发展史

💠搜索引擎的5个阶段

  1. FTP文件检索阶段
  2. 分类目录导航阶段
  3. 文本相关信检索阶段
  4. 网页链接分析和用户意图识别阶段

Elasticsearch简介

💨Elasticsearch就是一个用于数据搜索、分析和存储的框架

基于Java编写,内部使用Lucene做索引与搜索,屏蔽Lucene复杂性只需要了解简单一致的RESTful API即可。
相关功能: 检索相关数据、返回统计结构、响应速度、分布式下实时文档存储和实时分析搜索。

Lucene简介

💨Lucene是一个支持全文检索的工具包

Lucene仅仅是一个工具包并非完整的全文检索引擎
Lucene的索引文件格式独立于应用平台,定义一套以8Byte为基础的索引文件格式,兼容不同平台
Lucene默认实现布尔操作、模糊查询、分组查询等

主要模块: Analysis模块、Index模块、Store模块、QueryParser模块、Search模块和Similarity模块。

模块名称 模块功能
Analysis 词法分析与语言处理,形成存储或搜索的最小单元Term
Index模块 负责索引的构建工作
Store模块 负责索引的读和写,主要对文件的一些操作
QueryParser模块 负责语法分析,把查询语句生成Lucene底层可以识别的条件
Search模块 负责对索引的搜索工作
Similarity模块 负责相关性打分和排序

相关术语

术语 术语描述
Term 索引中最小存储和查询单元。在英语环境中一个term指的是一个单词;在中文环境中一个term指的是要给分词后的词
Term Dictionary 排序数组、HashMap、FST(Finite-State Transducer)
倒排表 一篇文档由多个词组成,倒排表记录某个词在哪些文章中出现过
正向信息 原始的文档信息,可以用来做排序、聚合、展示等
索引中最小的独立存储单元。一个索引文件由一个或多个段组成。

知识点关联

REST(resource - Representation State Transfer)协议

🌐Web技术架构四个基石: URI、HTTP、HyperText、MIME(Multipurpose Internet Mail Extensions,多用途互联网邮件扩展类型)。这四个基石支撑
💮Web开发技术经历5个阶段: 静态内容(静态HTML) -> CGI(Common Gateway Interface -> ASP、PHP、JSP) -> 脚本语言阶段(JS、Java Applet) -> 瘦客户端应用阶段(Web MVC) -> RIA(Rich Internet Application -> DHTML + Ajax)阶段和移动应用阶段

REST关键性原则: Resource、Hypertext Driven、Uniform Interface、Representation、State Transfer

Keyword DESC
Resource(资源) 表示事物定义ID
Hypertext Driven(超文本驱动) 将所有事物链接在一起
Uniform Interface(统一接口) 使用标准方法
Representation(资源的表述) 资源多重表述的方式
State Transfer(状态转移) 无状态的通信

🔺Resource 有一个或多个URI表示(URI是资源的名称也是资源在Web上的地址)

将服务器中很多离散的资源组合,每个资源是服务器上一个可命名的抽象概念。资源可是服务器文件系统中的一个文件也可以是数据库中的一张表。
每个事物都是可被标志的,都会拥有一个ID标识符。在Web开发中,代表ID的统一概念 ===》 URI(全局命名空间)

URI、URL和URN的区别 URI(资源名称+资源路径) = URL + URN
🌡URI(Uniform Resource Identifier: 统一资源标识符包括URL和URN
🌡URL(Uniform Resource Locater: 统一资源定位符
🌡URN(Uniform Resource Name: 统一资源名称

🔺URI的4个设计原则

  1. 名词
  2. 区分单复数
  3. URI有长度限制, <= 1KB
  4. URI不显示未加密信息

🔺URI中几个符号的解释

符号 描述 举例
/ 层次关系 https://www.xxx.cn/products/elasticsearch 【%2F】
; 并列关系 https://www.xxx.com/axis;x=0,y=9 sip:user@domain.com; foo=bar; x=y
- 提高可读性,最好小写 https://www.xxx-fan.-com/
+ + 表示空格(在URL中不能使用空格) 【%2B】
? 分割实际的URL和参数 【%3F】
# 表示书签🔖 【%23】
& URL中指定的参数间的分隔符 【%26】
= URL中指定的参数的值 【%3D】

🔺超文本驱动 所有事物链接在一起。超媒体被当作应用状态引擎

资源之间通过超链接相互关联,超链接既代表资源之间的关系也代表可以执行的状态转移
URI命名规范是全球标准,构成Web的所有资源都是可以互联互通的

超媒体原则: 服务器端为客户端提供一组链接🔗,使客户端能够通过链接将应用从一个状态改变为另一个状态

🔺统一接口 必须通过统一接口对资源执行各种操作

在HTTP 1.1中定义操作资源的统一接口: GET、POST、PUT、DELETE、PATCH、HEAD、OPTIONS

🔺资源表述 一段对资源在某个特定时刻的状态描述
资源表述格式: HTML、XML、JSON、文本、图片、视频、音频等
资源的表述方式通过协商机制来确定,请求响应的表述通常使用不同的格式。

🔺状态转移 无状态通信
状态转移是在客户端和服务端之间转移。通过转移和操作的资源表述,间接实现操作资源的目的

无状态意味着服务器的变化对客户端是不可见的。主要是为了保证架构设计的可伸缩性和可扩展性, 减少耦合

REST架构设计是否优秀的标准: 面向资源、可寻址、连通性、无状态、统一接口和超文本驱动

骐骥一跃,不能十步。 驽马十驾,功在不舍。

数据搜索🔍方式

🔰 搜索引擎是对数据进行检索,数据存在两种类型 结构化数据和非结构化数据
✋所谓的结构化数据
例如存储在关系型数据库中的数据, 它们具有指定的数据类型和个数。通过二维化表结构来承载。
✋所谓的非结构化数据
例如存储在非关型数据库中的数据,它们的数据长度不定且无固定数据格式。

🚀结构化数据搜索
结构化数据基于关系型数据库来存储,关系数据库支持索引,结构化数据通过DB来完成搜索和查找。
常用查找方式: 顺序扫描、关键词精确匹配、关键词部分匹配等

复杂匹配: 借助 LIKE 关键词
左匹配: xxx%
右匹配: %xxx
完全匹配: %xxx%

🛸非结构化数据搜索
数据的搜索: 顺序扫描(效率低)和全文检索(效率高)两种方法

在实现全文检索的过程中,要提取非结构化数据中的有效信息,重新组织数据的承载结构形式。
全文检索是一种空间换时间的做法(前期构建索引后期提高搜索效率)

用户 -> 输入内容预处理 -> 搜索关键词查询 -> 索引库 <- 数据索引 <- 数据预处理 <- 网页库 <- 网络爬虫 <- 互联网
搜索引擎的工作原理分为两个阶段:

  1. 网页数据爬取: 爬虫、数据预处理、数据索引三个主要动作(搜索关键词、输入内容、预处理、搜索关键词查询)

网页被爬虫爬取后,存储网页库,以备下一姐u但进行数据预处理。
预处理操作: 去除噪声内容、关键词处理(中文分词、去除停止词)、网页间链接关系计算

  1. 索引阶段、搜索阶段

在创建索引之前都需要对内容进行分词。分词不仅仅是关键词提取的前提,也是后续文本挖掘的基础。
在倒排索引中,词汇在网页或文章中出现的位置、频率和权重等,在查询阶段会用到。
在倒排索引中,有词条(Term)、词典(Term Dictionary)、倒排表(Post List)三个名词

🐷词条(Term): 索引中最小的存储和查询单元。
🐸词典(Term Dictionary): 又称字典,是词条的集合。单词词典是由网页或文章中出现所有词构成的字符串集合
🐼倒排表: 词出现在哪些文档里、出现的位置和频率

在Lucene中词典中词典和倒排表是实现快速检索的重要基石。
词典: 存储在内存中
倒排表: 存储在磁盘上

Elasticsearch 实战

Elasticsearch是一个分布式、可扩展、近实时的高性能搜索于数据分析引擎。
🔵 Elasticsearch基于Apache Lucene构建,采用Java编写其特点:
🔹分布式实时文件存储。Elasticsearch可以将索引文档中的每个字段存入索引,以便字段可以被检索到。
🔹实时分析的分布式搜索引擎。Elasticsearch的索引分拆成多个分片,每个分片有0或多个副本。集群中的每个数据结点都可承载一个或多个分片,并协调和处理各种操作。
🔹高扩展性。处理PB级别的结构化或非结构化数据。
如果需要将Elasticsearch作为守护进程运行则执行 bin/elasticsearch -d -p pid

Elasticsearch配置

“约定大于配置”的思想,配置文件包含特定的节点设置eg: node.name和paths路径等信息还会包含节点为了能够加入Elasticsearch集群需要添加cluster.name和network.host等

配置文件位置信息: elasticsearch.yml、jvm.options和log4j2.properties

安全设置

在ES中设置信息是敏感且需要保密的,此时单纯依赖文件系统权限保护不够需要提供密钥库和密钥库工具来管理密钥库中的设置。所有命令均适用于ES用户
对密钥库所有修改需要在重新启动ES之后生效
➰创建密钥库
bin/elasticsearch-keystore create 将会创建2个文件分为 elasticsearch.keystore和elasticsearch.yml

➰查看密钥库中的设置列表
bin/elasticsearch-keystore list

➰添加字符串设置
需要设置敏感的字符串则需要使用add命令添加
bin/elasticsearch-keystore add the.setting.name.to.set
命令执行后将提示输入设置。用户可以使用--stdin标志在窗口stdin中输出待设置的目标值eg:
cat /file/containing/setting/value | bin/elasticsearch-keystore add --stdin this.setting.name.to.set
➰添加文件设置
用户可以通过添加文件命令添加敏感信息文件,eg: 云插件的身份验证密钥文件。确保文件路径作为参数在设置名称之后
bin/elasticsearch-keystore add-file the.setting.name.to.set /path/example-file.json
➰删除密钥设置
从密钥库中删除设置则使用remove命令
bin/elasticsearch-keystore remove the.setting.name.to.remove
➰重新加载的安全设置
密钥库内容的更改不会对正在运行的ES节点起任何作用,必须重新启动节点才能重新读取设置。
对于某些安全设置可以设置为可重新加载,设置后可以在正在运行的节点上重新读取和应用

日志记录设置

ES可以通过log4j2进行日志记录。
ES公开三个属性

  1. $sys:es.logs.base_path -> 日志文件目录地址
  2. $sys:es.logs.cluster_name -> 群集名称(在默认配置中,用做日志文件名的前缀)
  3. $sys:es.logs.node_name -> 解析为节点名称(显式设置了节点名称)
    用户在配置文件中引用这些属性来确定日志文件的位置。

ES核心概念

学好、用好ES首先要了解其核心概念、名词和属性。eg:懂地图就要知道地图里面常用的标记符号一样
核心概念: Node、Cluster、Shards、Replicas、Index(数据库)、Type(数据表)、Document(记录)、Settings、Mapping和Analyzer

术语 描述
Node(节点) 节点是组成ES集群的基本服务单元,集群中每个运行中的ES服务器都可称之为节点
Cluster(集群) ES的集群是由具有相同cluster.name(默认为elasticsearch)的一个或多个ES节点组成,各个节点协同工作,共享数据。同一个集群内节点的名字不能重复,但集群的名称一定要相同
Shards(分片) 当索引的数据量太大时候,受限于单个节点的内存、磁盘处理能力等,节点无法足够块响应客户端的请求,需要将一个索引上的数据进行水平拆分。拆分出来的数据部分称之为一个分片。每个分片都会放在不同的服务器上
Replicas(副本\备份) 副本对主分片的备份,是精确复制模式,每个主分片均有*个副本
Index(索引) Index相当于数据库,索引被水平切分成多个分片,需要通过索引名称在集群内做唯一标识
Type(类别) Type相当于数据表,类别指的是索引内部的逻辑分区,通过Type的名字在索引内进行唯一标识
Document(文档) Document相当于记录,每一条数据就是一个文档
Settings Settings是对集群中索引的定义信息,比如一个索引默认的分片数
副本数等
Mapping(索引自身元信息) 相当于表结构信息,Mapping标识保存了索引中字段(Field)的存储类型、分词方式、是否存储等信息
Analyzer(字段分词方式的定义) 一个Analyzer通常由一个Tokenizer和零到多个Filter组成。在ES中,默认的标准Analyzer包含一个标注的Tokenizer和三个Filter -> Standard Token Filter、Lower Case Token Filter 和 Stop Token Filter

Mapping可以动态识别的。如果没有特殊需求,则不需要手动创建Mapping,ES会根据数据格式自动识别其类型。
当需要对某些字段添加特殊属性时。eg: 定义使用分词器、是否分词、是否存储等需要手动配置Mapping、

😱关于分片

进行分片操作之后,索引的规模扩大,性能也随之水涨船高
ES依赖Lucene,ES中的每个分片都是Lucene的一个索引文件,因此每个分片必须有一个主分片和0-多个副本分片
当开发人员在要给设置有多分片的索引中写入数据时,是通过路由来去顶具体写入哪个分片中的,因此在创建索引时需要指定分片的数量,并且分片的数量一旦确定就不能更改。
开发人员在查询索引时,需要哦在索引对应的多个分片上进行查询。ES会把查询发送给每个相关的分片,并汇总各个分片的查询结果。对上层应用程序,分片是透明的。
在ES中,默认一个索引创建5个主分片,并分别为每个主分片创建一个副本。
主分片和备份分片共同向外提供服务减轻负载,同时备份分片也可以作为主分片的候选,以防主分片失效。
备份分片可以提升ES系统的高可用性能,可以提升搜索时并发性能

🍱ES集群中,节点的状态有Green、Yellow和Red三种

1.💚Green: 节点运行状态为健康状态。所有的主分片和副本分片均能正常工作,集群100%健康
2.💛Yello: 节点运行状态为预警状态。所有的主分片都可以正常工作,但至少有一个副本分片无法正常工作。
3.💔Red: 集群无法使用。此时,集群中至少有一个分片的主分片及其全部副本均不能工作|

ES的架构设计


核心层(Lucene) =》 数据处理层(Index、Search、Mapping) =》 发现与脚本层 =》 协议和应用层

Discovery是ES自动发现节点的机制。
协议层默认是HTTP
应用层是RESTful的API

ES节点自动发现机制

4种可供选择的发现机制
【Azure Discovery】、【EC2 Discovery】、【Google Compute Engine(GCE) Discovery】、【Zen Discovery】
Zen Discovery是ES内置的默认发现模块。发现模块用于发现集群中的节点以及选择主节点(master节点)。
Zen Discovery提供单播模式和基于文件的发现,并且可以扩展为通过插件支持其他形式的发现机制。
主要参数配置

discovery.zen.ping.multicast.enabled: true
discovery.zen.fd.ping_timeout: 100s
discovery.zen.ping.timeout: 100s
discovery.zen.minimum_master_nodes: 2
discovery.zen.ping.unicast.hosts: ["172.31.X.Y"]
discovery.zen.ping.multicast.enabled
参数 描述
discovery.zen.ping.multicast.enabled: true 关闭多播模式的自动发现机制,主要为了防止其他机器上的节点自动连入
discovery.zen.fd.ping_timeout: 100s和discovery.zen.ping.timeout: 100s 设置节点与节点之间连接ping命令执行的超时过长
discovery.zen.minimum_master_nodes: 2 集群中选举主节点时至少需要有多少个节点参与
discovery.zen.ping.unicast.hosts: ["172.31.X.Y"] 在单薄模式下,节点应该自动发现哪些节点列表。action.auto_create_index:false表示关闭自动创建索引

ES支持多播模式和单播模式自动两种节点发现机制。(❗不推荐多播模式,多播模式大多数系统不支持且安全性低)

🥖单播模式

🚫关闭多播模式: discovery.zen.ping.multicast.enabled:false #关闭多播
在ES中发现机制默认采用单播模式以防止节点无意中加入集群。
ES支持同一个主机🖥启动多个节点◼。只有在同一台机器上运行的节点才会自动组成集群。

集群的节点不再统一服务器上时需要进行节点的IP配置

# 填写集群中的IP地址列表
discovery.zen.ping.unicast.hosts: ["192.168.X1.Y1:9300","192.168.X2.Y2:9300"]

◼节点类型

ES中,每个节点既可以作为候选主节点也可以是数据节点
节点的角色配置在配置文件/config/elasticsearch.yml中设置即可。在ES中默认均为true

node.master: true //true 为候选主节点 false反之
node.data: true // 是否为数据节点

数据节点负责数据的存储相关操作。eg: 数据的C、R、U、D和聚合等
数据节点📕对服务器配置要求高

一旦候选主节点被选举为主节点(管家),则主节点就要负责创建索引、删除索引、追踪集群中节点的状态,以及跟踪哪些节点是群集的一部分,并决定将哪些分片分配给相关节点

分片和路由

在创建索引的时候就应该指定分片的数量(一旦确定无法修改)
分片的数量和副本数量可以通过创建索引时的Settings来配置
默认参数

index.number_of_shards: 5 # 主分片数5
index.number_of_replicas: 1 # 副分片数1

对文档的新建、索引和删除请求等写✍操作,必须先在主分片上完成之后才会复制到相关的副本分片。

ES为提高速度,并发执行写的过程为解决并发冲突💥使用乐观锁进行控制,每个文档都存在一个Verion(版本号),当文档被修改时版本号递增。
ES通过文档标识符ID将文档分配到多个分片上。当查询数据时,ES会查询所有的分片并汇总结果

数据写过程

数据写入操作在ES的内容中执行,数据分配到特定的分片和副本上,最终数据需要持久化到磁盘上
🌅ES的数据存储路径配置: ../config/elasticsearch.yml进行设置

path.data: /path/to/data  # 索引数据
path.logs: /path/to/logs  # 日志记录

🌅分段存储
索引数据以分段的形式存储在磁盘上。

索引文件拆分成多个子文件(段),每个段是倒排索引的最小单元
段具有不变性一旦持久化则无法更改。
分段的存储模式为了避免在读写操作时使用“锁🔒”,提升ES的读写性能。

索引文件存储后无法修改则如何进行数据的更新、删除、新增?

🤡新增

数据是新的只需要在当前文档新增一个段即可

🤡删除

删除数据时,分段由于存在不可逆(无法更改)特性,不会讲文档从旧的段中移除。而是新增一个🔅*.del文件。
.del文件中会记录这些被删除文档的段信息。被标记删除的文档仍然可以被查询匹配到,但最终结果被返回前通过🔅*.del文件在其结果集中移除*

🤡更新

分段不可逆特性,ES无法修改原有的段来更新。故而 📛更新操作 = 先删除 + 后新增
ES先将旧的文档从*.del文件中标记删除,然后将文档的新版本索引到一个新的段中。

🐷在查询数据时,两个版本的文档都会被一个查询匹配到,但被删除的旧版本文档在结果集返回前会被移除。

段的优势

段不需要锁🔒,提升了ES的读写性能。分段不变性的主要缺点是存储空间占用量大---> 当删除旧数据时,旧数据不会马上被删除而是在*.del文件中标记删除,旧数据只有等到段更新的时才会被删除,

延迟写策略

在ES中,索引写入磁盘的过程是异步的。

ES不会每次更新一条数据就会增加一个段到磁盘上而是采用延迟写策略。

每当有新的数据写入时,就将其写入JVM的内存中。在内存和磁盘之间时文件系统缓存。文件缓存空间使用的是OS的空间。当达到默认的时间或内存的数据达到一定量时,就会触发一次刷新(refresh)操作,将内存中的数据生成一个新的分段并缓存到文件缓存系统,之后刷新到磁盘💽并生成提交点🔴
新数据写入内存时,内存中的数据不是以段的形式存储只有当数据经由内存刷新到文件缓存系统,并生成新的段后,才供搜索使用,而不需要等到刷新到磁盘中才可以搜索。

ES中,写入和打开一个新段的过程称为刷新。(默认情况,每个分片会每秒自动刷新一次 ---> 这就是ES实现实时搜索🔍的原因)

settings中通过配置refresh_interval的值,调整索引的刷新频率。在设置值的时候要注意后面的时间单位,否则默认是 ms
当refresh_interval = -1时,表示关闭索引的自动刷新

延迟策略会减少数据持久化的次数,提升ES整体写入效率。当文件缓存系统来带来数据丢失的风险eg: 机房断电等不可控因素

解决此问题 ===》 引入事务日志(Translog)机制。事务日志用于记录所有还没有持久化到磁盘的数据。

段合并

ES自动刷新流程中,每秒都会创建一个新的段,导致短时间内段的数量猛增,当段数量太多时会带来较大资源消耗,eg:文件句柄、内存和CPU的消耗。
在内容搜索阶段,由于搜索请求要检查到每个段,然后合并并查询结果。因此段越多,检索速度越慢。
段合并: 将每次产生的小段合并成更大的段。在段合并过程中ES会将旧段从文件系统中清除。合并结束后,old段被删除,new段被Flush到磁盘中,同时写入
一个包含new段且排除old和较小的段的新提交点。打开新的段之后,可以用来搜索。

知识点互联

🐷 YAML(Yet Another Markup Language 一种置标语言),强盗YAML以数据作为中心,而不是以置标语言作为重点。

配置文件格式的历史

ini => JSON => XML => Properties => HOCON

HOCON(Human-Optimized Config Object Notation) 文件以.conf后缀
🐷ES和关系型数据库对比

ElasticSearch 关系型数据库
Indices(索引) Databases(库)
Types(类型) Tables(表)
Documents(文档) Rows(行)
Fields(字段) Columns(列)
Mapping(映射) schema
GET/POST/UPDATE/PUT/DELETE 增删改查

学问勤中得,萤窗万卷书

posted @ 2020-11-09 16:20  Felix_Openmind  阅读(759)  评论(0编辑  收藏  举报