面试官:ES深度分页该如何优化?说说看ES的rollover api?ES别名机制有什么作用?ES索引数据过多该如何优化?

面试题概览:

  • 请说说看ES的深度分页该如何优化?
  • 有使用过ES的rollover api吗,rollover api的使用场景有哪些?
  • Elasticsearch中的别名机制有什么作用?
  • Elasticsearch中的Mapping是什么?如何设计合理的Mapping?
  • 知不知道Elasticsearch的ILM是什么,有什么作用?
  • Elasticsearch索引数据过多该如何优化?

面试官:请说说看ES的深度分页该如何优化

Elasticsearch(ES)的深度分页是一个常见的性能问题,特别是在处理大数据集时。

一、理解深度分页问题

Elasticsearch的默认分页方式是通过 fromsize 参数来实现的。这种方式在深度分页时会导致性能问题,因为Elasticsearch需要扫描并跳过大量的文档才能找到目标页的数据,这增加了IO操作和计算成本。

此外,Elasticsearch对结果窗口的返回数据有默认10000条的限制(参数: index.max_result_window),当 from + size 的条数大于10000条时,Elasticsearch会提示可以通过scroll方式进行分页。

二、官方优化建议

  1. 使用Scroll API

    • 适用场景:需要导出大量数据,但不关心数据实时性的场景。
    • 工作原理:Scroll API允许保持搜索上下文开放一段时间,并在这段时间内逐步检索大量数据。它会在第一次搜索时保存一个视图快照,后续搜索基于该快照提供数据,期间数据变更不会被用户看到。
    • 操作方法:初始化Scroll查询时,指定一个时间窗口(如 scroll=5m),在这个时间窗口内,可以多次请求数据而不需要重新执行原始查询。每次请求都会返回一个 _scroll_id,用于后续查询。
  2. 使用Search After API

    • 适用场景:需要实时查询且数据量大的场景。
    • 工作原理:Search After API提供了一种基于上一页最后一个文档的排序值来获取下一页数据的方法,避免了跳过大量文档的性能开销。
    • 操作方法:首次查询时不设置 search_after,后续查询时使用上一页最后一个文档的排序值作为 search_after 参数的值。

面试官:有使用过ES的rollover api吗,rollover api的使用场景有哪些?

Rollover API是Elasticsearch中用于管理索引生命周期的一个重要工具,它允许用户根据预设的条件自动滚动索引,即创建新的索引并将旧的索引移动到另一个位置(通常是归档或删除)。以下是对Rollover API的详细解释及其用途:

一、定义与原理

Rollover API的原理是基于索引别名(index alias)和预设条件来实现的。用户首先创建一个带别名的索引,并设定一定的滚动条件(如时间范围、索引大小、文档数量等)。当满足这些条件时,Elasticsearch会自动创建一个新的索引,并将别名切换指向新的索引。这样,在物理层面就实现了索引的自动分区功能。

二、用途与优势

  1. 降低索引大小 通过定期滚动索引,可以有效控制单个索引的大小,避免索引过大导致的性能问题。
  2. 提高查询性能 当查询数据落在特定时间内时,只需到相对小的索引中查询,相比所有数据都存储在一个大索引中的情况,查询效率会显著提升。
  3. 简化索引管理 Rollover API允许用户通过预设条件自动滚动索引,无需手动创建和删除索引,简化了索引管理的复杂性。
  4. 支持时间序列数据 对于时间序列数据(如日志、监控数据等),Rollover API可以根据时间范围自动滚动索引,便于按时间范围查询和分析数据。

三、使用示例

场景描述

假设你正在运行一个Elasticsearch集群,用于存储日志数据。你希望每天创建一个新的索引来存储当天的日志,并自动将旧的日志数据滚动到之前的索引中。你可以使用Rollover API来实现这一需求。

步骤

创建索引模板

首先,你需要创建一个索引模板,以便新创建的索引具有相同的mapping。假设你要创建的索引模板匹配模式为 log-*

创建初始索引并设置别名

