ElasticSearch整理备忘
整理自 https://github.com/boboweike/elasticsearch_complete_course
ElasticSearch介绍:
分布式的搜索和分析引擎,简称ES (基于Lucene,JAVA开发的)
7.10前开源、7.11后对商业有使用限制
概念:
- 一个ES集群由若干个节点(Node)组成
- ES中的数据存放于节点上
- 数据以文档(Document)形式存放,文档即JSON对象
- ES索引(Index)存放一组相关的文档
1. 索引(Index)
由文档组成,文档为Json对象,对象的每个字段可进行分词
2. 节点(Node)
包括数据节点、协同节点等,也可当成一个ES实例
角色 | 职责 |
---|---|
Master(候选) | 集群管理 |
Data | 文档索引/存储/查询 |
Ingest | 通过pipeline转换数据 |
Coordination | 转发请求到对应节点(缺省角色) |
配置 dim:node.roles: [data, injest, master]
配置coordination: node.roles: []
3. 分片 (Sharding)
-
大索引拆为各个节点上的Sharding
-
类型:Primary Sharding 和 Replication Sharding
-
同一索引的Primary 和 Replication不能在一个Node上, Replication保证了高可用,也可以提升查询性能
-
Sharding本质上是一个Luence实例
-
⼀个Shard最多可存放20亿个⽂档
通过Kibana查看Shard,"?v"表示展示详情
GET /_cat/indices?v
Sharding主要作用:
- 支持数据量的水平扩展
- 将索引分散在各个节点上,并行查询,提高查询性能
Sharding配置:
- ⼀个Index缺省配置⼀个Shard(ES 7.x)
- Shards并⾮越多越好,存储开销/管理复杂性
- 增加或减少Shards
- 增加Shards -> Split API
- 减少Shards -> Shrink API
- 配置多少个Shards合适?
- 视情况定,节点数量,每个节点的容量,索引数量/⼤⼩,查询模式
- 预期⼤索引 -> 适当多分配⼀些Shards(⽐⽅说从5个开始)
- 中⼩索引 -> 从1/2个Shards开始
- Replication副本数量:关键数据 >=2个副本, 非关键业务数据如日志1个副本
- 监控+调整
活跃Index上的Shard数量不能随便修改
原因:由于索引和查询时使用的路由算法依赖于分片数,运行时修改数量会导致路由到错误的分片上。
路由算法: 哪个Primary分片 = hash(document_id)% 总的Primary分片数
shard_number = hash(document_id) % number_of_primary_shards
修改需要:
- 修改Shard数量需要使用re-indexing
- 如果是replication分片数量,运行时可以随意修改(Index settings API)
选择合适的Shard大小
4. 快照
ES文档管理
关于自动创建索引
action.auto_create_index
,缺省为true
PUT /movie/_doc/100
{
"title": "Mission Impossible",
"director": "James Cameron"
}
GET /_cluster/settings
PUT /_cluster/settings
{
"persistent": {
"action.auto_create_index": "false"
}
}
添加/修改
- 添加不带id的文档 ~ POST {index}/_doc
- 添加带id的文档 ~ PUT {index}/_doc/
- 避免文档被覆盖 ~ put {index}/_create/{id}
原理:先根据文档Id路由到对应的分片(Lucene Instance),存到内存buffer中,定时refresh把内存中的数据,以segment(Doc+Inverted Index)的形式存到硬盘
PS: segment是不可变的(immutable),删除只是对之前的数据进行了标记;segment有三个等级,每有3个等级会升级为一个,更有利用查询
更新原理
- 原理:1.获取和id对应的现有文档 -> 2.更新字段 -> 3.替换(replace)现有文档
- 原文档不可变(immutable)
- 对更新的文档进行重新索引
- 将原文档标记为删除
- 可手动实现,但是需要两次API调用
- Update API只需要一次调用,自动在对应的shard上进行操作
refresh
refresh是耗时操作
- 索引级别设置(动态可调)
- 缺省1秒
- 关闭设-1,可手动refresh
设置refresh_interval
:
GET /books/_settings
PUT /books/_settings
{
"index": {
"refresh_interval": "15s"
}
}
- CRUD级别设置(index/delete/update/_bulk)
脚本
脚本类似于数据库的存储过程,一次编译运行后,后续使同一脚本会提高性能
通过脚本更新文档的基本语法
POST /<index>/_update/<id>
{
"script" : {
"source": "...", // 条件/表达式和给文档设置的值
"lang": "painless|expression..", // 表达式语言,缺省是painless
"params": {...} // 为脚本传入动态数据
}
}
e.g.
POST /books/_update/2
{
"script": {
"source": "ctx._source.inStock -= params.quantity",
"params": {
"quantity": 10
}
}
}
批量更新(_update_by_query)
es进行批量更新时,如果中间出现异常,由于索引的不可变,无法进行回滚
这里es是用了乐观锁,也就是不会事先去请求锁,而是基于版本号(Primary Term & Sequence Number),使用快照实现乐观并发控制
POST books/_update_by_query
{
"conflicts": "abort",
"script": {
"source": "ctx._source.inStock += 10",
"lang": "painless"
},
"query": {
"match_all": {}
}
}
实操
使用docker-compose运行多节点(实验性质,生产需配置更多)
version: "3.7"
services:
es01:
image: "docker.elastic.co/elasticsearch/elasticsearch-oss:7.10.2"
container_name: es01
ports:
- "9200:9200"
- "9300:9300"
environment:
node.name: es01
discovery.seed_hosts: es01,es02,es03
cluster.initial_master_nodes: es01,es02,es03
cluster.name: mycluster
ES_JAVA_OPTS: -Xms512m -Xmx512m
volumes:
- "es-data-es01:/usr/share/elasticsearch/data"
ulimits:
memlock:
soft: -1
hard: -1
es02:
image: "docker.elastic.co/elasticsearch/elasticsearch-oss:7.10.2"
container_name: es02
ports:
- "9201:9200"
- "9301:9300"
environment:
node.name: es02
discovery.seed_hosts: es01,es02,es03
cluster.initial_master_nodes: es01,es02,es03
cluster.name: mycluster
ES_JAVA_OPTS: -Xms512m -Xmx512m
volumes:
- "es-data-es02:/usr/share/elasticsearch/data"
ulimits:
memlock:
soft: -1
hard: -1
es03:
image: "docker.elastic.co/elasticsearch/elasticsearch-oss:7.10.2"
container_name: es03
ports:
- "9202:9200"
- "9302:9300"
environment:
node.name: es03
discovery.seed_hosts: es01,es02,es03
cluster.initial_master_nodes: es01,es02,es03
cluster.name: mycluster
ES_JAVA_OPTS: -Xms512m -Xmx512m
volumes:
- "es-data-es03:/usr/share/elasticsearch/data"
ulimits:
memlock:
soft: -1
hard: -1
kibana:
image: docker.elastic.co/kibana/kibana-oss:7.10.2
container_name: kibana
depends_on:
- es01
- es02
- es03
ports:
- "5601:5601"
- "9600:9600"
environment:
SERVERNAME: kibana
ELASTICSEARCH_HOSTS: '["http://es01:9200","http://es02:9200","http://es03:9200"]'
ES_JAVA_OPTS: -Xmx512m -Xms512m
volumes:
es-data-es01: {}
es-data-es02: {}
es-data-es03: {}
查看ES集群状态
ES
暴露HTTP RESTful API,可以通过常用工具进行访问:
- Kibana Dev Console
- Postman
- cURL
Kibana Dev Console:
- 最简单的访问ES API的方法
- 对查询结果进行格式化展示
- 自动设置必要的HTTP headers(Content-Type etc)
- 请求自动提示/补全
- 本课主要使用该工具
使用Kibana Dev Console查询集群状态
- 查询集群健康状态
GET /_cluster/health
_cluster
表示APIhealth
表示命令- red :部分Primary Sharding还未分配到节点
- yellow :Primary Sharding全部就绪,部分Replication Sharding还未分配到节点
- green :所有Sharding就绪
- 查询节点状态
GET /_cat/nodes?v
cat
表示Compact and aligned text
node.role=dimr表示 角色包括[data, injest, master]还有一个 remote_cluster_client
- 查看索引情况
GET /_cat/indices?v
使用cUrl查询集群状态
curl -X GET http://localhost:9200
curl -X GET http://localhost:9200/_cluster/health
npm install -g json
curl -X GET http://localhost:9200/_cluster/health | json
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 推荐几款开源且免费的 .NET MAUI 组件库
· 实操Deepseek接入个人知识库
· 易语言 —— 开山篇
· 【全网最全教程】使用最强DeepSeekR1+联网的火山引擎,没有生成长度限制,DeepSeek本体