ES操作手册
一、ES配置项作用解析
1. 集群连接核心配置
-
es.hostlist
:定义ES集群的节点列表(domain:9200
等3个节点)。
作用:客户端通过这些节点连接集群,ES会自动发现集群拓扑,实现负载均衡(查询请求分散到不同节点)和故障转移(某节点宕机时自动切换到其他节点)。9200
是ES默认的HTTP通信端口。 -
es.httpType=http
:指定连接协议为HTTP
(未加密)。
若集群启用SSL/TLS加密,需改为https
,并可能需要额外配置证书(如ssl.certificate
等)。 -
es.username=elastic
和es.password=passwordXXXX
:
作用:ES的认证凭证。elastic
是内置超级管理员用户,通过HTTP Basic认证访问集群(需集群开启安全模块,如X-Pack Security)。生产环境建议创建权限更精细的专用用户(避免直接使用elastic
)。
2. 索引创建配置(es.settings.as
)
{"number_of_replicas":0, "number_of_shards":1}
-
number_of_shards:1
:每个索引的主分片数量为1。
主分片是数据存储的基本单元,决定索引的“水平扩展能力”(分片越多,可分散到更多节点存储)。此配置适合数据量较小的场景(单节点可承载)。 -
number_of_replicas:0
:主分片的副本分片数量为0。
副本分片是主分片的冗余备份,作用是:① 故障恢复(主分片所在节点宕机时,副本可升级为主分片);② 分担查询压力。
风险:副本数为0时,若主分片所在节点故障,数据可能永久丢失(生产环境建议至少设置1个副本:number_of_replicas:1
)。
3. 索引映射配置(es.mappings.as
)
映射定义字段的类型、分词规则及功能(如是否支持聚合),核心字段解析:
{"properties": {"fs_ocode": { "type":"text", "fields":{"keyword":{"type":"keyword"}}, "fielddata":"true" },"fs_atext": { "fielddata":"true", "analyzer":"ik_max_word", "type":"text" },"fs_ctext": { "fielddata":"true", "analyzer":"ik_max_word", "type":"text" },"fs_agentno": { "type":"keyword" },"fs_extracttag": { "type":"keyword" },"fs_bcode": { "type":"keyword" },"fdt_cdate": { "type":"text", "fields":{"keyword":{"type":"keyword"}}, "fielddata":"true" },"fdt_starttime": { "type":"keyword" },"fdt_endtime": { "type":"keyword" },"fdt_full_cdate": { "type":"keyword" }}
}
-
text
类型(如fs_ocode
、fs_atext
):
用于全文检索,会被分词器处理。例如fs_atext
和fs_ctext
指定analyzer: "ik_max_word"
(IK分词器的“最细粒度分词”),支持中文文本拆分(如“客服服务”拆分为“客服、服务、客、服”等),适合中文搜索。 -
keyword
子字段(如fs_ocode.keyword
):
text
字段默认不支持精确匹配、聚合或排序,通过fields.keyword
定义keyword
类型子字段,用于:① 精确匹配(如term
查询);② 聚合(如统计不同fs_ocode
的数量);③ 排序。 -
keyword
类型(如fs_agentno
、fs_bcode
):
字段值不分词,直接作为整体存储,适合:① 唯一标识(如座席工号fs_agentno
);② 枚举值(如业务编码fs_bcode
);③ 时间字符串(如fdt_starttime
),支持精确匹配和聚合。 -
fielddata:true
:
text
字段默认关闭fielddata
(避免占用内存),开启后允许对text
字段进行聚合/排序。但fielddata
会加载字段值到内存并构建缓存,风险:高频更新或大容量字段可能导致内存溢出。建议优先使用keyword
子字段(如用fs_ocode.keyword
聚合,而非fs_ocode
)。
4. 查询限制(es.limit.as=5000
)
作用:单次查询默认最大返回5000条文档,避免大量数据导致客户端内存溢出。如需更多数据,可通过分页(from
+size
)或滚动查询(scroll
)实现。
二、连接ES集群(基于配置)
需使用集群节点、协议、认证信息,以下是常用工具/语言的连接方式:
1. 命令行(curl)连接
# 测试集群健康状态(返回"status":"green"表示正常)
curl -u elastic:passwordXXXX "http://domain:9200/_cluster/health"
-u
:指定用户名和密码(elastic:密码
);- 连接任一节点即可(ES客户端会自动发现其他节点)。
- 地址格式:
http://{host}:{port}
(对应es.httpType
和es.hostlist
)。
2. Python(elasticsearch
库)连接
from elasticsearch import Elasticsearch# 初始化客户端(自动负载均衡)
es = Elasticsearch(hosts=["http://domain:9200","http://nlpaicc-2-prd-es.bdp.sfcloud.local:9200","http://nlpaicc-3-prd-es.bdp.sfcloud.local:9200"],basic_auth=("elastic", "passwordXXXX"), # 认证timeout=30 # 超时时间(秒)
)# 测试连接(返回True表示成功)
print(es.ping())
3. Java(High Level REST Client)连接
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.RestClientBuilder.HttpHost;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;// 配置认证
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY,new UsernamePasswordCredentials("elastic", "passwordXXXX")
);// 构建客户端
RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("domain", 9200, "http"),new HttpHost("nlpaicc-2-prd-es.bdp.sfcloud.local", 9200, "http"),new HttpHost("nlpaicc-3-prd-es.bdp.sfcloud.local", 9200, "http")).setHttpClientConfigCallback(httpClientBuilder -> httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider))
);// 测试连接(无异常则成功)
client.info();
三、查询操作示例(基于映射)
假设目标索引为biz_index
,以下是典型查询场景:
1. 精确匹配(keyword
字段)
查询fs_bcode
为“000010”的文档:
# curl命令
curl -u elastic:passwordXXXX "http://domain:9200/biz_index/_search" -H "Content-Type: application/json" -d '
{"query": { "term": { "fs_bcode": "000010" } }, # term查询keyword字段(精确匹配)"size": 10 # 返回10条结果
}'
2. 中文全文检索(text
字段+IK分词)
查询fs_atext
中包含“客服”的文档:
# Python代码
response = es.search(index="biz_index",body={"query": { "match": { "fs_atext": "客服" } } # match查询text字段(全文检索)}
)# 打印结果
for hit in response["hits"]["hits"]:print(hit["_source"]) # 文档原始数据
3. 聚合统计(keyword
字段)
统计不同座席工号(fs_agentno
)的文档数量:
response = es.search(index="biz_index",body={"size": 0, # 不返回文档,只返回聚合结果"aggs": {"agent_stats": { "terms": { "field": "fs_agentno" } } # 聚合keyword字段}}
)# 打印聚合结果
print(response["aggregations"]["agent_stats"]["buckets"])
四、删除索引操作(谨慎执行)
删除索引会永久删除数据,步骤如下:
1. 命令行(curl)删除
# 1. 确认索引存在
curl -u elastic:passwordXXXX "http://domain:9200/biz_index"# 2. 确认后删除(替换为目标索引名)
curl -u elastic:passwordXXXX -X DELETE "http://domain:9200/biz_index"
2. Python删除索引
# 检查索引是否存在
if es.indices.exists(index="biz_index"):es.indices.delete(index="biz_index") # 删除索引print("索引删除成功")
else:print("索引不存在")
五、空索引风险分析
空索引的核心风险点:
- 元数据冗余:ES集群的master节点需要维护所有索引的元数据(映射、分片配置等),空索引会无意义地消耗元数据资源,尤其当空索引数量增多时,可能降低集群状态更新效率。
- 资源浪费:即使无数据,空索引仍会占用固定的分片资源(默认1主分片),若分片分配到数据节点,会占用节点的内存和文件描述符。
- 隐藏业务问题:空索引可能是“数据未正确写入”的信号(如程序bug、权限问题、索引名称配置错误等),若未及时处理,可能导致业务数据丢失或功能异常。
1. 核实空索引状态(确认是否真的为空及属性)
通过ES API查询索引的文档数量、创建时间、映射配置等,判断是否为“真·空索引”及是否有保留价值:
- 查看文档数:
GET /{index}/_count
(结果count:0
则为空) - 查看索引信息:
GET /{index}
(含创建时间、分片数、映射等) - 查看历史数据痕迹:
GET /{index}/_stats
(确认是否曾经有数据,因删除变为空)
2. 分类处理空索引
根据索引用途和业务确认结果,分三类处理:
(1)废弃索引(确认不再使用)
- 典型场景:测试残留(如
000003
、000007
这类数字索引)、业务下线后未清理的索引。 - 处理方式:安全删除,释放资源。
- 操作前备份映射(如需留存配置):
GET /{index}/_mapping
→ 保存结果。 - 删除命令:
DELETE /{index}
(生产环境建议先关闭索引POST /{index}/_close
,观察1-2天无影响后再删除)。
- 操作前备份映射(如需留存配置):
(2)临时空索引(计划使用但暂未写入数据)
- 典型场景:新业务准备上线的索引(如
kg_ft_company_reg_info~xianggang
、~aomen
、~taiwan
可能是按地区划分的公司注册信息索引,暂未同步数据)。 - 处理方式:标记管理+监控,避免长期空转。
- 标记索引:通过别名或索引元数据添加备注(如
PUT /{index}/_settings {"metadata": {"description": "待同步香港公司数据,预计2025-09月启用"}}
)。 - 定期监控:设置定时任务(如每周)检查是否有数据写入,若超过预期时间仍为空,触发告警排查原因。
- 标记索引:通过别名或索引元数据添加备注(如
(3)异常空索引(应写入数据但未成功)
- 典型场景:
sq_text_embedding_index
(文本嵌入索引,可能因数据处理程序故障未生成数据)、地区索引(如~xianggang
)因同步脚本错误导致数据未写入。 - 处理方式:排查写入链路,修复数据同步。
- 检查应用日志:查看数据写入ES的客户端日志(如Java/Python客户端),确认是否有连接失败、权限不足、索引名称写错(如大小写、特殊字符)等错误。
- 验证索引配置:确认索引映射是否与写入数据结构匹配(如字段类型不兼容会导致写入失败),可通过
GET /{index}/_mapping
对比写入数据格式。 - 测试写入:手动插入一条测试数据(如
POST /{index}/_doc { "test": "data" }
),验证是否成功,定位是否为索引本身的问题。
3. 建立预防机制(避免未来空索引泛滥)
- 规范索引创建流程:要求创建索引时必须注明用途、生命周期、负责人,禁止随意创建测试索引。
- 索引生命周期管理(ILM):为业务索引配置ILM策略,自动清理长期为空的索引(如“30天无数据则自动删除”)。
- 示例策略:
关联索引:PUT _ilm/policy/empty_index_cleanup {"policy": {"phases": {"hot": {"actions": {}},"delete": {"min_age": "30d","actions": {"delete": {}}}}} }
PUT /{index}/_settings {"index.lifecycle.name": "empty_index_cleanup"}
- 示例策略:
- 定期巡检:每周通过脚本(如Python调用ES API)扫描集群所有索引,筛选出空索引并通知负责人确认,形成闭环管理。