☰
Elasticsearch:原理、Docker 安装与常用命令
2026/10/11 1:54:24 网站建设 项目流程

假设你做了一个博客网站,里面有十万篇文章。读者输入“Docker 安装”,希望找到标题或正文中相关的内容,还想按分类筛选、按发布时间排序。

这时,搜索功能需要做的事情就比“查找某个字段等于某个值”多了:理解关键词、找到相关文章、决定谁排在前面,再把结果分页返回。Elasticsearch 就是常用于处理这类需求的工具。当然,在企业级项目中也会常常将ES作为日志系统搭建的中间件。

一、Elasticsearch 到底是什么

Elasticsearch,通常简称 ES,是基于 Apache Lucene 的搜索与分析引擎。Lucene 提供底层检索能力,Elasticsearch 将这些能力封装成 HTTP 接口,并支持多台机器协同处理数据。常见用途包括文章搜索、商品搜索和日志查询。它也能做统计,例如“每个分类有多少篇文章”“某个时间段出现了多少次错误”。

它与 MySQL 的侧重点不同。MySQL 常用于保存订单、账户等业务数据,处理事务和关系查询;Elasticsearch 常用于全文检索、相关性排序和搜索分析。数据库本身也有全文检索能力,是否需要引入 ES,要看实际需求和维护成本。

一般常见的做法:业务数据仍存放在 MySQL,将需要搜索的字段同步到 ES。搜索请求查询 ES,交易操作继续由业务数据库处理。这样会增加数据同步工作,还要考虑同步失败和延迟,不能期待两边天然一致。

先理解几个概念

概念含义
文档(Document)一条 JSON 数据
索引(Index)一组文档及其配置
Mapping字段类型和索引方式的定义
主分片(Primary shard)索引数据的一部分,每个分片是一个 Lucene 索引
副本分片(Replica shard)主分片的副本
节点(Node)一个 Elasticsearch 实例
集群(Cluster)协同工作的多个节点,也可以只有一个节点

二、它为什么可以快速找到你想要的内容

1、倒排索引:从“词”找到“文章”

假设有三篇文章,标题分别是:

文档 ID标题
1Docker 安装教程
2Elasticsearch 安装教程
3Docker 网络排查

按“文章 → 标题”保存内容,很容易回答“第 1 篇文章叫什么”。但读者搜索“Docker”时,需要反过来回答:“哪些文章包含这个词?”。为此,可以提前整理一份查找表:

词包含它的文档 ID
docker1、3
elasticsearch2
安装1、2
教程1、2
网络3
排查3

这就是倒排索引的基本思路:记录一个词出现在哪些文档中。搜索 Docker 时,就能先找到文档 1 和 3,不必每次逐篇扫描全文。搜索“Docker 安装”时,如果要求两个词都出现,就取两个列表的交集,得到文档 1;如果允许任意一个词出现,就会有更多候选结果,再根据相关性排序。

2、分词:先把句子变成可搜索的词

建立倒排索引前,ES 要先处理文本,这个过程叫分析,通常包含分词、大小写转换等步骤。负责这些工作的配置叫分析器(Analyzer)。例如,标准分析器会把Docker Install Guide处理成docker、install、guide这样的词。后面安装好环境,可以亲自查看:

POST /_analyze
{
"analyzer": "standard",
"text": "Docker Install Guide"
}

//响应结果

{
"tokens": [{
"token": "docker",
"start_offset": 0,
"end_offset": 6,
"type": "<ALPHANUM>",
"position": 0
},
{
"token": "install",
"start_offset": 7,
"end_offset": 14,
"type": "<ALPHANUM>",
"position": 1
},
{
"token": "guide",
"start_offset": 15,
"end_offset": 20,
"type": "<ALPHANUM>",
"position": 2
}
]
}

3、分片与副本:数据多了,怎么分给多台机器

一个 Elasticsearch 实例叫一个节点(Node),多个节点可以组成集群(Cluster)。当索引很大时,可以把它分成几份,每一份叫分片(Shard)。例如把文章索引划成 3 个主分片,各自存放一部分文档;ES 通过路由决定一条文档属于哪个主分片。副本是主分片的复制件。3 个主分片,每个配置 1 个副本,就一共有 6 个分片副本实例,占用的存储和资源也会相应增加。

主分片与它自己的副本不能放在同一个节点上。这样一个节点故障时,集群可以利用其他节点上的有效副本恢复服务;

