notebook notebook
首页
  • 计算机网络
  • 计算机系统
  • 数据结构与算法
  • 计算机专业课
  • 设计模式
  • 前端 (opens new window)
  • Java 开发
  • Python 开发
  • Golang 开发
  • Git
  • 软件设计与架构
  • 大数据与分布式系统
  • 常见开发工具

    • Nginx
  • 爬虫
  • Python 数据分析
  • 数据仓库
  • 中间件

    • MySQL
    • Redis
    • Elasticsearch
    • Kafka
  • 深度学习
  • 机器学习
  • 知识图谱
  • 图神经网络
  • 应用安全
  • 渗透测试
  • Linux
  • 云原生
面试
  • 收藏
  • paper 好句
GitHub (opens new window)

学习笔记

啦啦啦,向太阳~
首页
  • 计算机网络
  • 计算机系统
  • 数据结构与算法
  • 计算机专业课
  • 设计模式
  • 前端 (opens new window)
  • Java 开发
  • Python 开发
  • Golang 开发
  • Git
  • 软件设计与架构
  • 大数据与分布式系统
  • 常见开发工具

    • Nginx
  • 爬虫
  • Python 数据分析
  • 数据仓库
  • 中间件

    • MySQL
    • Redis
    • Elasticsearch
    • Kafka
  • 深度学习
  • 机器学习
  • 知识图谱
  • 图神经网络
  • 应用安全
  • 渗透测试
  • Linux
  • 云原生
面试
  • 收藏
  • paper 好句
GitHub (opens new window)
  • 爬虫

  • Python 数据分析

  • MySQL

  • Redis

  • Elasticsearch

    • Elasticsearch 核心技术与实战

      • 基本概念与操作
        • 1. Elasticsearch 的安装
          • 1.1 安装 Java
          • 1.2 获取 Elasticsearch 安装包
          • 1.3 Elasticsearch 的文件目录结构
          • 1.4 JVM 配置
          • 1.5 安装与查看插件
          • 1.6 如何在开发机上运行多个 Elasticsearch 实例
          • 1.7 kibana 的安装与界面浏览
          • 1.8 Logstash 的安装
        • 2. 基本概念
          • 2.1 文档(Document)
          • 2.2 索引(Index)
          • 2.3 Type
          • 2.4 节点
          • 2.5 分片
        • 3. 文档的基本 CRUD 和批量操作
          • 3.1 基本 CRUD
          • 3.2 Bulk API
          • 3.3 常见返回错误
        • 4. 倒排索引
          • 4.1 什么是倒排索引
          • 4.2 倒排索引的核心组成
        • 5. 通过 Analyzer 进行分词
          • 5.1 Analysis
          • 5.2 Analyzer 的组成
          • 5.3 _analyzer API
          • 5.4 ES 内置的分词器
          • 5.5 中文分词
      • Search API
  • Kafka

  • 数据仓库

  • 数据科学
  • Elasticsearch
  • Elasticsearch 核心技术与实战
yubin
2023-04-08
目录

基本概念与操作

参考 Elasticsearch 核心技术与实战 | 极客时间 (opens new window)的 01~13 讲

# 1. Elasticsearch 的安装

# 1.1 安装 Java

运行 ES,需要安装并配置 JDK,即设置 $JAVA_HOME。

各版本对 Java 的依赖:

  • ES 5 需要 Java 8 以上的版本
  • ES 6.5 开始支持 Java 11
  • 7.0 开始,内置了 Java 环境

# 1.2 获取 Elasticsearch 安装包

下载页 (opens new window)

# 1.3 Elasticsearch 的文件目录结构

目录 配置文件 描述
bin 脚本文件,包括启动 ES,安装插件,运行统计数据等
config elasticsearch 集群配置文件,user、role based 相关配置
JDK Java 运行环境
data path.data 数据文件
lib Java 类库
logs path.log 日志文件
modules 包含所有 ES 模块
plugins 包含所有已安装插件

# 1.4 JVM 配置

  • 修改 JVM - config/jvm.options
    • 7.1 下载的默认设置是 1 GB
  • 生产配置的建议
    • Xmx 和 Xms 设置成一样
    • Xmx 不要超过机器内存的 50%
    • 内存总量不要超过 30GB

# 1.5 安装与查看插件

$ bin/elasticsearch-plugin install analysis-icu
-> Downloading analysis-icu from elastic
[===============================================]100%
-> Installed analysis-icu

