一 相关概念
1 介绍
Elasticsearch(简称 ES)是一个基于 Apache Lucene 的开源分布式、RESTful 风格的搜索和分析引擎,专为处理大规模数据集的实时搜索、分析和可视化而设计。它支持全文检索、结构化搜索、数据分析、地理空间搜索等多种功能,广泛应用于日志分析、全文检索、商业智能、安全分析等场景。
2 Elastic Stack(ELK)
Elastic Stack 由 Elasticsearch、Logstash、Kibana 和 Beats 组成,是一套完整的开源数据收集、处理、存储和可视化解决方案,广泛应用于日志分析、实时监控、安全分析等领域。是日志数据分析与实时监控的核心架构,其中:
Elasticsearch
数据存储与搜索引擎。可存储日志、指标等结构化/非结构化数据。提供全文检索、聚合分析、实时查询能力。支持分布式扩展,处理 PB 级数据。
关键特性:近实时搜索(通常 1 秒内可检索)。水平扩展(通过分片和副本)。RESTful API,易于集成。
Kibana
数据可视化与分析平台。可创建仪表盘、图表(如折线图、饼图)。实时监控数据趋势(如错误率、请求延迟)。支持交互式查询(如通过 Dev Tools 调试 ES 查询)。
关键特性:直观的 UI,适合非技术人员使用。支持告警规则配置(如异常检测)。
Logstash
数据管道(ETL 工具)。可收集日志(如文件、数据库、消息队列)。解析、过滤、转换数据(如 JSON 解析、字段提取)。输出到 Elasticsearch 或其他存储(如 S3)。
关键特性:支持插件化扩展(如输入插件 file、输出插件 elasticsearch)。可处理复杂的数据清洗逻辑。
Beats
轻量级数据采集器。可针对特定场景的采集工具(如 Filebeat 采集日志、Metricbeat 采集系统指标)。低资源占用,适合部署在边缘设备。
关键特性:开箱即用,配置简单。支持多输出(如直接发送到 ES 或 Logstash)。
二 倒排索引
1 构建格式
ES其核心优势在于倒排索引
结构,使其能够高效处理全文检索、复杂查询和实时分析。与传统的正向索引(文档 ID → 内容)不同,倒排索引将数据结构反转,存储数据时,记录每个词条(Term)出现在哪些文档中。
正向:
id → | 文档 |
---|---|
1 | 大疆无人机 |
2 | 小米无人机 |
3 | 大疆Pocket 3 |
倒排:
词条(Term)→ | 文档 ID 列表(Posting List) |
---|---|
大疆 | 1,3 |
无人机 | 1,2 |
Pocket 3 | 3 |
词条(Term)文档内容经过分词后的最小语义单元。
"大疆无人机" → 分词为 ["大疆", "无人机"]。
文档 ID 列表(Posting List)记录包含该词条的所有文档 ID,通常按相关性排序。
大疆 → [1, 3] # 文档 1 和 3 包含“大疆”
无人机 → [1, 2] # 文档 1 和 2 包含“无人机”
附加信息(可选)词频(TF):词条在文档中出现的次数。位置信息:词条在文档中的具体位置(用于短语查询)。权重:如 TF-IDF 分数,用于排序。
2 倒排索引的查询流程
① 用户输入处理:用户输入查询词:“大疆 无人机”,系统进行分词,拆分为词项:[“大疆”, “无人机”]。
② 倒排索引查找:分别查找每个词项对应的倒排列表
“大疆” → 包含该词的文档ID集合:[1, 3]
“无人机” → 包含该词的文档ID集合:[1, 2]
③ 集合运算(取交集):对两个倒排列表执行交集操作
[1, 3] ∩ [1, 2] = [1]
结果:仅文档 1 同时包含“华为”和“手机”。
④ 返回结果:命中文档 1,内容为:“大疆无人机发布”。
⑤ 若用户查询"华为 OR 手机"(逻辑或),则取并集:[1, 3] ∪ [1, 2] = [1, 2, 3],返回文档1、2、3。
三 文档与索引
1 文档
① 定义:文档是 Elasticsearch 中的最小数据单元,对应业务中的一条记录(如商品、订单、日志等)。
② 格式:文档以 JSON 格式存储,字段可以是任意类型(字符串、数字、日期、嵌套对象等)。
③ 示例:
{
"id": 1,
"title": "大疆无人机",
"price": 3499
},
{
"id": 2,
"title": "小米无人机",
"price": 2999
},
{
"id": 3,
"title": "大疆Pocket 3",
"price": 3599
}
2 索引
① 定义:索引是 Elasticsearch 中存储相同类型文档集合的逻辑容器,类似于关系型数据库中的“表”。逻辑上隔离不同类型的数据(如商品、用户、订单)。支持分布式存储和查询。
② 示例:
商品索引(products) | 存储商品信息(如品牌、功能等)。 |
---|---|
用户索引(users) | 存储用户信息(如姓名、年龄等)。 |
订单索引(orders) | 存储订单信息(如用户ID、商品ID、总金额等)。 |
// 商品索引
[
{
"id": 1,
"title": "大疆无人机",
"price": 3499
},
{
"id": 2,
"title": "小米无人机",
"price": 2999
},
{
"id": 3,
"title": "大疆Pocket 3",
"price": 3599
}
]
// 用户索引
[
{
"id": 66,
"name": "大黄",
"age": 21
},
{
"id": 88,
"name": "小黄",
"age": 24
}
]
3 映射(Mapping)
Elasticsearch 中为上述索引定义的映射(可通过 API 动态生成或手动指定),定义字段类型,优化存储和搜索性能(如 text 字段支持分词,keyword 字段支持聚合)。约束字段格式(如日期格式、数字范围)。
// 商品索引映射
PUT /products
{
"mappings": {
"properties": {
"id": { "type": "integer" },
"title": { "type": "text" },
"price": { "type": "integer" }
}
}
}
// 用户索引映射
PUT /users
{
"mappings": {
"properties": {
"id": { "type": "integer" },
"name": { "type": "keyword" },
"age": { "type": "integer" }
}
}
}
4 核心概念对比表
MySQL(关系型数据库) | Elasticsearch(搜索与分析引擎) | 说明 |
---|---|---|
Table(表) | Index(索引) | 存储数据的逻辑容器,类似“表”。 |
Row(行) | Document(文档) | 单条数据记录,类似“行”。 |
Column(列) | Field(字段) | 文档中的键值对,类似“列”。 |
Schema(表结构) | Mapping(映射) | 定义字段类型、约束等,类似“表结构”。 |
SQL(结构化查询语言) | DSL(领域特定语言) | Elasticsearch 的 JSON 风格查询语言,用于 CRUD 和搜索。 |
主键/外键 | 文档 ID(_id) | 文档的唯一标识符,无显式外键关系(需通过应用层关联)。 |
事务(ACID) | 近实时(NRT) | Elasticsearch 不支持严格事务,但提供近实时搜索(写入后约 1 秒可搜索)。 |
四 安装 Elasticsearch
1 拉取docker镜像 elasticsearch 7.6.1 可使用jdk8
docker pull elasticsearch:7.6.1
2 构建目录结构
mkdir -p /usr/local/docker/elasticsearch/{config,data,plugins}
3 创建配置文件并写入内容
vim /usr/local/docker/elasticsearch/config/elasticsearch.yml
# 指定 Elasticsearch HTTP API 监听的网络接口。0.0.0.0 表示绑定到所有可用网络接口
http.host: 0.0.0.0
# 定义 Elasticsearch 集群的名称。同一集群的所有节点必须使用相同的名称。
cluster.name: "docker-cluster"
#控制 Elasticsearch 所有网络通信的绑定地址(包括 HTTP API 和内部节点通信)。0.0.0.0 表示允许通过所有网络接口通信
network.host: 0.0.0.0
4 创建专属网络
# 创建一个名为 es-net 的 Docker 网络 给两者通信交流
docker network create es-net
5 运行 Elasticsearch 容器
docker run -d \
--name elasticsearch \
--privileged \
--network es-net \
-p 9200:9200 \
-p 9300:9300 \
-e "discovery.type=single-node" \
-e "ES_JAVA_OPTS=-Xms512m -Xmx512m" \
-v /usr/local/docker/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \
-v es-data:/usr/share/elasticsearch/data \
-v es-plugins:/usr/share/elasticsearch/plugins \
elasticsearch:7.6.1
-d:以后台模式运行容器。
--name elasticsearch:为容器指定一个名称。
-p 9200:9200 和 -p 9300:9300:将容器的 9200 和 9300 端口映射到主机的对应端口。9200 端口用于 HTTP REST API 请求,9300 端口用于 Elasticsearch 分布式集群状态下节点之间的通信。
-e "discovery.type=single-node":以单节点模式启动 Elasticsearch。
-e "ES_JAVA_OPTS=-Xms512m -Xmx512m":设置 Elasticsearch 启动时占用的 JVM 内存大小。
创建命名卷 "es-data" 持久化数据
创建命名卷 "es-plugins" 持久化插件
6 通过ip地址验证
五 安装 Kibana
1 创建目录
sudo mkdir -p /usr/local/docker/kibana/config/
2 编写配置文件
vim /usr/local/docker/kibana/config/kibana.yml
server.name: kibana
server.host: "0.0.0.0"
elasticsearch.hosts: ["http://elasticsearch:9200"]
i18n.locale: "zh-CN"
3 拉取运行 Kibana 镜像
docker run -d \
--name kibana \
-p 5601:5601 \
--network=es-net \
-e ELASTICSEARCH_HOSTS=http://elasticsearch:9200 \
-v /usr/local/docker/kibana/config/kibana.yml:/usr/share/kibana/config/kibana.yml \
kibana:7.6.1
4 通过ip验证成功
六 安装 IK 分词器
1 各版本IK分词器下载
2 查看挂载卷所在位置
[root@localhost plugins]# docker volume inspect es-plugins
[
{
"CreatedAt": "2025-06-29T23:45:37+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/es-plugins/_data",
"Name": "es-plugins",
"Options": null,
"Scope": "local"
}
]
3 解压文件并上传
存放至刚查询出的挂在卷所在位置目录中即可,此处使用的是Xftp
# 刚查询出的挂在卷所在位置
/var/lib/docker/volumes/es-plugins/_data
# 若需要显式配置绑定挂载目录
/usr/local/docker/elasticsearch/plugins
4 重启容器
docker restart elasticsearch
5 IK 分词器的两种模式
① ik_smart(粗粒度切分,分词少)
POST /_analyze
{
"analyzer": "ik_smart",
"text": "自然语言处理技术"
}
② ik_max_word(细粒度切分,分词多)
POST /_analyze
{
"analyzer": "ik_max_word",
"text": "自然语言处理技术"
}
对比维度 | ik_smart(最少切分) | ik_max_word(最细切分) |
---|---|---|
切分粒度 | 粗粒度(尽可能少切分) | 细粒度(尽可能多切分) |
分词结果数量 | 较少(返回核心词汇) | 较多(返回所有可能的子词组合) |
适用场景 | 快速匹配、分类、标签、短语搜索 | 全文检索、模糊匹配、语义分析 |
性能开销 较低 | (计算量少) | 较高(需要生成更多子词) |
典型输出示例 | “自然语言处理技术” → [自然语言处理技术"] | “自然语言处理技术” → [“自然”, “自然语言”, “语言”, “处理”, “技术”, “自然语言处理”, “语言处理”] |
是否包含子词 | ❌ 不包含子词 | ✅ 包含所有子词组合 |
是否适合热词更新 | 适合(粗粒度对词典依赖较低) | 部分适合(细粒度依赖词典完整性) |
6 DSL语言
DSL是Elasticsearch提供的基于JSON的查询语言,用于构建复杂的查询条件。与SQL类似,DSL对ES的意义就像SQL对MySQL一样重要。
# 发送post请求; /_analyze:Elasticsearch的分析API端点,用于测试文本如何被分析
POST /_analyze
{
# 指定使用IK分析器的ik_smart分词模式
"analyzer": "ik_smart",
#要分析的文本内容
"text": "自然语言处理技术"
}
7 通过 kibana 进行测试
8 IK词库
① 定位词库文件
# ik分词器目录中的config目录中的IKAnalyzer.cfg.xml
vim /usr/local/docker/elasticsearch/plugins/elasticsearch-analysis-ik-7.6.1/config/IKAnalyzer.cfg.xml
② 设置拓展词库与停用词库,文件应位于配置文件所在目录。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>IK Analyzer</comment>
// 设置拓展词典
<entry key="ext_dict">ext.dic</entry>
// 设置停用词典
<entry key="ext_stopwords">stopword.dic</entry>
<!-- <entry key="remote_ext_dict">words_location</entry> -->
<!-- <entry key="remote_ext_stopwords">words_location</entry> -->
</properties>
③ 拓展词典ext.dic
vim ext.dic
六月的雪
无情的你
④ 停用词典stopword.dic
vim stopword.dic
a
an
and
are
as
at
be
but
by
for
if
in
into
is
it
no
not
of
on
or
such
that
the
their
then
there
these
they
this
to
was
will
with
的
了
啊
⑤ 重启生效:分词器会在创建倒排索引时;用户搜索时(对输入内容分词)生效。