4、一次写入和搜索,大致经历什么

写入时,接收请求的节点找到目标主分片,由主分片处理写入,再复制到同步副本。正常情况下,相关同步副本处理完成后,才完成写入确认。

搜索时,接收请求的节点负责协调,将查询交给相关分片的某个可用副本执行,再合并结果、获取需要的文档,返回给客户端。搜索不需要把同一份数据的主分片和全部副本都查一遍。

因此,副本既能帮助应对故障,也可以分担搜索流量,但会增加存储和写入复制成本。(其实在一定程度上有点类似于MYSQL主从结构,主库写入完成同步到从库,后续读取也可以从从库进行数据读取)

三、用 Docker 启动单节点环境

1、准备运行环境

先安装适合操作系统的 Docker Engine 或 Docker Desktop,确认命令可用:

docker version

2、 创建网络和持久化卷

以下命令在 Bash 或 Zsh 中执行。先创建一个工作目录,再准备专用网络与数据卷:

mkdir -p elasticsearch-lab cd elasticsearch-lab export STACK_VERSION=8.18.6 docker network create es-lab-net docker volume create es-lab-data docker volume create es-lab-config docker pull docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION}

两个卷分别保存索引数据,以及节点配置与证书。这里的配置卷属于当前节点,不要让多个节点共享同一个配置卷。

3、启动 Elasticsearch

docker run -dit \ --name es-lab \ --hostname es-lab \ --network es-lab-net \ --restart unless-stopped \ --memory 2g \ --ulimit nofile=65535:65535 \ --log-driver json-file \ --log-opt max-size=20m \ --log-opt max-file=5 \ -p 127.0.0.1:9200:9200 \ -e discovery.type=single-node \ -v es-lab-data:/usr/share/elasticsearch/data \ -v es-lab-config:/usr/share/elasticsearch/config \ docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION}

这段配置中,有几个地方值得理解:

  • discovery.type=single-node用于单节点实验环境;组建多节点集群时需要重新规划发现与安全配置。
  • 127.0.0.1:9200:9200只把 REST API 发布到宿主机回环地址。节点间通信使用的9300端口不需要在本示例中发布。
  • 数据卷让数据独立于容器生命周期。配置卷保留首次启动生成的证书、密钥库和配置;空命名卷首次挂载时会由 Docker 填充镜像中对应目录的内容。

4、验证是否启动成功

打开浏览器,访问9200地址:http://127.0.0.1:9200/,如果可以正常访问,则表示启动成功。

四、常用命令:模拟一个小例子

为了方便ES的可视化管理,建议开发测试可以使用轻量级的Elasticvue工具,如果是正式环境可以使用功能强大的Kibana工具:https://www.elastic.co/cn/kibana/https://www.elastic.co/cn/kibana/

1、创建索引

控制台请求由“方法、路径、请求体”组成。例如PUT /articles-v1表示向该路径发送 PUT 请求,后面的 JSON 描述索引配置。命令中的/是接口路径,不是本地文件目录。

PUT /articles-v1 //请求参数 { "settings": { "number_of_shards": 1, "number_of_replicas": 0 }, "mappings": { "properties": { "title": { "type": "text" }, "category": { "type": "keyword" }, "published_at": { "type": "date" }, "views": { "type": "long" } } } } //响应参数 { "acknowledged": true, "shards_acknowledged": true, "index": "articles-v1" }

这个索引用一个主分片、零副本,适合单节点学习。生产环境应按可用性要求配置副本,并提供能够承载副本的其他节点。提前定义 Mapping,可以避免日期、数字被错误识别成字符串。查看配置:

GET /articles-v1/_mapping

GET /articles-v1/_settings

2、写入文档:给文章一个 ID

PUT /articles-v1/_doc/1?refresh=wait_for //请求参数 { "title": "Docker 安装教程", "category": "运维", "published_at": "2026-10-01T10:00:00+08:00", "views": 120 } //响应参数 { "_index": "articles-v1", "_id": "1", "_version": 1, "result": "created", "_shards": { "total": 1, "successful": 1, "failed": 0 }, "_seq_no": 0, "_primary_term": 1 }
  • _id:文档ID,向同一索引、同一 ID 再次执行这个 PUT,会替换该文档,而不是新增第二条。
  • 如果只允许新建、不允许覆盖,使用PUT /articles-v1/_create/1;ID 已存在时会返回冲突。让 ES 自动生成 ID,则使用POST /articles-v1/_doc。
  • refresh=wait_for用于方便后续搜索验证

