Elasticsearch 架構(gòu)與索引設(shè)計(jì)完全指南:輕松掌握建模到實(shí)戰(zhàn)的寶貴經(jīng)驗(yàn)
本文系統(tǒng)性地介紹了 Elasticsearch 的架構(gòu)設(shè)計(jì)、索引規(guī)范、Mapping 優(yōu)化、查詢性能調(diào)優(yōu)及生命周期管理等核心內(nèi)容。通過(guò)電商產(chǎn)品與用戶行為日志兩大實(shí)戰(zhàn)案例,詳解字段類型選擇、分片策略、ILM 策略配置,以及寫(xiě)入、查詢、聚合的優(yōu)化技巧。附有監(jiān)控指標(biāo)、日常運(yùn)維清單和不同規(guī)模應(yīng)用的架構(gòu)方案,助力構(gòu)建高性能、高可用、易維護(hù)的搜索與數(shù)據(jù)分析平臺(tái)。
1. 架構(gòu)設(shè)計(jì)概述
1.1 設(shè)計(jì)目標(biāo)
- 高性能: 毫秒級(jí)查詢響應(yīng),支持高并發(fā)訪問(wèn)
- 高可用: 99.9% 以上服務(wù)可用性
- 可擴(kuò)展: 支持水平擴(kuò)展,應(yīng)對(duì)數(shù)據(jù)增長(zhǎng)
- 易維護(hù): 清晰的索引結(jié)構(gòu),便于運(yùn)維管理
1.2 核心設(shè)計(jì)原則
- 合理的數(shù)據(jù)建模: 根據(jù)查詢模式設(shè)計(jì)索引結(jié)構(gòu)
- 適度的冗余: 在存儲(chǔ)和性能間平衡
- 分片策略: 合理規(guī)劃分片數(shù)量和大小
- 映射優(yōu)化: 精確定義字段類型和分析器
- 生命周期管理: 實(shí)施 ILM 策略管理數(shù)據(jù)
2. 索引設(shè)計(jì)規(guī)范
2.1 命名規(guī)范
<業(yè)務(wù)域>-<數(shù)據(jù)類型>-<環(huán)境>-<版本>-<時(shí)間標(biāo)識(shí)>
示例:
- product-catalog-prod-v1
- user-behavior-prod-v2-2025.10
- order-transaction-dev-v1-2025.10.18命名規(guī)則:
- 使用小寫(xiě)字母
- 使用連字符 - 分隔
- 避免使用特殊字符
- 時(shí)間序列數(shù)據(jù)包含日期標(biāo)識(shí)
2.2 分片策略
分片數(shù)量計(jì)算
建議分片大小: 20GB - 50GB
分片數(shù)量 = 預(yù)估數(shù)據(jù)總量 / 目標(biāo)分片大小
示例:
- 數(shù)據(jù)量 500GB,建議分片數(shù): 500GB / 30GB ≈ 17 個(gè)主分片分片配置建議
數(shù)據(jù)規(guī)模 | 主分片數(shù) | 副本數(shù) | 說(shuō)明 |
< 10GB | 1-3 | 1 | 小型索引 |
10GB - 100GB | 3-5 | 1-2 | 中型索引 |
100GB - 1TB | 5-15 | 1-2 | 大型索引 |
> 1TB | 15-30 | 2 | 超大索引,考慮索引拆分 |
2.3 副本策略
{
"settings": {
"number_of_shards": 5,
"number_of_replicas": 1,
"refresh_interval": "30s"
}
}副本數(shù)建議:
- 生產(chǎn)環(huán)境: 至少 1 個(gè)副本
- 讀密集型: 2-3 個(gè)副本
- 寫(xiě)密集型: 1 個(gè)副本
- 開(kāi)發(fā)環(huán)境: 0 個(gè)副本
3. Mapping 設(shè)計(jì)
3.1 字段類型選擇
基礎(chǔ)類型映射表
數(shù)據(jù)特征 | ES 類型 | 說(shuō)明 |
精確值(ID、狀態(tài)) | keyword | 不分詞,支持聚合 |
全文搜索 | text | 分詞索引 |
數(shù)值計(jì)算 | long, integer, double | 支持范圍查詢 |
日期時(shí)間 | date | 支持日期范圍查詢 |
布爾值 | boolean | true/false |
IP 地址 | ip | 支持 CIDR 查詢 |
地理位置 | geo_point, geo_shape | 地理查詢 |
嵌套對(duì)象 | nested | 獨(dú)立索引的對(duì)象數(shù)組 |
父子關(guān)系 | join | 關(guān)聯(lián)文檔 |
3.2 實(shí)戰(zhàn)案例:電商產(chǎn)品索引
{
"settings": {
"number_of_shards": 5,
"number_of_replicas": 1,
"refresh_interval": "30s",
"max_result_window": 10000,
"analysis": {
"analyzer": {
"ik_smart_pinyin": {
"type": "custom",
"tokenizer": "ik_smart",
"filter": ["lowercase", "pinyin_filter"]
}
},
"filter": {
"pinyin_filter": {
"type": "pinyin",
"keep_first_letter": true,
"keep_full_pinyin": false,
"keep_original": true
}
}
}
},
"mappings": {
"properties": {
"product_id": {
"type": "keyword"
},
"product_name": {
"type": "text",
"analyzer": "ik_smart_pinyin",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
},
"standard": {
"type": "text",
"analyzer": "standard"
}
}
},
"category": {
"type": "keyword"
},
"category_path": {
"type": "text",
"analyzer": "path_analyzer",
"fielddata": true
},
"price": {
"type": "scaled_float",
"scaling_factor": 100
},
"stock": {
"type": "integer"
},
"sales_count": {
"type": "long"
},
"rating": {
"type": "half_float"
},
"brand": {
"type": "keyword"
},
"tags": {
"type": "keyword"
},
"description": {
"type": "text",
"analyzer": "ik_max_word"
},
"attributes": {
"type": "nested",
"properties": {
"name": {
"type": "keyword"
},
"value": {
"type": "keyword"
}
}
},
"images": {
"type": "keyword",
"index": false
},
"status": {
"type": "keyword"
},
"created_at": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss||epoch_millis"
},
"updated_at": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss||epoch_millis"
},
"location": {
"type": "geo_point"
},
"seller": {
"properties": {
"seller_id": {
"type": "keyword"
},
"seller_name": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword"
}
}
},
"seller_rating": {
"type": "half_float"
}
}
}
}
}
}3.3 實(shí)戰(zhàn)案例:用戶行為日志索引
{
"settings": {
"number_of_shards": 10,
"number_of_replicas": 1,
"refresh_interval": "5s",
"index.lifecycle.name": "user-behavior-policy",
"index.lifecycle.rollover_alias": "user-behavior-prod"
},
"mappings": {
"properties": {
"user_id": {
"type": "keyword"
},
"session_id": {
"type": "keyword"
},
"event_type": {
"type": "keyword"
},
"event_name": {
"type": "keyword"
},
"timestamp": {
"type": "date"
},
"page_url": {
"type": "keyword",
"fields": {
"text": {
"type": "text"
}
}
},
"referrer": {
"type": "keyword"
},
"device": {
"properties": {
"type": {
"type": "keyword"
},
"os": {
"type": "keyword"
},
"browser": {
"type": "keyword"
}
}
},
"geo": {
"properties": {
"country": {
"type": "keyword"
},
"city": {
"type": "keyword"
},
"location": {
"type": "geo_point"
}
}
},
"properties": {
"type": "object",
"enabled": false
},
"ip_address": {
"type": "ip"
},
"user_agent": {
"type": "text",
"index": false
}
}
}
}4. 查詢優(yōu)化設(shè)計(jì)
4.1 字段設(shè)計(jì)優(yōu)化
Multi-fields 策略
{
"product_name": {
"type": "text",
"analyzer": "ik_smart",
"fields": {
"keyword": {
"type": "keyword"
},
"pinyin": {
"type": "text",
"analyzer": "pinyin_analyzer"
},
"suggest": {
"type": "completion"
}
}
}
}使用場(chǎng)景:
- 主字段: 全文搜索
- .keyword: 精確匹配、聚合、排序
- .pinyin: 拼音搜索
- .suggest: 自動(dòng)補(bǔ)全
4.2 禁用不必要的功能
{
"large_text": {
"type": "text",
"index": false,
"norms": false,
"doc_values": false
},
"static_content": {
"type": "keyword",
"index": false
}
}優(yōu)化建議:
- index: false: 不需要搜索的字段
- norms: false: 不需要評(píng)分的字段
- doc_values: false: 不需要聚合/排序的字段
- enabled: false: 僅存儲(chǔ),不索引不解析
5. 索引生命周期管理 (ILM)
5.1 ILM 策略示例
{
"policy": {
"phases": {
"hot": {
"min_age": "0ms",
"actions": {
"rollover": {
"max_size": "50GB",
"max_age": "7d",
"max_docs": 100000000
},
"set_priority": {
"priority": 100
}
}
},
"warm": {
"min_age": "7d",
"actions": {
"allocate": {
"number_of_replicas": 1
},
"forcemerge": {
"max_num_segments": 1
},
"shrink": {
"number_of_shards": 1
},
"set_priority": {
"priority": 50
}
}
},
"cold": {
"min_age": "30d",
"actions": {
"allocate": {
"number_of_replicas": 0
},
"freeze": {},
"set_priority": {
"priority": 0
}
}
},
"delete": {
"min_age": "90d",
"actions": {
"delete": {}
}
}
}
}
}5.2 階段劃分策略
階段 | 時(shí)間 | 操作 | 適用場(chǎng)景 |
Hot | 0-7天 | 高性能寫(xiě)入和查詢 | 實(shí)時(shí)數(shù)據(jù) |
Warm | 7-30天 | 減少副本,合并段 | 近期數(shù)據(jù) |
Cold | 30-90天 | 凍結(jié)索引,最小資源 | 歷史數(shù)據(jù) |
Delete | 90天+ | 刪除索引 | 過(guò)期數(shù)據(jù) |
6. 性能優(yōu)化建議
6.1 寫(xiě)入優(yōu)化
{
"settings": {
"refresh_interval": "30s",
"number_of_replicas": 0,
"translog": {
"durability": "async",
"sync_interval": "30s",
"flush_threshold_size": "1gb"
}
}
}批量寫(xiě)入配置:
- 批量大小: 5-15 MB
- 并發(fā)請(qǐng)求: 根據(jù)節(jié)點(diǎn)數(shù)調(diào)整
- 初始化時(shí): 副本設(shè)為 0,寫(xiě)入完成后恢復(fù)
6.2 查詢優(yōu)化
使用 Filter Context
{
"query": {
"bool": {
"must": [
{ "match": { "product_name": "手機(jī)" } }
],
"filter": [
{ "term": { "status": "active" } },
{ "range": { "price": { "gte": 1000, "lte": 5000 } } }
]
}
}
}分頁(yè)優(yōu)化
深度分頁(yè)問(wèn)題解決:
- 使用 search_after 替代 from/size
- 使用 Scroll API 處理大數(shù)據(jù)集
- 限制 max_result_window
6.3 聚合優(yōu)化
{
"aggs": {
"category_stats": {
"terms": {
"field": "category",
"size": 10,
"execution_hint": "map"
},
"aggs": {
"avg_price": {
"avg": {
"field": "price"
}
}
}
}
}
}7. 監(jiān)控與維護(hù)
7.1 關(guān)鍵指標(biāo)監(jiān)控
指標(biāo)類型 | 監(jiān)控項(xiàng) | 告警閾值 |
集群健康 | cluster_health | status != green |
節(jié)點(diǎn)狀態(tài) | node_stats | CPU > 80%, Memory > 85% |
索引性能 | indexing_rate | 突降 50% |
查詢性能 | search_latency | p99 > 1s |
磁盤(pán)使用 | disk_usage | > 85% |
JVM 堆內(nèi)存 | heap_used_percent | > 75% |
7.2 日常運(yùn)維檢查清單
# 1. 檢查集群健康狀態(tài)
GET /_cluster/health
# 2. 查看節(jié)點(diǎn)狀態(tài)
GET /_cat/nodes?v
# 3. 檢查索引狀態(tài)
GET /_cat/indices?v&s=store.size:desc
# 4. 查看分片分配
GET /_cat/shards?v&h=index,shard,prirep,state,node
# 5. 檢查待處理任務(wù)
GET /_cat/pending_tasks
# 6. 查看熱點(diǎn)線程
GET /_nodes/hot_threads8. 最佳實(shí)踐總結(jié)
8.1 設(shè)計(jì)階段
? DO:
- 根據(jù)查詢模式設(shè)計(jì)索引
- 使用合適的字段類型
- 合理規(guī)劃分片數(shù)量
- 設(shè)計(jì) ILM 策略
- 預(yù)留 20-30% 磁盤(pán)空間
? DON'T:
- 過(guò)度設(shè)計(jì)字段
- 分片數(shù)過(guò)多或過(guò)少
- 忽略數(shù)據(jù)增長(zhǎng)預(yù)估
- 所有字段都可搜索
- 忽略索引生命周期
8.2 開(kāi)發(fā)階段
? DO:
- 使用批量 API
- 優(yōu)先使用 Filter Context
- 限制返回字段
- 使用 Query DSL 而非 Script
- 啟用查詢緩存
? DON'T:
- 深度分頁(yè)
- 使用 Wildcard 查詢開(kāi)頭
- 過(guò)度使用 Script
- 忽略查詢超時(shí)設(shè)置
- 返回不必要的字段
8.3 運(yùn)維階段
? DO:
- 定期監(jiān)控集群狀態(tài)
- 定期備份重要數(shù)據(jù)
- 定期清理過(guò)期索引
- 優(yōu)化慢查詢
- 記錄配置變更
? DON'T:
- 忽略告警信息
- 磁盤(pán)使用超過(guò) 85%
- 手動(dòng)刪除系統(tǒng)索引
- 在生產(chǎn)環(huán)境直接測(cè)試
- 忽略版本升級(jí)
9. 架構(gòu)方案參考
9.1 小型應(yīng)用 (< 100GB)
架構(gòu)配置:
- 節(jié)點(diǎn)數(shù): 3
- 每節(jié)點(diǎn): 8C 16G 500GB SSD
- 索引分片: 3 主 + 1 副本
- 適用場(chǎng)景: 企業(yè)內(nèi)部搜索、小型電商9.2 中型應(yīng)用 (100GB - 1TB)
架構(gòu)配置:
- 節(jié)點(diǎn)數(shù): 6-9 (3 Master + 6 Data)
- Data 節(jié)點(diǎn): 16C 64G 2TB SSD
- 索引分片: 5-10 主 + 1-2 副本
- 適用場(chǎng)景: 中型電商、日志分析平臺(tái)9.3 大型應(yīng)用 (> 1TB)
架構(gòu)配置:
- 節(jié)點(diǎn)數(shù): 15+ (3 Master + 10+ Data + 2 Coordinating)
- Data 節(jié)點(diǎn): 32C 128G 4TB SSD
- 索引分片: 10-20 主 + 2 副本
- 冷熱分離架構(gòu)
- 適用場(chǎng)景: 大型電商、企業(yè)級(jí)日志系統(tǒng)10. API
10.1 常用 API 速查
# 創(chuàng)建索引
PUT /my-index
# 更新 Mapping
PUT /my-index/_mapping
# 更新 Settings (部分)
PUT /my-index/_settings
# 重建索引
POST /_reindex
# 索引別名
POST /_aliases
# 關(guān)閉索引
POST /my-index/_close
# 打開(kāi)索引
POST /my-index/_open
# 刪除索引
DELETE /my-index


































