Elasticsearch 学习

Elasticsearch 使用了有一段时间了, 一直没有做深入的学习,最近深入的学习总结一下.

ES主要的功能

  • 分布式的搜索引擎和数据分析引擎
  • 全文检索,结构化检索,数据分析
  • 对海量数据进行近实时的处理速度快

ES的存储结构

Es是面向文档型数据库, 一条数据在这里就是一个文档,用JSON作为文档序列的格式,当一个对象被序列化成为 JSON,它被称为一个 JSON 文档 。

1
2
3
4
5
6
{
"name":"PFinal社区",
"members":1000,
"desc":"PHP学习"
}

关系数据库 ⇒ 数据库 ⇒ 表 ⇒ 列(Columns)

Elasticsearch ⇒ 索引(Index) ⇒ 文档(Docments) ⇒ 字段(Fields)

在ES中以文档存储,每个文档都有自己的元数据存放自己的信息,其中:

ES的核心

  1. Cluster:集群

    ES可以作为单个搜索服务器,不过在大数据集的时候 ES可以运行在许多互相合作的服务器上,形成集群,一个集群就是由一个或多个节点组织在一起,它们共同持有整个的数据,并一起提供索引和搜索功能。

  2. Node: 节点

    节点是集群中的一个服务器,作为集群的一部分,它存储数据,参与集群的索引和搜索功能。一个节点可以通过配置集群名称的方式来加入一个指定的集群。默认情况下,每个节点都会被安排加入到一个叫做“elasticsearch”的集群中,

  3. Shard: 分片

    当有大量的文档时,由于内存的限制、磁盘处理能力不足、无法足够快的响应客户端的请求等,一个节点可能不够。或者单个节点处理搜索请求,响应太慢。这种情况下,数据可以分为较小的分片。每个分片放到不同的服务器上。 每个分片本身也是一个功能完善并且独立的“索引”,这个“索引”可以被放置到集群中的任何节点上。

  4. Replia: 副本

    为提高查询吞吐量或实现高可用性,可以使用分片副本。 副本是一个分片的精确复制,每个分片可以有零个或多个副本。ES中可以有许多相同的分片,其中之一被选择更改索引操作,这种特殊的分片称为主分片。

    当主分片丢失时,如:该分片所在的数据不可用时,集群将副本提升为新的主分片。

ES中的几个概念

  1. 正向索引

    正排表是以文档的ID为关键字,表中记录文档中每个字的位置信息,查找时扫描表中每个文档中字的信息直到找出所有包含查询关键字的文档。

    这种组织方法在建立索引的时候结构比较简单,建立比较方便且易于维护;因为索引是基于文档建立的,若是有新的文档加入,直接为该文档建立一个新的索引块,挂接在原来索引文件的后面。若是有文档删除,则直接找到该文档号文档对应的索引信息,将其直接删除。但是在查询的时候需对所有的文档进行扫描以确保没有遗漏,这样就使得检索时间大大延长,检索效率低下。

  2. 倒排索引

    倒排表以字或词为关键字进行索引,表中关键字所对应的记录表项记录了出现这个字或词的所有文档,一个表项就是一个字表段,它记录该文档的ID和字符在该文档中出现的位置情况。

    由于每个字或词对应的文档数量在动态变化,所以倒排表的建立和维护都较为复杂,但是在查询的时候由于可以一次得到查询关键字所对应的所有文档,所以效率高于正排表。在全文检索中,检索的快速响应是一个最为关键的性能,而索引建立由于在后台进行,尽管效率相对低一些,但不会影响整个搜索引擎的效率。

正排索引是从文档到关键字的映射(已知文档求关键字),倒排索引是从关键字到文档的映射(已知关键字求文档)。

  1. 分片关系

    在 ES 中为了应对并发更新的问题上, ES 采用主从模式, 主分片的数据作为权威数据, 写入的过程优先写入主分片, 成功执行后再写入副分片, 在数据恢复阶段的时候亦是以主分片的数据为基准.

    一个 ES 索引包含很多个分片, 一个分片就是一个 Lucene 索引, 一个 Lucene 索引包含很多个分段, 一个分段是由多个倒排索引组成, 一个倒排索引包含若干个文档数据, 一个文档数据由若干个词构成, 词是经过分词器处理和语言处理最后的结果。

  2. ES 分词器(Analyzer)

    分词器的作用是:把文本内容的词按一定规则进行切割分离,对应的是Analyzer 类,这是一个抽象基类,切分词的具体规则是由子类继承实现的,所以对于不同的语言的条件下,需要用不同的分词器。在创建索引时和数据搜索时都会用到分词器,并且使用的分词器需要统一,否则将会出现数据检索为空的情况

Docker 安装 ES

  1. docker-composer 编排es集群
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
version: '2.2'
services:
es01:
image: elasticsearch:7.5.1
container_name: es01
environment:
- node.name=es01
- cluster.name=es-docker-cluster
- discovery.seed_hosts=es02
- cluster.initial_master_nodes=es01,es02
- bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- data01:/usr/share/elasticsearch/data
ports:
- 9200:9200
networks:
- elastic
es02:
image: elasticsearch:7.5.1
container_name: es02
environment:
- node.name=es02
- cluster.name=es-docker-cluster
- discovery.seed_hosts=es01
- cluster.initial_master_nodes=es01,es02
- bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- data02:/usr/share/elasticsearch/data
networks:
- elastic
kibana:
image: kibana:7.5.1
container_name: kibana
restart: always
ports:
- "5601:5601"
environment:
I18N_LOCALE: zh-CN #汉化
networks:
- elastic
links:
- es01:elasticsearch
volumes:
data01:
driver: local
data02:
driver: local
networks:
elastic:
driver: bridge
  1. docker-composer 编排单点
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
elasticsearch:
image: elasticsearch:7.7.0
ports:
- "9200:9200"
- "9300:9300"
volumes:
- ./conf/elasticsearch/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml
- ./elasticsearch/data:/usr/share/elasticsearch/data
- ./elasticsearch/plugins:/usr/share/elasticsearch/plugins
- ./log/elasticsearch/:/usr/share/elasticsearch/logs
user: ${ES_UID}
command: ["sh", "-c", "./bin/elasticsearch"]
environment:
- "ES_JAVA_OPTS=-Xms2g -Xmx2g"
- "discovery.type=single-node"
- "COMPOSE_PROJECT_NAME=elasticsearch-server"