Appearance
性能优化
写入优化
1. 批量写入
json
POST /products/_bulk
{"index": {"_id": "1"}}
{"name": "iPhone", "price": 999}
{"index": {"_id": "2"}}
{"name": "MacBook", "price": 1999}python
# Python批量写入
from elasticsearch import Elasticsearch
es = Elasticsearch()
actions = []
for doc in docs:
actions.append({"index": {"_index": "products", "_id": doc["id"]}})
actions.append(doc)
es.bulk(body=actions, requests_per_second=None)2. 调整refresh_interval
json
PUT /products/_settings
{
"refresh_interval": "30s" # 写入期间关闭,完成后恢复
}
# 写完后恢复
PUT /products/_settings
{
"refresh_interval": "1s"
}3. 调整translog
json
PUT /my_index/_settings
{
"index": {
"translog": {
"sync_interval": "30s",
"durability": "async"
}
}
}4. 禁用副本(批量写入期间)
json
PUT /my_index/_settings
{
"number_of_replicas": 0
}
# 完成后恢复
PUT /my_index/_settings
{
"number_of_replicas": 1
}5. 文档ID优化
json
// 使用自定义ID,避免自动生成
POST /products/_doc/1 # 指定ID,减少写放大
// 合理使用routing
POST /products/_doc?routing=user_id查询优化
1. 用filter替代bool must
json
// ❌ 不推荐
{
"query": {
"bool": {
"must": [
{"term": {"status": "active"}},
{"range": {"price": {"gte": 100}}}
]
}
}
}
// ✅ 推荐
{
"query": {
"bool": {
"filter": [
{"term": {"status": "active"}},
{"range": {"price": {"gte": 100}}}
]
}
}
}2. 路由优化
json
// 指定routing,减少搜索节点数
GET /products/_search?routing=user_1
{
"query": {"term": {"category": "phone"}}
}3. 分页优化
json
// ❌ 深度分页问题
POST /products/_search
{
"from": 10000,
"size": 10
}
// ✅ 使用search_after
POST /products/_search
{
"size": 10,
"sort": [{"create_date": "desc"}, {"_id": "asc"}],
"search_after": ["2024-01-01", "100"]
}4. 聚合优化
json
// 使用filter聚合替代avg+filter
{
"aggs": {
"avg_price": {
"filter": {"term": {"status": "active"}},
"aggs": {"avg": {"avg": {"field": "price"}}}
}
}
}
// 减少精度
{
"aggs": {
"unique_users": {
"cardinality": {
"field": "user_id",
"precision_threshold": 100
}
}
}
}5. index vs query
json
// 查询时指定index只搜必要字段
GET /products/_search?preference=_local
{
"_source": ["name", "price"],
"query": {"match": {"name": "iPhone"}}
}内存优化
1. jvm堆配置
yaml
# jvm.options
-Xms4g
-Xmx4g
# 不要超过物理内存50%2. fielddata缓存
json
// 查看fielddata使用
GET /_nodes/stats/indices/fielddata
// 限制fielddata大小
{
"indices": {
"fielddata": {
"limit": "40%"
}
}
}3. circuit breaker
json
{
"indices": {
"breaker": {
"total": {
"limit": "70%"
},
"fielddata": {
"limit": "40%"
}
}
}
}面试考点
Q: 写入慢怎么优化?
- 批量写入
- 调整refresh_interval
- 关闭replica(临时)
- 用bulk
Q: 查询慢怎么优化?
- 用filter替代must
- 减少返回字段
- 用search_after分页
- 优化聚合精度
Q: 深度分页问题?
- from+size有上限(10000)
- 用search_after或scroll