$ bin/elasticsearch-plugin list
analysis-icu
1
2
3
4
5
6
7

或者访问 localhost:9200/_cat/plugins?v

Elasticsearch 提供插件的机制对系统进行扩展:

  • Discovery Plugin
  • Analysis Plugin
  • Security Plugin
  • Management Plugin
  • Ingest Plugin
  • Mapper Plugin
  • Backup Plugin

# 1.6 如何在开发机上运行多个 Elasticsearch 实例

  • bin/elasticsearch -E node.name=node1 -E cluster.name=geektime -E path.data=node1_data -d
  • bin/elasticsearch -E node.name=node2 -E cluster.name=geektime -E path.data=node2_data -d
  • bin/elasticsearch -E node.name=node3 -E cluster.name=geektime -E path.data=node3_data -d

删除进程:ps | grep elasticsearch,kill pid。

然后通过访问 localhost:9200/_cat/nodes 来得到结果。

# 1.7 kibana 的安装与界面浏览

下载后,/bin/kibana 即可启动。

# 1.8 Logstash 的安装

# 2. 基本概念

# 2.1 文档(Document)

Elasticsearch 是面向文档的,文档是所有可搜索数据的最小单位。比如:

  • 日志文件中的日志项
  • 一本电影的具体信息 / 一张唱片的详细信息
  • MP3 播放器里的一首歌/一篇 PDF 文档中的具体内容

文档会被序列化成 JSON 格式,保存在 Elasticsearch 中:

  • JSON 对象由字段组成
  • 每个字段都有对应的字段类型(字符串/数值/布尔/日期/二进制/范围类型)

每个文档都有一个 Unique ID,你可以自己指定这个 ID,也可以通过 Elasticsearch 自动生成。

# 2.1.1 JSON 文档

  • 一篇文档包含了一系列的字段。类似数据库表中一条记录。
  • JSON 文档,格式灵活,不需要预先定义格式:
    • 字段的类型可以指定或者通过 Elasticsearch 自动推算
    • 支持数组 / 支持嵌套

# 2.1.2 文档的元数据

元数据,用于标注文档的相关信息

  • _index:文档所属的索引名
  • _type:文档所属的类型名
  • _id:文档唯一 ID
  • _source:文档的原始 JSON 数据
  • _all:整合所有字段内容到该字段,已被废除
  • _version:文档的版本信息
  • _score:相关性打分(做全文检索是很重要)
20230408214255

# 2.2 索引(Index)

索引(Index)是文档的容器,是一类文档的结合:

  • Index 体现了逻辑空间的概念: 每个索引都有自己的 Mapping 定义,用于定义包含的文档的字段名和字段类型。
  • Shard 体现了物理空间的概念: 索引中的数据分散在 Shard 上

索引的 Mapping 与 Settings:

  • Mapping 定义文档字段的类型
  • Setting 定义不同的数据分布

索引的不同语意

  • 名词:一个 Elasticsearch 集群中,可以创建很多个不同的索引
  • 动词:保存一个文档到 Elasticsearch 的过程也叫索引(indexing)
    • ES 中,创建一个倒排索引的过程
  • 名词:一个 B 树索引,一个倒排索引

# 2.3 Type

在 7.0 之前,一个Index 可以设置多个 Types。从 6.0 开始,Type 已经被 Deprecated。7.0 开始,一个索引只能创建一个 _doc 的 Type。

传统关系型数据库与 Elasticsearch 的一个不太恰当的类比:

20230408215032
  • Elasticsearch:Schemaless / 相关性 / 高性能全文检索
  • RDMS:事务性 / Join

# 2.4 节点

# 2.4.1 ES 的分布式

分布式系统的可用性和扩展性:

  • 高可用性:
    • 服务可用性:允许有节点停止服务
    • 数据可用性:部分节点丢失,不会丢失数据
  • 可扩展性:
    • 请求量提升/数据的不断增长 (将数据分布到所有节点上)

Elasticsearch 的分布式架构的好处

  • 存储的水平扩容
  • 提高系统的可用性,部分节点停止服务,整个集群的服务不受影响

Elasticsearch 的分布式架构:

  • 不同的集群通过不同的名字来区分,默认名字“elasticsearch“
  • 通过配置文件修改,或者在命令行中 -E cluster.name=geektime 进行设定
  • 一个集群可以有一个或者多个节点

# 2.4.2 节点的概念

