当今最流行的日志分析平台 ELK Stack 的核心引擎,PB级数据毫秒级返回的秘密,尽在此文。
想象一下,你在淘宝搜索"苹果手机",0.3秒内几百万条商品数据被精准筛选、按相关性排序呈现在你面前。这背后的"魔法引擎",就是 Elasticsearch(简称 ES)。
当传统数据库面对海量非结构化文本时,LIKE %keyword% 早已力不从心。Elasticsearch——这颗诞生于2010年的搜索心脏,基于 Apache Lucene 打造,以分布式、近实时、RESTful的姿态,重新定义了"搜索"二字。
一句话总结:ES = Lucene(内核)+ 分布式架构(扩展)+ RESTful API(易用),一切数据皆 JSON,一切字段皆可搜。
⚠️ 重要变更:自2021年1月起,Elasticsearch 已从 Apache 2.0 开源协议迁移至 SSPL 专有双许可,AWS 随即分叉出 OpenSearch 继续保持 Apache 2.0 开源。但 ES 7.x 依然是业界的主流选择。
学 ES,先搞懂这张概念映射表,它是你理解一切的基石:
关系型数据库 | Elasticsearch 7.x | 说明 |
|---|---|---|
数据库(Database) | 索引(Index) | 数据的逻辑容器 |
表(Table) | 类型(Type) | ⚠️ 7.x 已彻底删除! |
行(Row) | 文档(Document) | 一条 JSON 数据 |
列(Column) | 字段(Field) | 文档的属性 |
表分区 | 分片(Shard) | ES 扩展性之源 🔑 |
传统数据库以 id 为主键,是 key → value 的查找模式。而 ES 颠覆了这一逻辑:
传统 DB | Elasticsearch |
|---|---|
id = 1 → "Java编程思想" | "Java" → [id: 1, id: 3] |
按 ID 查找内容 | 按内容匹配文档 |
所有不重复的词条构成索引,每个词条下挂着包含它的文档列表。搜索时,直接定位词项,瞬间返回匹配文档——这就是 ES 能在 PB 级数据中毫秒级返回结果的根本原因。
7.0 引入了"搜索空闲"机制:当一个分片 30秒内没有搜索请求时,自动进入 Search Idle 状态,跳过所有计划内的 refresh,直到下一次搜索到来才触发刷新。
💡 这意味着:对于读多写少的场景,索引吞吐量可大幅提升!
⚠️ 注意:此行为仅在未显式设置
refresh_interval时生效。
对于匹配少量文档的查询,7.x 引入了 Magic Wand 算法,通过跳过低排名记录来加速 Top Hits 的检索。这是一项基于算法层面的重大优化(注意:不适用于聚合查询)。
Cross-Cluster Replication 让数据在不同集群间实时同步,对于灾备和多活架构是巨大的利好。
别被安装劝退,ES 天生就是"开箱即用"的。
bashdocker pull elasticsearch:7.6.1bashdocker run --name elasticsearch \
-p 9200:9200 -p 9300:9300 \
-e "discovery.type=single-node" \
-e ES_JAVA_OPTS="-Xms256m -Xmx256m" \
-d elasticsearch:7.6.1浏览器访问 http://你的IP:9200,看到 JSON 响应即表示成功。
bashdocker exec -it elasticsearch /bin/bash
cd /usr/share/elasticsearch/config
vim elasticsearch.yml末尾追加:
yamlhttp.cors.enabled: true
http.cors.allow-origin: "*"保存退出,重启容器:docker restart elasticsearch
bashdocker pull kibana:7.6.1
docker run --name kibana --link=elasticsearch:test -p 5601:5601 -d kibana:7.6.1⚠️ Kibana 版本必须与 Elasticsearch 版本一致! 访问
http://你的IP:5601即可进入可视化界面。
ES 的 API 简洁优雅,核心就三个动作:
操作 | API | 说明 |
|---|---|---|
索引文档 | POST /<index>/_doc | 新增或覆盖 |
获取文档 | GET /<index>/_doc/<id> | 精确查询 |
删除文档 | DELETE /<index>/_doc/<id> | 删除 |
搜索 | GET /<index>/_search | 全文检索 |
索引信息 | GET /<index> | 文档数、分片数等 |
实战示例:
bash# 插入文档
curl -X POST "localhost:9200/products/_doc/1" \
-H 'Content-Type: application/json' \
-d'{
"name": "Elasticsearch实战指南",
"price": 89,
"tags": ["搜索", "大数据", "nosql"]
}'
# 搜索
curl -X GET "localhost:9200/products/_search?pretty" \
-H 'Content-Type: application/json' \
-d'{
"query": {
"match": { "name": "搜索" }
}
}'Bool Query 是 ES 中最强大的查询组合方式:
子句 | 作用 | 是否评分 |
|---|---|---|
must | 必须匹配(AND) | ✅ 是 |
should | 应该匹配(OR) | ✅ 是 |
must_not | 必须不匹配(NOT) | ❌ 否 |
filter | 过滤条件 | ❌ 否(可缓存!) |
json{
"query": {
"bool": {
"must": [
{ "match": { "title": "elasticsearch" } }
],
"filter": [
{ "range": { "price": { "gte": 50 } } }
],
"must_not": [
{ "term": { "status": "deleted" } }
]
}
}
}💡 性能秘诀:能用 filter 就别用 must,因为 filter 不计算评分且可被缓存,速度提升显著。
创建索引时,Mapping 决定了你的数据如何被存储和搜索。
类型 | 说明 | 场景 |
|---|---|---|
text | 默认分词,支持模糊查询 | 全文搜索 |
keyword | 不分词,精确匹配 | 过滤、聚合、排序 |
number(long/integer/double...) | 数值类型 | 价格、数量、评分 |
date | 日期类型,支持毫秒 | 时间范围查询 |
boolean | true/false | 状态标记 |
geo_point | 经纬度 | 地图搜索、距离计算 |
array | 数组(不需显式声明) | 标签列表 |
nested | 嵌套对象,可检索子项 | 复杂对象数组 |
Mapping 实战示例:
jsonPUT /products
{
"settings": {
"number_of_shards": 2,
"number_of_replicas": 1
},
"mappings": {
"properties": {
"name": { "type": "text" },
"price": { "type": "long" },
"tags": { "type": "keyword" },
"created_at": { "type": "date" }
}
}
}9200 端口暴露在公网,一旦被扫到,集群及数据会受到灾难式影响。安全无小事!
第一步:启用安全功能(elasticsearch.yml)
yamlxpack.security.enabled: true第二步:生成 TLS 证书
bashbin/elasticsearch-certutil cert第三步:配置加密通信(elasticsearch.yml)
yamlxpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.verification_mode: certificate
xpack.security.transport.ssl.keystore.path: elastic-certificates.p12第四步:设置密码
bashbin/elasticsearch-setup-passwords auto自此,单节点安全配置完毕,访问 9200 会出现用户名和密码的提示窗口。
⚠️ 官方明确指出:你不能仅通过获取集群所有节点的数据目录副本来备份 Elasticsearch 集群。直接拷贝文件会导致失败或数据丢失!备份集群的唯一可靠方法是使用快照和还原功能。
Step 1:注册快照存储库
bashPUT /_snapshot/my_backup
{
"type": "fs",
"settings": {
"location": "/path/to/backup"
}
}Step 2:拍摄快照
bash# 全量备份
PUT /_snapshot/my_backup/snapshot_cluster?wait_for_completion=true
# 索引快照
PUT /_snapshot/my_backup/snapshot_products?wait_for_completion=true
{
"indices": "products_*",
"ignore_unavailable": true,
"include_global_state": false
}Step 3:恢复快照
bashPOST /_snapshot/my_backup/snapshot_cluster/_restore💡 快照是增量创建的,可以非常频繁地为集群创建快照,支持本地文件存储及 S3、HDFS、Azure 等远程存储。
引入依赖:
xml<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.4.2</version>
</dependency>配置类:
java@Configuration
public class ElasticSearchConfig {
@Bean
public RestHighLevelClient restHighLevelClient() {
return new RestHighLevelClient(
RestClient.builder(
new HttpHost("127.0.0.1", 9200, "http")
)
);
}
}⚠️ 坑:不同版本的 ES API 不一致,7.x 已经移除了 Type,URL 格式从
/index/type/id变为/index/_doc/id,切勿写错!
命令 | 说明 |
|---|---|
GET /_cat/indices | 查看所有索引信息 |
GET /<index> | 查看某个索引信息 |
PUT /<index> | 创建索引(可指定分片数) |
POST /<index>/_doc | 插入文档(自动生成ID) |
PUT /<index>/_doc/<id> | 插入/更新文档(指定ID) |
DELETE /<index>/_doc/<id> | 删除文档 |
POST /_bulk | 批量操作 |
GET /_snapshot/_all | 查看所有快照 |
Elasticsearch 7.x 的分布式架构,本质上是一场关于一致性、可用性与分区容错性的精密博弈。从倒排索引的魔法到 Search Idle 的吞吐量飞跃,从 X-Pack 的安全护航到快照机制的数据保险,ES 以其卓越的架构设计照亮了企业级搜索与分析的征途。
理解其内核,方能在实战中游刃有余。现在,拉起你的 Docker 容器,开始你的 ES 之旅吧!
标签:Elasticsearch 搜索引擎 ELK Stack 分布式 NoSQL 全文检索 Docker Spring Boot
专栏:玩转搜索框架 Elasticsearch 7.x 实战
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。