接下来,你需要创建一个初始索引,并为其设置一个别名,以便后续使用Rollover API进行滚动。

PUT log-000001
{  
    "aliases":{  
        "log-alias":{    
            "is_write_index":true    
        }  
    }
}

在这个例子中, log-000001 是初始索引的名称, log-alias 是别名的名称,并且设置了 is_write_indextrue,表示这个别名当前指向的是写索引。

配置Rollover API的滚动条件

现在,你可以配置Rollover API的滚动条件。在这个例子中,我们假设当索引的大小达到5GB时,就创建一个新的索引。

POST log-alias/_rollover
{  
    "conditions":{    
        "max_size":"5gb"  
    }
}

这个请求会检查 log-alias 别名指向的索引是否满足 max_size 为5GB的条件。如果满足条件,Elasticsearch会创建一个新的索引(例如 log-000002),并将别名 log-alias 切换到新的索引上。

定期调用Rollover API

为了确保索引能够按照预期进行滚动,你需要定期调用Rollover API。你可以使用cron作业或其他调度计划工具来定期执行这个请求。

例如,你可以设置一个cron作业,每天凌晨执行一次Rollover API的请求。这样,每天就会创建一个新的索引来存储当天的日志数据。

四、注意事项

  1. 别名管理 在使用Rollover API时,需要确保别名正确指向当前正在写入的索引。如果别名指向了错误的索引,可能会导致数据写入错误或查询失败。
  2. 条件设置 滚动条件需要根据实际情况进行合理设置。如果条件设置过于宽松,可能会导致索引滚动过于频繁;如果条件设置过于严格,可能会导致单个索引过大或查询性能下降。

面试官:Elasticsearch中的别名机制有什么作用?

Elasticsearch中的别名(Alias)机制具有多种重要作用,以下是其主要作用的归纳:

  1. 简化查询

    • 使用别名可以为一个或多个索引提供一个更简洁、易记的名称。在查询时,用户无需记住复杂的索引名称,只需使用别名即可,从而简化了查询过程。
  2. 避免硬编码索引名

    • 在应用程序中,如果直接使用索引名称进行查询和操作,当索引名称发生变化时,需要修改大量的代码。而使用别名,可以将索引名称的变化隔离在配置文件或Elasticsearch管理界面中,避免了对应用程序代码的频繁修改。
  3. 滚动索引场景

    • 在一些场景下,如日志处理或数据分析,可能会使用滚动索引(rolling index)策略。通过别名,可以轻松地将查询和操作从一个旧索引切换到新创建的索引,而无需修改应用程序代码。
  4. 蓝绿部署

    • 在进行软件部署或数据迁移时,可以使用别名来实现蓝绿部署策略。
    • 创建两个索引,一个用于当前生产环境(蓝色),另一个用于新的版本或数据(绿色)。
    • 通过切换别名的指向,可以快速、安全地将应用程序从旧的索引切换到新的索引。
  5. 跨索引查询

    • 别名可以指向多个索引,允许在一次查询中同时搜索多个索引。
    • 这对于需要整合来自不同数据源或不同时间段的数据非常有用。
  6. 过滤特定索引

    • 通过在别名中指定过滤器,可以只包含符合特定条件的索引。
    • 这可以用于排除某些不需要的索引,或者只查询特定时间段或特定类型的数据。
  7. 索引重命名或删除

    • 如果需要重命名或删除一个索引,可以通过更新别名的指向来实现,而不会影响应用程序的正常运行。
    • 例如,当一个索引需要重命名时,可以创建一个新的索引,并将别名指向新的索引,然后删除旧的索引。
  8. 索引分组和分类

    • 可以使用别名对索引进行分组和分类,以便更好地管理和组织数据。
    • 例如,可以为不同类型的日志创建不同的别名,如“error_logs”、“info_logs”等,但实际这些不同类型的日志都存在于一个索引里。
  9. 平滑升级

    • 使用别名可以使滚动升级更加平滑,无需中断对数据的访问。
    • 在升级期间,可以将新索引添加到别名,并逐步将查询和写入流量切换到新索引。