节点是一个 Elasticsearch 的实例,本质上就是一个 Java 进程,生产环境一般建议一台机器只运行一个 Elasticsearch 实例。

  • 每一个节点都有名字,通过配置文件配置,或者启动时候使用命令行 -E node.name=node1 指定
  • 每一个节点在启动之后,会分配一个 UID,保存在 data 目录下

# 2.4.3 Master eligible nodes 与 Master Node

每个节点启动后,默认就是一个 Master eligible 节点,它可以参加选主流程,进而成为 Master 节点。

  • 可以设置 node.master: false 禁止一个节点成为 Master eligible 节点。
  • 当第一个节点启动时候,它会将自己选举成 Master 节点。
  • 每个节点上都保存了集群的状态,只有 Master 节点才能修改集群的状态信息,否则会导致数据的不一致。

集群状态(Cluster State)是指维护了一个集群中的必要信息,比如:

  • 所有的节点信息
  • 所有的索引和其相关的 Mapping 与 Setting 信息
  • 分片的路由信息

# 2.4.4 不同类型的节点

  • Data Node:可以保存数据的节点。它负责保存分片数据,在数据扩展上起到了至关重要的作用。

当集群已经无法再保存现有数据时,就可以通过增加一个 Data Node 的实例来扩展。

  • Coordinating Data:负责接受 Client 的请求,将请求分发到合适的节点,最终把结果汇集到一起。

    • 每个节点默认都起到了 Coordinating Node 的职责。
  • Hot & Warm Node

    • Hot Node 是那些配置较高的节点
    • Warm Node 是那些配置较低的节点,往往存储一些较旧的数据
    • 通过不同硬件配置的 Data node,用来实现 Hot & Warm 架构,可以降低集群部署的成本。
  • Machine Learning Node

    • 负责跑机器学习的 Job,用来做异常检测
  • Tribe Node

    • Tribe Node 连接到不同的 Elasticsearch 集群并且支持将这些集群当成一个单独的集群处理
    • 面临淘汰,5.3 后开始使用 Cross Cluster Serarch

# 2.4.5 配置节点类型

  • 开放环境中一个节点可以承担多种角色
  • 生产环境中,应该设置单一的角色的节点(dedicated node)
20230408221655

# 2.5 分片

# 2.5.1 分片的概念

存在 Primary Shard 和 Replica Shard,实现了一个主从架构。

  • Primary Shard(主分片),用以解决数据水平扩展的问题。通过主分片,可以将数据分布到集群内的所有节点之上。

    • 一个分片是一个运行的 Lucene 的实例
    • 主分片数在索引创建时指定,后续不允许修改,除非 Reindex
  • Replica Shard(副本),用以解决数据高可用的问题。分片是主分片的拷贝。

    • 副本分片数,可以动态调整
    • 增加副本数,还可以在一定程度上提高服务的可用性(读取的吞吐)

这里就是数据复制和数据分区同时使用了。

下面看一个三节点的集群中,blogs 索引的分片分布情况:

20230408222502

看 Settings 就知道:

  • number_of_shards:表示由 3 个主分片
  • number_of_replicas:表示每个主分片有 1 个副本

# 2.5.2 分片的设定

对于生产环境中分片的设定,需要提前做好容量规划:

  • 如果分片数设置过小:
    • 导致后续无法增加节点实现水品扩展;
    • 单个分片的数据量太大,导致数据重新分配耗时;
  • 如果分片数设置过大:
    • 影响搜索结果的相关性打分,影响统计结果的准确性;
    • 单个节点上过多的分片,会导致资源浪费,同时也会影响性能;

7.0 开始,默认主分片从 5 改成 1,解决了 over-sharding 的问题。

# 2.5.3 分片的健康状况

  • Green:主分片与副本都正常分配
  • Yellow:主分片全部正常分配,有副本分片未能正常分配
  • Red:有主分片未能分配
20230408223209

相关 API

  • GET _cluster/health:查看集群的健康状况
  • GET _cat/nodes:查看集群 nodes 的信息
  • GET _cat/shards:查看集群的分片信息

# 3. 文档的基本 CRUD 和批量操作

# 3.1 基本 CRUD

20230408224148

# 3.1.1 Create 一个文档

  • 支持自动生成文档 ID 和指定文档 ID 两种方式:
    • 调用 POST users/_doc 会自动生成文档 ID
    • 调用 PUT user/_create/1 则指定文档 ID 为 1,如果该 ID 的文档已存在,则操作失败。
