索引设计
- 合理的字段映射:
- 避免使用
text
类型进行聚合,对于需要聚合的字段,使用keyword
类型。例如,如果有一个“商品类别”字段用于聚合统计各类别商品数量,将其映射为keyword
类型。
- 对于嵌套文档,确保嵌套层级不要过深,过深的嵌套会增加查询和解析的复杂度。例如,在订单文档中,订单包含多个订单项,订单项又包含商品信息等,尽量控制这种嵌套深度在2 - 3层以内。
- 适当的索引分片:
- 根据数据量和集群节点数合理分配分片。如果有数十亿条文档,可以适当增加分片数量,但要注意每个分片不要过小(一般建议单个分片不小于10GB且不大于50GB)。例如,对于100亿条文档,每个文档大小约1KB,总数据量约1TB,可以考虑设置20 - 30个分片。
查询优化
- 使用Filter代替Query:
- 如果查询只是为了筛选数据而非打分,使用
filter
子句。例如,要查询某个特定日期范围内的文档,使用filter
而不是query
,因为filter
不进行打分计算,性能更高。
- 示例:
{
"query": {
"bool": {
"filter": [
{
"range": {
"create_date": {
"gte": "2023 - 01 - 01",
"lte": "2023 - 12 - 31"
}
}
}
]
}
}
}
- 分页优化:
- 避免使用
from
和size
进行深度分页,对于大数据量的分页,使用scroll
或者search_after
。例如,当需要获取第10000 - 10010条数据时,使用search_after
:
{
"size": 10,
"query": {
"match_all": {}
},
"search_after": [10000]
}
脚本优化
- 尽量避免脚本:
- 如果可能,使用Elasticsearch内置的聚合功能替代自定义脚本。例如,计算文档中某个数值字段的平均值,使用
avg
聚合而不是编写自定义脚本计算。
- 脚本语言选择:
- 如果必须使用脚本,优先选择Painless脚本,因为它在Elasticsearch中性能更好。例如,对于复杂的多字段聚合计算,用Painless脚本编写计算逻辑。
ElasticSearch集群配置
- 硬件资源优化:
- 确保集群节点有足够的内存和CPU资源。例如,对于处理数十亿条文档的集群,每个节点可以配置16GB以上内存,多核CPU。
- 节点角色分离:
- 可以将集群节点分为不同角色,如专门的
master
节点负责集群管理,data
节点负责存储和处理数据,coordinating
节点负责接收客户端请求和分发查询等。这样可以提高集群的整体性能。
- 调优集群参数:
- 调整
indices.memory.index_buffer_size
参数,根据集群内存情况合理分配索引缓冲区大小,一般可以设置为节点堆内存的10% - 30%。例如,节点堆内存为32GB,可以将该参数设置为3.2GB - 9.6GB之间。