面试官:Elasticsearch中的Mapping是什么?如何设计合理的Mapping?

Elasticsearch中的Mapping定义了索引的结构、字段类型、分词器等属性,是索引不可或缺的组成部分。Mapping有点类似于关系型数据库中的“表结构”的概念,在MySQL中,表结构包含了字段名称、字段的类型以及索引信息等,而在Elasticsearch的Mapping中也包含了类似的属性,比如字段名称、类型、字段使用的分词器、是否评分、是否创建索引等。

要设计合理的Mapping,可以从以下几个方面进行考虑:

一、明确字段类型和属性

  1. 字段类型

    • 根据数据的特点选择合适的字段类型,如数值型(double、float、integer等)、字符串型(text、keyword)、布尔型(boolean)等。
    • 注意Elasticsearch 5.X之后,String被分成text和keyword两种类型。text类型适用于分词全文检索场景,而keyword类型适用于字符串的精准匹配场景。
  2. 字段属性

    • index 控制字段是否可以索引。默认为true,即记录索引,false则不记录,即不可搜索。对于敏感信息或不需要搜索的字段,可以将其index属性设为false。
    • analyzer 设置字段的分词器。分词器决定了字段在索引和搜索时的分词方式。
    • normalizer 针对keyword字段的属性,与analyzer类似,不同之处在于它保证analyzer生成单个token。与analyzer相比,缺少了tokenizer。
    • boost 增强字段的权重。在搜索时,权重高的字段会获得更高的评分。
    • null_value 当字段遇到null值时的处理策略。可以设定该值来设定字段的默认值。

二、考虑动态映射和模板

  1. 动态映射

    • Elasticsearch具有动态映射机制,会根据插入数据自动匹配对应的类型。但为了避免类型不匹配的问题,建议显式指定字段类型。
    • 可以通过设置dynamic参数来控制动态映射的行为,如设为strict时,遇到新字段会抛出异常。
  2. 动态映射模板

    • 可以根据字段名、字段类型等条件动态设定字段类型,实现更灵活的字段映射。

下面是一个使用动态映射模板的示例:

假设我们有一个名为 my_index 的索引,我们希望对该索引中的新字段进行动态映射。我们希望根据字段的类型和内容,自动为其应用适当的映射定义。

创建索引并配置动态映射

我们可以使用PUT请求来创建索引,并在请求体中配置动态映射规则。以下是一个示例请求:

PUT /my_index
{  
    "mappings": {	
        "_doc": {	  
            "dynamic": true,  // 启用动态映射	  
            "dynamic_templates": [		
                {		  
                    "integers": {  // 定义一个动态模板,用于匹配整数字段			
                        "match_mapping_type": "long",  // 匹配JSON解析器检测到的long类型字段			
                        "mapping": {			  
                            "type": "integer"  // 将匹配的字段映射为integer类型			
                        }		  
                    }		
                },{		  
                    "strings": {  // 定义一个动态模板,用于匹配字符串字段			
                    "match_mapping_type": "string",  // 匹配JSON解析器检测到的string类型字段			
                    "mapping": {			  
                        "type": "text",  // 将匹配的字段映射为text类型			  
                        "fields": {				
                            "raw": {  // 为text字段添加一个keyword类型的子字段				 
                                 "type": "keyword",				  
                                 "ignore_above": 256  // 忽略长度超过256的字符				
                            }			  
                        }			
                    }		  
                }		
            },{		  
                "dates": {  // 定义一个动态模板,用于匹配日期字段			
                    "match": "create_date*",  // 使用模式匹配字段名,匹配以create_date开头的字段			
                    "mapping": {			  
                        "type": "date",  // 将匹配的字段映射为date类型			  
                        "format": "yyyy/MM/dd HH:mm:ss||yyyy/MM/dd||epoch_millis"  // 指定日期格式			
                    }		  
                }		
            }
        ]	
    }  
}

向索引中添加文档

在配置了动态映射之后,我们可以向索引中添加文档。Elasticsearch会根据我们定义的动态模板,自动为文档中的新字段应用适当的映射定义。

PUT /my_index/_doc/1
{  
    "name": "Alice",  
    "age": 30,  // 该字段会被映射为integer类型  
    "description": "A software engineer.",  // 该字段会被映射为text类型,并包含一个keyword类型的子字段  
    "create_date": "2023/10/01"  // 该字段会被映射为date类型,并根据指定的格式进行解析
}

验证映射结果

我们可以通过GET请求来查看索引的映射定义,以验证动态映射是否按预期工作。

GET /my_index/_mapping

三、优化索引和查询性能

  1. 避免嵌套类型(nested)的过度使用

    • nested类型会导致查询速度变慢,并且更新包含nested字段的文档会产生大量垃圾文件。
    • 在可能的情况下,可以考虑将nested字段展平或使用其他数据结构来替代。
  2. 合理设置分片

    • 分片是Elasticsearch的最大优势之一,可以将数据分散到多个节点以实施并行化。
    • 但要注意索引的主分片一旦设置便无法更改(除非重建索引或reindex)。
  3. 调整索引刷新间隔(refresh_interval)

    • 根据业务需求动态调整索引刷新间隔,以平衡索引的实时性和性能。
  4. 优化translog配置

    • 尝试调整translog的sync_interval和flush_threshold_size设置,以减少对性能的影响。

四、其他注意事项

  1. 禁用日期检测(date_detection)

    • 默认情况下,Elasticsearch会自动识别日期类型的字段。但为了避免误识别,可以禁用日期检测并显式指定字段类型。
  2. 考虑字段的复制(copy_to)

    • 可以使用copy_to属性将某个字段的值复制到另一个字段,以实现字段值的组合查询。
  3. 多字段(multi-fields)

    • 对于同一个字段,可以建立不同的索引方式,如使用不同的分词器或配置不同的属性。这有助于满足多样化的查询需求。

面试官:知不知道Elasticsearch的ILM是什么,有什么作用?

一、ILM的定义

ILM是一个涵盖信息在其整个生命周期中各个阶段的管理概念,是指从一个信息系统数据及其相关元数据产生和初始储存阶段到最后过时被删除时的一套综合管理方法。在Elasticsearch中,ILM通过定义生命周期策略,并根据这些策略自动执行索引的创建、删除、滚动、缩小等操作,从而帮助用户轻松地管理索引的生命周期。

利用 ILM 策略我们针对索引不同阶段对数据读写的要求,我们可以将索引分配到合适的节点上,从而更好地利用机器的资源。

例如最新需要频繁读写的数据,可以保存到 SSD 硬盘的节点上。

对于较旧的数据,可以保存到机械硬盘的节点上。

对于归档数据,可以保持到大容量廉价硬盘的节点上。

当数据超过一定的时间,不再需要时,可以将该数据删除。

二、ILM的主要阶段

ILM通常包括以下几个阶段,每个阶段都有其特定的优化目标和操作:

  1. Hot阶段 此阶段索引处于活动状态,数据频繁更新和查询。优化目标是高写入速度和实时查询性能。为此,索引可能会被放置在高性能硬件上,并拥有较多的副本以保证可用性。在这个阶段,可以配置滚动索引,将较旧的数据移动到暖阶段或冷阶段。此外,可以设置索引别名,使所有查询都指向新索引。
  2. Warm阶段 此阶段索引处于半活动状态,数据较少更新和查询。在这个阶段,可以执行一些操作,如压缩索引、合并段或更改数据存储方式,以减少存储成本。索引可能会被迁移到成本较低的硬件上。
  3. Cold阶段 此阶段索引处于非活动状态,数据不再更新,只有少量查询。在这个阶段,可以将索引移动到低成本的存储层(如S3),以进一步减少存储成本。数据通常会被压缩并存储在更便宜的存储介质上。
  4. Delete阶段 此阶段索引被删除,释放存储空间。当数据达到其保留期限或不再需要时,ILM会自动删除索引。

以下是一个Elasticsearch的索引生命周期管理(ILM)配置的示例,该示例展示了如何创建一个ILM策略并将其应用于索引模板:

1. 创建ILM策略

首先,我们需要创建一个ILM策略。在这个示例中,我们将创建一个名为 my_policy 的策略,该策略包含两个阶段:hot阶段和delete阶段。在hot阶段,当索引的大小超过50GB或年龄超过10天时,将触发rollover操作。在delete阶段,当索引的年龄超过30天时,将删除该索引。

可以使用以下HTTP PUT请求来创建这个策略:

PUT /_ilm/policy/my_policy{  "policy": 
{    
    "phases": {      
        "hot": {        
            "actions": {          
                "rollover": {            
                    "max_size": "50gb",            
                    "max_age": "10d"          
                    }        
                }      
            },     
             "delete": {        
                "min_age": "30d",        
                "actions": {          
                    "delete": {}      
                }      
             }    
        } 
    }
}

2. 创建索引模板

接下来,我们需要创建一个索引模板,并将前面创建的ILM策略应用到这个模板上。在这个示例中,我们将创建一个名为 my_template 的模板,该模板将自动把生命周期管理策略 my_policy 赋给索引名称以 test- 开头的索引。

可以使用以下HTTP PUT请求来创建这个模板:

PUT /_template/my_template
{  
    "index_patterns": ["test-*"],  
    "settings": {    
        "index.lifecycle.name": "my_policy",    
        "index.lifecycle.rollover_alias": "test-alias"  
    }
}

3. 创建索引

现在,我们可以创建一个新的索引,该索引将自动应用前面创建的模板和ILM策略。在这个示例中,我们将创建一个名为 test-000001 的索引,并为其设置一个别名 test-alias,该别名将用于rollover操作。

可以使用以下HTTP PUT请求来创建这个索引:

PUT /test-000001
{  
    "aliases": {    
        "test-alias": {      
            "is_write_index": true    
        }  
    }
}

4. 验证配置

最后,我们可以通过获取索引的详细信息来验证ILM策略是否已经成功应用。在这个示例中,我们将获取 test-000001 索引的详细信息,并检查其设置中的 lifecycle 字段。

可以使用以下HTTP GET请求来获取索引的详细信息:

GET /test-000001

在响应体中,我们应该能够看到类似以下的设置:

"settings": {  
    "index": {    
        "lifecycle": {      
            "name": "my_policy",     
             "rollover_alias": "test-alias"    
        },    
        "number_of_shards": "1",    
        "provided_name": "test-000001",  
        "creation_date": "时间戳",    
        "number_of_replicas": "1",    
        "uuid": "索引UUID",    
        "version": {      
            "created": "版本号"    
        }  
    }
}

这表明ILM策略 my_policy 已经成功应用到 test-000001 索引上。

通过以上步骤,我们完成了一个简单的ES ILM配置示例。

下面再来看一个 ILM 策略,包含以下 4 个阶段:

Hot 阶段:超过 5 个文档以后 rollover 创建新的索引。

Warm 阶段:60s 后进入 warm 阶段,将副本分片数缩减为 0。

Cold 阶段:120s 后进入 cold 阶段,将索引设置为只读。

Delete 阶段:180s 后进入 delete 阶段,删除索引。

其策略描述如下:

PUT _ilm/policy/log-ilm-policy{  "policy": 
{   
    "phases": {      
        "hot": {        
            "min_age": "0s",        
            "actions": {          
                "rollover": {            
                    "max_docs": 5  // 超过 5 个文档以后 rollover 创建新的索引          
                },          
                "set_priority": {            
                    "priority": 100 // 优先级最高,当节点重启后优先恢复 hot 阶段的索引          
                }        
            }     
        },      
        "warm": {       
            "min_age": "60s", // 60s 后进入 warn 阶段     
                "actions": {         
                "allocate": {     
                    "number_of_replicas": 0 // 将副本分片数缩减为 0         
                },          
                "set_priority": {            
                    "priority": 50          
                }        
            }      
        },      
        "cold": {        
            "min_age": "120s", // 120s 后进入 cold 阶段        
            "actions": {          
                "readonly" : {}, // 将索引设置为只读          
                "set_priority": {           
                    "priority": 0          
                }       
            }     
        },      
        "delete": {        
            "min_age": "180s", // 180s 后删除索引        
            "actions": {         
                "delete": {}      
            }     
        }   
    }  
}

三、ILM的作用

  1. 自动化管理 ILM减少了手动管理索引的需求,从而降低了出错的风险和运营成本。管理员可以定义生命周期策略,并将其应用到新创建或现有的索引上。当索引满足某个阶段的触发条件时,ILM会自动将其移动到下一个阶段并执行相应的操作。
  2. 成本优化 通过将数据移动到成本较低的存储介质上,ILM有助于降低存储成本。例如,在Cold阶段,数据可以被压缩并存储在更便宜的HDD上,而不是高性能的SSD上。又例如,在Hot阶段,索引可能会被放置在高性能硬件上,并拥有较多的副本以保证可用性;而在Warm和Cold阶段,则可以执行一些操作来减少存储占用并提高查询效率。
  3. 简化操作 ILM提供了一种统一的方式来管理索引的生命周期,使得跨多个Elasticsearch集群的操作更加简单和一致。管理员可以通过监视工具来观察索引如何随着时间的推移在生命周期的各个阶段之间转换,并根据实际的数据保留需求和硬件资源来调整生命周期策略中的设置。

面试官:Elasticsearch索引数据过多该如何优化?

一、索引管理策略

  1. 按时间分割索引

    • 对于时间序列数据(如日志、监控数据等),可以按时间(如天、周或月)分割索引。这种策略主要是指以时间为后缀创建多个索引,而不是在一个索引内按照时间分片。按时间分割索引可以控制单个索引的大小,提高查询效率,并便于历史数据的清理。 以下是对按时间分割索引的详细说明以及代码示例:

    ### 按时间分割索引的说明

    1. 索引命名 每个索引的名称以时间为后缀,例如“logs-2024-09”表示2024年9月的日志数据。
    2. 索引别名 使用索引别名(index alias)可以简化对时间分割索引的管理。别名可以指向一个或多个索引,查询时只需针对别名进行查询即可。
    3. 索引生命周期管理 Elasticsearch的索引生命周期管理(ILM)功能可以自动管理索引的生命周期,包括创建、保留和删除索引。

    代码示例

    • ### 创建索引模板

    首先,可以创建一个索引模板,用于定义索引的默认属性和分片设置。以下是一个示例模板,用于创建按天分割的日志索引:

     PUT _template/daily_logs
     {  
        "order": 0,  
        "index_patterns": ["logs-*"],  
        "settings": {    
            "index": {      
                "refresh_interval": "5s",      
                "number_of_shards": 1,      
                "number_of_replicas": 1,      
                "lifecycle": {        
                    "name": "logs_policy",  // 引用后面创建的索引生命周期策略        
                    "rollover_alias": "logs"  // 指定别名,用于rollover操作     
                }    
            } 
          },  
          "mappings": {    
             "_source": {      
                    "enabled": true    
             },    
             "properties": {     
                    "timestamp": {        
                        "type": "date",        
                        "format": "yyyy-MM-dd HH:mm:ss"      
                    },      
                    "message": {        
                        "type": "text"      
                    },      // 其他字段定义    
             } 
          },  
          "aliases": {    
            "logs": {  // 这里只是声明别名,实际别名指向由rollover API管理      
               "is_write_index": false  // 不允许直接写入此别名    
            } 
          }
        }
    

    注意:在上面的模板中,没有直接为索引指定别名,因为别名将由rollover API在索引滚动(rollover)时动态分配。 rollover_alias 字段指定了用于rollover操作的别名,而 is_write_index 设置为false表示不允许直接写入此别名。

    另外,生命周期策略 logs_policy 需要在后面单独创建,用于定义索引的保留时间、滚动条件等。

    然而,Elasticsearch的ILM功能在较新版本中可能有所变化,并且可能不支持在索引模板中直接指定 rollover_aliasis_write_index。在这种情况下,你可以使用Logstash、Filebeat等客户端工具配合Elasticsearch的Index Lifecycle Management(ILM)策略来实现索引的按时间滚动创建和删除。

    对于较旧版本的Elasticsearch或者不使用ILM的情况,你可以手动创建索引并为其分配别名。以下是一个手动创建索引并分配别名的示例:

     PUT /logs-2024-12-11
     {  
        "settings": {   
            "number_of_shards": 1,    
            "number_of_replicas": 1  
        },  
        "mappings": {    
            "properties": {      
                "timestamp": {        
                    "type": "date",        
                    "format": "yyyy-MM-dd HH:mm:ss"      
                },      
                "message": {        
                    "type": "text"      
                },      // 其他字段定义    
            }  
        },  
        "aliases": {    
            "logs": {}  // 将别名"logs"指向当前索引  
        }
     }
    
    • 请注意,手动方式需要定期创建新索引并更新别名指向,这通常通过脚本或自动化工具来实现。

    • 使用索引别名进行查询

    查询时,只需针对别名进行查询即可。Elasticsearch会自动将查询分发到别名所指向的所有索引中。以下是一个查询示例:

     GET /logs/_search
     {  
         "query": {    
             "range": {      
                "timestamp": {        
                    "gte": "2024-12-11T00:00:00",        
                    "lte": "2024-12-11T23:59:59"      
                }    
             }  
        },  
        "_source": ["timestamp", "message"]  // 只返回所需的字段
     }
    

    在这个查询中,我们针对别名“logs”进行了查询,并指定了时间范围。Elasticsearch会自动将查询分发到别名所指向的所有符合时间范围的索引中。

    • 索引滚动(如果需要的话)

    对于使用ILM的情况,Elasticsearch会根据预设的策略自动进行索引的滚动创建和删除。滚动创建是指当满足一定条件时(如索引大小、文档数量等),Elasticsearch会自动创建一个新的索引,并将写入操作切换到新索引上。同时,旧索引会根据策略进行保留或删除。

    对于不使用ILM的情况,你需要手动进行索引的滚动创建和别名更新。涉及以下步骤:

    • 创建一个新索引并为其分配一个临时别名(如 logs-temp)。
    • 将写入操作切换到新索引上。
    • 更新别名指向,将 logs 别名从旧索引指向新索引(可能需要先删除旧索引上的别名)。
  2. 索引合并

    • 当旧的索引不再频繁访问时,可以考虑将多个小索引合并为一个大索引,以节省存储空间和减少索引的管理开销。
    • Elasticsearch的索引生命周期管理(ILM)功能允许自动管理索引的生命周期,包括索引的分割、迁移和删除操作。

二、分片和副本配置

  1. 分片数量

    • 初始分片数量应根据预计的数据量进行合理配置。
    • 建议单个分片的大小保持在10~50GB之间,以确保分片查询的效率。
    • 当发现分片配置不合理时,可以通过reindex API或使用Elasticsearch提供的分片重分布工具来调整分片数量。
  2. 副本数量

    • 副本增加了查询性能的并发性和数据的冗余性,但也会增加磁盘和网络开销。
    • 通常,1~2个副本是合理的配置,具体数量取决于查询压力和容灾要求。
    • 可以根据实际需求动态调整副本数量,如在非高峰期减少副本数量以节省资源,在高峰期增加副本数量以提升查询性能。

三、查询优化

  1. 索引字段的优化

    • 在查询时,只检索所需的字段,避免不必要的数据传输。
    • 可以通过_source参数控制返回字段。
  2. 利用过滤器

    • 对于不需要打分的查询部分,使用过滤器(filter)而不是查询(query),因为过滤器不会参与打分计算,性能更高。
  3. 避免深度分页

    • 深度分页(如使用from和size参数)可能导致严重的性能问题。
    • 可以考虑使用search_after或scroll API来处理大数据量分页。

原文阅读