20230408224823

# 3.1.2 Get 一个文档

  • 找到文档,返回 HTTP 200
    • 其中文档元信息部分,_version 的值代表经过了多少次改动,因为同一 ID 的文档,即使被删除,version 号也会不断增加。
    • _source 中默认包含了文档的所有原始信息。
  • 找不到文档,返回 HTTP 404
20230408224934

# 3.1.3 Index 文档

Index 和 Create 不一样的地方: 如果文档不存在,就索引新的文档。否则现有文档会被删除,新的文档被索引。_version 会加 1。

# 3.1.4 Update 文档

Update 方法不会删除原来的文档,而是实现真正的数据更新。

它的 POST 方法的 payload 需要包含在 “doc” 中:

20230408225413

# 3.2 Bulk API

批量操作,可以减少网络连接所产生的开销,提高性能。

# 3.2.1 bulk 操作

支持四种类型操作:Index、Create、Update、Delete

  • 可以再 URL 中指定 index,也可以在请求的 Payload 中进行。
  • 操作中单条操作失败,并不会影响其他操作。
  • 返回结果包括了每一条操作执行的结果。
20230409114144

但一次也别发送过多的数据。

# 3.2.2 批量读取:mget

GET _mget
{
  "docs": [
    {
      "_index": "user",
      "_id": 1
    },
    {
      "_index": "comment",
      "_id": 1
    }
  ]
}
1
2
3
4
5
6
7
8
9
10
11
12
13

# 3.2.3 批量查询:msearch

POST /users/_msearch

{}
{"query": {"match_all": {}}, "from": 0, "size": 10}
{}
{"query": {"match_all": {}}}
{"index": "twitter2"}
{"query": {"match_all": {}}}
1
2
3
4
5
6
7
8

# 3.3 常见返回错误

问题 原因
无法连接 网络故障或集群挂了
连接无法关闭 网络故障或节点出错
429 集群过于繁忙
4xx 请求体格式有错
500 集群内部错误

# 4. 倒排索引

# 4.1 什么是倒排索引

  • 正排索引:doc ID -> doc
  • 倒排索引:term -> doc ID
20230409211304

# 4.2 倒排索引的核心组成

倒排索引包含两个部分:

  • 单词词典(Term Dictionary),记录所有文档的单词,记录单词到倒排列表的关联关系
    • 单词词典一般比较大,可以通过 B+ 树或哈希拉链法实现,以满足高性能的插入与查询
  • 倒排列表(Posting List),记录了单词对应的文档组合,由倒排索引项组成
    • 倒排索引项(Posting)
      • 文档 ID
      • 词频 TF - 该单词在文档中出现的次数,用于相关性评分
      • 位置(Position) - 单词在文档中分词的位置。用于语句搜索(phrase query)
      • 偏移(Offset) - 记录单词的开始结束位置,实现高亮显示

示例:以 term Elasticsearch 为例来展示:

20230410205622

Elasticsearch 对 doc 的每个字段,都有自己的倒排索引。

你可以指定对某些字段不做索引

  • 优点:节省存储空间
  • 缺点:字段无法被搜索

# 5. 通过 Analyzer 进行分词

# 5.1 Analysis

Analysis:文本分析是把全文本转换一系列单词 (term / token) 的过程,也叫分词。

Analysis 是通过 Analyzer(分词器)来实现的,可以使用 Elasticsearch 内置的分析器,或者按需定制化分析器。

除了在数据写入时转换词条,匹配 Query 语句时候也需要用相同的分析器对查询语句进行分析。

下图是一个分词的示例:

20230410212527
  • 可以看到,分词器将 Elasticsearch Server 分成了 elasticsearch 和 server,不仅分成了两个单词,还都变成了小写。

# 5.2 Analyzer 的组成

Analyzer(分词器)是专门处理分词的组件,由三部分组成:

  • Character Filters:针对原始文本处理,例如去除 html
  • Tokenizer:按照规则切分为单词
  • Token Filter:将切分的的单词进行加工:小写,删除 stopwords,增加同义词等

如下图所示:

20230410212942

# 5.3 _analyzer API

使用 _analyzer API 可以用三种方式来查看 Analyzer 是如何工作的。

# 1)直接指定 Analyzer 进行测试

20230410214946

# 2)指定索引的字段进行测试

20230410215006

# 3)自定义分词器进行测试

