Skip to content

性能优化

写入优化

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

最后更新: