Elasticsearch:原理、Docker 安装与常用命令

假设你做了一个博客网站,里面有十万篇文章。读者输入"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 标题
1 Docker 安装教程
2 Elasticsearch 安装教程
3 Docker 网络排查

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

词 包含它的文档 ID
docker 1、3
elasticsearch 2
安装 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,确认命令可用:

bash 复制代码
docker version

2、 创建网络和持久化卷

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

bash 复制代码
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

bash 复制代码
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 描述索引配置。命令中的 / 是接口路径,不是本地文件目录。

bash 复制代码
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

bash 复制代码
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 读取文章

bash 复制代码
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、批量写入:一次添加多篇文章

bash 复制代码
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 的文章

bash 复制代码
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、精确筛选:只看运维类文章

bash 复制代码
POST /articles-v1/_search
{
  "query": {
    "bool": {
      "filter": [
        { "term": { "category": "运维" } }
      ]
    }
  }
}

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

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

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

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

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

bash 复制代码
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 安装与常用命令的一个介绍和使用,欢迎各位同学交流学习!

相关推荐
starzy19901 小时前
Flink 注册Slot源码深度剖析:从TaskManager注册到Slot状态机的完整链路
大数据·flink
刚入门的大一新生1 小时前
Linux-Ext系列文件系统
linux·运维·服务器
出海客2 小时前
跨境客服工单如何跨时区交接:队列分流、SLA计时与异常兜底
大数据
小小AK2 小时前
采购订单同步策略实战:金蝶云星空到旺店通的字段映射与调度设计
大数据·数据库
灯澜忆梦2 小时前
【docker】#4 | Docker 自定义镜像与 Dockerfile
运维·docker·容器
众壹能源科技2 小时前
边缘设备 OTA 为什么要采用灰度发布
大数据
SKH.2 小时前
Linux驱动-led、beep
linux·运维·单片机
JingliAlex2 小时前
企业微信自动回复的话术怎么过审?三级审核流程的搭法
大数据·html·企业微信
CCblandy2 小时前
Airllm 大模型本地化部署与高效推理应用指南
大数据·网络·人工智能