3、根据 ID 读取文章

GET /articles-v1/_doc/1 //响应参数 { "_index": "articles-v1", "_id": "1", "_version": 3, "_seq_no": 2, "_primary_term": 1, "found": true, "_source": { "title": "Docker 安装教程", "category": "运维", "published_at": "2026-10-01T10:00:00+08:00", "views": 120 } }

响应中的_source包含原始业务字段,found表示是否找到文档。

4、批量写入:一次添加多篇文章

POST /articles-v1/_bulk?refresh=wait_for {"index":{"_id":"2"}} {"title":"Elasticsearch 安装教程","category":"搜索","published_at":"2026-10-02T10:00:00+08:00","views":80} {"index":{"_id":"3"}} {"title":"Docker 网络排查","category":"运维","published_at":"2026-10-03T10:00:00+08:00","views":200}

Bulk 使用 NDJSON,即一行一个 JSON。上例每两行是一组:第一行说明操作和 ID,第二行提供文档。通过 curl 或程序发送时,请求体最后也要以换行符结束,内容类型使用application/x-ndjson。

5、全文搜索:找标题包含 Docker 的文章

POST /articles-v1/_search //请求参数 { "query": { "match": { "title": "Docker" } } } //响应参数 { "took": 29, "timed_out": false, "_shards": { "total": 1, "successful": 1, "skipped": 0, "failed": 0 }, "hits": { "total": { "value": 2, "relation": "eq" }, "max_score": 0.4700036, "hits": [ { "_index": "articles-v1", "_id": "1", "_score": 0.4700036, "_source": { "title": "Docker 安装教程", "category": "运维", "published_at": "2026-10-01T10:00:00+08:00", "views": 120 } }, { "_index": "articles-v1", "_id": "3", "_score": 0.4700036, "_source": { "title": "Docker 网络排查", "category": "运维", "published_at": "2026-10-03T10:00:00+08:00", "views": 200 } } ] } }

match会分析搜索文本,再查找匹配的文档。在当前样例中,应匹配文章 1 和 3。返回结果主要看三处:

字段作用
hits.total匹配总数及其计数关系;大结果集可能只是下界
hits.hits当前返回的文档列表
_score相关性分数;默认搜索通常按分数从高到低返回

6、精确筛选:只看运维类文章

POST /articles-v1/_search { "query": { "bool": { "filter": [ { "term": { "category": "运维" } } ] } } }

term匹配字段索引中的精确词项,适合这里的keyword分类字段。filter用于判断“是否满足条件”,不计算相关性得分。

7、排序与分页:按浏览量取前两篇

POST /articles-v1/_search { "query": { "match_all": {} }, "sort": [ { "views": "desc" } ], "from": 0, "size": 2, "_source": ["title", "views"] }

from 是跳过多少条,size 是本次取多少条,_source 限定返回哪些业务字段。第二页可以把 from 改为 2。

8、修改文档:只更新浏览量

POST /articles-v1/_update/1?refresh=wait_for { "doc": { "views": 180 } }

这会把浏览量设置为 180,其他字段保留。它与前面的PUT /_doc/1全量替换不同。

9、 删除数据:分清文档和索引

删除一条ID为3的文档:

DELETE /articles-v1/_doc/3?refresh=wait_for

删除索引(索引下的所有文档都会被删除):

DELETE /articles-v1

五、常用命令速查

目的命令
查看版本与基本信息GET /
检查分词结果POST /_analyze,附分析器和文本
创建索引PUT /articles-v1,附 settings 与 mappings
查看字段类型GET /articles-v1/_mapping
写入或替换文档PUT /articles-v1/_doc/1,附完整文档
只允许新建PUT /articles-v1/_create/1,附文档
按 ID 查询GET /articles-v1/_doc/1
搜索POST /articles-v1/_search,附查询条件
统计文档数量GET /articles-v1/_count
局部更新POST /articles-v1/_update/1,附 doc 或 script
批量操作POST /articles-v1/_bulk,附 NDJSON
删除一条文档DELETE /articles-v1/_doc/1
删除整个索引DELETE /articles-v1
查看集群健康GET /_cluster/health

六、小结

以上是本次对于Elasticsearch原理、Docker 安装与常用命令的一个介绍和使用,欢迎各位同学交流学习!

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询