索引设置优化
- 字段映射优化
- 数据类型选择:尽量使用能够准确表示数据且占用空间小的数据类型。例如,对于固定范围的整数,选择合适的整型(如
byte
、short
等)而不是 long
。对于不需要进行全文搜索的文本字段,使用 keyword
类型,这样可避免分词带来的性能损耗。
- 动态映射:谨慎使用动态映射,避免因为自动映射生成不必要的字段。可以通过预定义字段映射来控制索引结构,减少不必要的字段和映射冲突。
- 索引分片与副本设置
- 分片数量:根据数据量和集群规模合理设置分片数量。一般原则是每个分片大小控制在 10GB - 50GB 左右。如果数据量较小,过多的分片会增加集群管理开销;数据量较大时,分片过少会导致单个分片数据量过大,影响搜索性能。可以根据预估的数据量和节点数量,通过公式大致估算分片数。
- 副本数量:副本主要用于提高数据可用性和搜索性能。适当增加副本数量可以提升读性能,但过多的副本会占用更多的磁盘空间和网络带宽,同时在数据写入时也会增加额外的同步开销。一般设置 1 - 2 个副本即可,根据实际业务对读写性能的要求进行调整。
- 索引存储优化
- 存储类型选择:对于不同类型的数据,可以选择不同的存储类型。例如,对于一些很少更新但经常查询的索引,可以使用
doc_values
存储来加快排序和聚合操作;对于需要快速检索的文本字段,使用 fielddata
(但要注意内存消耗)。
- 压缩:开启索引数据的压缩,可以有效减少磁盘空间占用,提高磁盘 I/O 效率。Elasticsearch 支持多种压缩算法,如
LZ4
、DEFLATE
等,LZ4
算法在性能和压缩比之间有较好的平衡,通常是较好的选择。
查询语句优化
- 减少返回字段:尽量只返回需要的字段,避免返回所有字段(
_source
)。通过在查询语句中指定 _source
包含或排除某些字段,可以减少网络传输的数据量,提高查询性能。例如:
{
"query": {
"match_all": {}
},
"_source": ["field1", "field2"]
}
- 使用过滤代替查询:对于不需要进行相关性评分的条件,使用
filter
而不是 query
。filter
操作通常会利用缓存,查询性能更高。例如,在根据某个固定值过滤文档时:
{
"query": {
"bool": {
"filter": [
{
"term": {
"category": "electronics"
}
}
]
}
}
}
- 优化布尔查询:在使用
bool
查询时,合理安排 must
、should
、filter
和 must_not
子句。将更严格、过滤效果更好的条件放在前面,这样可以快速减少需要处理的文档数量。例如,如果有两个条件,一个是 term
过滤条件,另一个是 match
全文搜索条件,应将 term
条件放在前面作为 filter
或 must
子句。
- 使用聚合优化:在进行聚合操作时,尽量减少聚合的层级和聚合的文档数量。可以通过
filter
先对数据进行过滤,然后再进行聚合。同时,对于嵌套聚合,合理安排聚合顺序,以减少中间结果集的大小。例如:
{
"query": {
"bool": {
"filter": [
{
"range": {
"price": {
"gte": 100
}
}
}
]
}
},
"aggs": {
"category_agg": {
"terms": {
"field": "category"
},
"aggs": {
"avg_price": {
"avg": {
"field": "price"
}
}
}
}
}
}
- 避免使用通配符查询:通配符查询(如
*
和 ?
)在大数据量时性能较差,因为它需要对每个文档进行匹配。尽量使用 term
或 match
查询代替通配符查询,如果实在需要使用通配符,尽量将通配符放在词尾而不是词首,因为词首通配符查询无法利用倒排索引,性能更低。
其他优化
- 集群硬件优化
- 硬件配置:确保集群节点有足够的内存、CPU 和磁盘 I/O 性能。内存对于 Elasticsearch 非常重要,因为它会缓存索引数据和查询结果。建议为每个节点分配足够的堆内存,但也要注意避免堆内存过大导致垃圾回收问题。CPU 性能影响数据处理速度,磁盘 I/O 性能则影响数据的读写速度,选择高性能的磁盘(如 SSD)可以显著提升性能。
- 网络优化:保证集群内部网络带宽充足,减少网络延迟和丢包。合理配置网络拓扑,避免网络瓶颈。
- 缓存优化
- 查询结果缓存:利用 Elasticsearch 的查询结果缓存机制,如
fielddata
缓存和 filter
缓存。fielddata
缓存可以加快排序和聚合操作,filter
缓存可以缓存过滤结果,提高重复查询的性能。但要注意缓存的内存管理,避免缓存占用过多内存导致节点性能下降。
- 索引缓存:合理设置索引的缓存参数,如
index.cache.filter.size
和 index.cache.fielddata.size
,以控制缓存的大小和使用方式。根据业务查询模式和数据特点,调整这些参数以达到最佳的缓存效果。