20230410215030

# 5.4 ES 内置的分词器

Elasticsearch 内置的分词器有如下:

  • Standard Analyzer:默认分词器,按词切分,小写处理
  • Simple Analyzer:按照非字母切分 (符号被过滤),小写处理
  • Stop Analyzer:小写处理,停用词过滤 (the,a,is)
  • Whitespace Analyzer:按照空格切分,不转小写
  • Keyword Analyzer:不分词,直接将输入当作输出
  • Patter Analyzer:正则表达式,默认 \W+(非字符分隔)
  • Language:提供了 30 多种常见语言的分词器
  • Customer Analyzer:自定义分词器

下面依次看一下。

# 1)Standard Analyzer

它是默认的分词器:按词切分,小写处理。

20230410215417

可以在 Kibana 的 dev tools 中进行如下尝试:

GET _analyze
{
  "analyzer": "standard",
  "text": "2 running Quick brown-foxes leap over lazy dogs in the summer evening."
}
1
2
3
4
5

# 2)Simple Analyzer

按照非字母切分,非字母的都被去除,并小写处理。

20230410223313
GET _analyze
{
  "analyzer": "simple",
  "text": "2 running Quick brown-foxes leap over lazy dogs in the summer evening."
}
1
2
3
4
5

# 3)Whitespace Analyzer

按照空格切分。

20230410223702
GET _analyze
{
  "analyzer": "whitespace",
  "text": "2 running Quick brown-foxes leap over lazy dogs in the summer evening."
}
1
2
3
4
5

# 4)Stop Analyzer

相比 Simple Analyzer,多了 stop filter,这会把 the、a、is 等修饰性词语去除掉。

20230410223828
GET _analyze
{
  "analyzer": "stop",
  "text": "2 running Quick brown-foxes leap over lazy dogs in the summer evening."
}
1
2
3
4
5

# 5)Keyword Analyzer

不分词,直接将输入当一个 term 输出。

20230410224112
GET _analyze
{
  "analyzer": "keyword",
  "text": "2 running Quick brown-foxes leap over lazy dogs in the summer evening."
}
1
2
3
4
5

# 6)Pattern Analyzer

通过正则表达式进行分词,默认是 \W+,即按照非字符的符号进行分割。

20230410224432
GET _analyze
{
  "analyzer": "pattern",
  "text": "2 running Quick brown-foxes leap over lazy dogs in the summer evening."
}
1
2
3
4
5

# 7)Language Analyzer

20230410224626
GET _analyze
{
  "analyzer": "english",
  "text": "2 running Quick brown-foxes leap over lazy dogs in the summer evening."
}
1
2
3
4
5
  • 可以看到,经过这里的分词,running 被变成了 run,foxes 被变成了 fox 等,以及也停用了 in 等 term。

# 5.5 中文分词

中文分词也就是将中文句子切分成一个个的 term,而不是一个个字,但根据不同的上下文语境,一句中文的不同切分方法会有不同的理解。

这里需要用到 ICU Analyzer:

  • 需要安装:elasticsearch-plugin install analysis-icu
  • 它提供了 Unicode 的支持,更好的支持亚洲语言
20230410225238

对比一下 ICU Analyzer 和 Standard Analyzer,standard 的会将中文切分成一个字一个字,但 icu_analyzer 则会有更好的表现:

GET _analyze
{
  "analyzer": "standard",
  "text": "他说的的确在理"
}

GET _analyze
{
  "analyzer": "icu_analyzer",
  "text": "他说的的确在理"
}
1
2
3
4
5
6
7
8
9
10
11

尽管如此,icu_analyzer 表现仍然不是很让人满意,社区中还有更多的中文分词器,他们的表现会更好:

  • IK
    • 支持自定义词库,支持热更新分词字典
    • IK Github (opens new window)
  • THULAC
    • THU LexucalAnalyzer for Chinese,清华大学自然语言处理和社会人文计算实验室的一套中文分词器
    • THULAC Github (opens new window)
编辑 (opens new window)
上次更新: 2023/04/26, 13:34:07
集群的数据倾斜和通信开销问题
Search API

← 集群的数据倾斜和通信开销问题 Search API→

最近更新
01
Deep Reinforcement Learning
10-03
02
误删数据后怎么办
04-06
03
MySQL 一主多从
03-22
更多文章>
Theme by Vdoing | Copyright © 2021-2024 yubincloud | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×