MK
摩柯社区 - 一个极简的技术知识社区
AI 面试

ElasticSearch索引设置的参数调整

2021-05-181.7k 阅读

ElasticSearch 索引设置的基础概念

在 ElasticSearch 中,索引是文档的集合,类似于传统关系型数据库中的数据库概念。索引设置决定了 ElasticSearch 如何存储、检索和管理文档数据。理解索引设置的参数对于优化 ElasticSearch 的性能和功能至关重要。

索引的结构

ElasticSearch 的索引由多个分片(shard)组成,每个分片是一个独立的 Lucene 索引。分片的设计使得 ElasticSearch 能够处理大规模数据,并实现分布式存储和并行处理。除了主分片,索引还可以有副本分片(replica shard),副本分片用于数据冗余和高可用性,同时也能分担读请求。

索引设置的参数类型

  1. 基本参数:例如 index.number_of_shardsindex.number_of_replicas,分别定义了索引的主分片数量和副本分片数量。这些参数在索引创建时设置,并且在大多数情况下,一旦索引创建后,主分片数量不能更改,而副本分片数量可以动态调整。
  2. 存储相关参数:如 index.codec,它决定了 ElasticSearch 使用的存储编解码器。不同的编解码器在压缩率和读写性能上有所不同,选择合适的编解码器可以有效节省磁盘空间或提高读写速度。
  3. 索引生命周期管理参数:例如 index.lifecycle.nameindex.lifecycle.rollover_alias,用于管理索引的生命周期,包括索引的创建、滚动、删除等操作。这些参数在大规模数据管理场景中非常重要,可以自动化索引的维护过程。

调整主分片和副本分片参数

主分片数量的选择

主分片数量的设置直接影响到 ElasticSearch 的数据分布和查询性能。如果主分片数量过多,会导致每个分片的数据量过小,增加了分片之间的通信开销,降低查询效率;而主分片数量过少,则可能导致单个分片数据量过大,影响索引和查询的性能。

  1. 考虑因素
    • 数据量:预估索引未来的数据量大小。如果数据量会持续增长,应适当设置较多的主分片,以避免后期数据量过大导致的性能问题。例如,对于每天可能新增数百万条文档的索引,可能需要设置较多的主分片。
    • 硬件资源:包括服务器的内存、CPU 和磁盘 I/O 能力。较多的主分片会占用更多的内存和 CPU 资源,因此需要根据硬件资源来合理设置主分片数量。
    • 查询模式:如果查询主要是全索引扫描,较少的主分片可能更有利,因为可以减少分片间的合并操作;如果查询主要是基于特定字段的检索,较多的主分片可以提高并行处理能力。
  2. 代码示例 创建索引时设置主分片数量为 5:
PUT /my_index
{
    "settings": {
        "index": {
            "number_of_shards": 5,
            "number_of_replicas": 1
        }
    }
}

副本分片数量的调整

副本分片主要用于提高数据的可用性和读性能。增加副本分片数量可以提高系统的容错能力,当某个主分片或节点出现故障时,副本分片可以接替工作。同时,副本分片也可以分担读请求,提高读性能。

  1. 调整时机
    • 提高读性能:当读请求压力较大时,可以适当增加副本分片数量。例如,在一个以查询为主的应用场景中,随着用户查询量的增加,可以逐步增加副本分片来提升查询响应速度。
    • 增强高可用性:如果系统对数据的可用性要求极高,如金融交易系统,应确保有足够的副本分片,以防止数据丢失。
  2. 动态调整副本分片数量 可以使用以下 API 动态调整副本分片数量:
PUT /my_index/_settings
{
    "index": {
        "number_of_replicas": 3
    }
}

这个操作会将 my_index 索引的副本分片数量调整为 3。

存储相关参数的优化

存储编解码器的选择

ElasticSearch 支持多种存储编解码器,如 defaultbest_compressionbest_speed

  1. default 编解码器:这是默认的编解码器,在压缩率和读写性能之间提供了较好的平衡。它适用于大多数场景,不需要特别强调压缩率或读写速度的情况。

  2. best_compression 编解码器:这种编解码器侧重于压缩率,能够最大限度地减少磁盘空间占用。但由于压缩和解压缩的计算开销较大,会导致读写性能有所下降。适用于存储大量历史数据或对磁盘空间非常敏感的场景,如日志存储。

  3. best_speed 编解码器:该编解码器优先考虑读写速度,压缩率相对较低。适用于对读写性能要求极高,而对磁盘空间不太敏感的场景,如实时数据分析。

  4. 代码示例 创建索引时选择 best_compression 编解码器:

PUT /my_index
{
    "settings": {
        "index": {
            "codec": "best_compression"
        }
    }
}

磁盘存储类型与参数

  1. 磁盘类型:ElasticSearch 可以使用不同类型的磁盘,如机械硬盘(HDD)和固态硬盘(SSD)。SSD 具有更快的读写速度,适合对性能要求较高的场景,但成本相对较高;HDD 成本较低,适合存储大量不太频繁访问的数据。
  2. 存储路径设置:可以通过 path.data 参数指定 ElasticSearch 的数据存储路径。如果服务器有多个磁盘,可以将数据分散存储在不同的磁盘上,以提高 I/O 性能。例如:
path.data: /data1,/data2

这样可以将数据分布在 /data1/data2 两个路径下,提高磁盘 I/O 的并行性。

索引生命周期管理参数的配置

索引滚动(Index Rollover)

索引滚动是 ElasticSearch 中管理索引生命周期的重要功能。它允许在索引达到一定条件(如文档数量、大小或时间)时,自动创建新的索引,并将数据写入新索引。

  1. 设置索引滚动参数
    • index.lifecycle.name:指定索引生命周期策略的名称。
    • index.lifecycle.rollover_alias:指定用于索引滚动的别名。所有与该别名相关的操作(如写入数据)会自动切换到最新的索引。
  2. 代码示例 首先,创建一个索引模板:
PUT _index_template/my_template
{
    "index_patterns": ["my_index*"],
    "template": {
        "settings": {
            "index": {
                "lifecycle": {
                    "name": "my_policy",
                    "rollover_alias": "my_write_alias"
                },
                "number_of_shards": 5,
                "number_of_replicas": 1
            }
        }
    }
}

然后,创建一个索引生命周期策略:

PUT _ilm/policy/my_policy
{
    "policy": {
        "phases": {
            "hot": {
                "actions": {
                    "rollover": {
                        "max_size": "50gb",
                        "max_docs": 10000000
                    }
                }
            }
        }
    }
}

my_index 索引的数据量达到 50GB 或文档数量达到 10000000 时,会自动滚动创建新的索引。

索引删除策略

除了索引滚动,还可以设置索引删除策略,以清理不再需要的历史索引。

  1. 基于时间的删除策略:可以通过 index.lifecycle.policy.delete.min_age 参数设置索引在满足一定年龄(如 30 天)后自动删除。
  2. 代码示例 在索引生命周期策略中添加删除阶段:
PUT _ilm/policy/my_policy
{
    "policy": {
        "phases": {
            "hot": {
                "actions": {
                    "rollover": {
                        "max_size": "50gb",
                        "max_docs": 10000000
                    }
                }
            },
            "delete": {
                "min_age": "30d",
                "actions": {
                    "delete": {}
                }
            }
        }
    }
}

这样,当索引达到 30 天的年龄时,会自动被删除。

分析器相关参数调整

分析器的作用

分析器在 ElasticSearch 中用于将文本转换为适合索引和搜索的 tokens。它由字符过滤器(character filters)、分词器(tokenizer)和词元过滤器(token filters)组成。正确选择和配置分析器对于提高搜索的准确性和相关性至关重要。

内置分析器

  1. 标准分析器(Standard Analyzer):这是 ElasticSearch 的默认分析器。它按词边界(如空格、标点符号)将文本分词,并将所有词转换为小写。适用于大多数语言的通用文本处理。
  2. 简单分析器(Simple Analyzer):简单分析器按非字母字符分词,并将所有词转换为小写。它适用于处理简单文本,如英文短文。
  3. 空格分析器(Whitespace Analyzer):该分析器按空格分词,不进行任何字符转换。适用于需要按空格精确分词的场景,如代码片段分析。
  4. 语言分析器(Language Analyzers):ElasticSearch 提供了多种语言特定的分析器,如 englishchinese 等。这些分析器针对特定语言的语法和词汇特点进行优化,能更好地处理该语言的文本。

自定义分析器

在某些情况下,内置分析器不能满足需求,需要创建自定义分析器。

  1. 创建自定义分析器的步骤
    • 定义字符过滤器:可以选择 ElasticSearch 提供的字符过滤器,如 html_strip 用于去除 HTML 标签。
    • 选择分词器:如 standard 分词器、keyword 分词器等。keyword 分词器将整个文本作为一个词元,不进行分词。
    • 定义词元过滤器:例如 stop 过滤器用于去除停用词(如 “the”、“and” 等),stemmer 过滤器用于词干提取。
  2. 代码示例 创建一个自定义分析器,用于处理包含 HTML 标签的英文文本:
PUT /my_index
{
    "settings": {
        "analysis": {
            "analyzer": {
                "my_custom_analyzer": {
                    "type": "custom",
                    "char_filter": ["html_strip"],
                    "tokenizer": "standard",
                    "filter": ["lowercase", "stop", "english_stemmer"]
                }
            }
        }
    }
}

在这个自定义分析器中,首先使用 html_strip 字符过滤器去除 HTML 标签,然后使用 standard 分词器分词,接着通过 lowercase 过滤器将所有词转换为小写,stop 过滤器去除停用词,最后使用 english_stemmer 过滤器进行词干提取。

字段映射参数调整

字段映射的概念

字段映射定义了 ElasticSearch 如何索引和存储文档中的字段。它决定了字段的数据类型(如 textkeywordnumber 等),以及字段的索引方式、是否存储等属性。

常见字段类型及参数

  1. text 类型:用于存储全文本数据,如文章内容、评论等。text 类型的字段会经过分析器处理,将文本转换为 tokens 进行索引。可以通过 analyzer 参数指定使用的分析器。例如:
PUT /my_index
{
    "mappings": {
        "properties": {
            "content": {
                "type": "text",
                "analyzer": "my_custom_analyzer"
            }
        }
    }
}
  1. keyword 类型:用于存储精确值,如 ID、标签等。keyword 类型的字段不会经过分析器处理,而是直接将整个值作为一个词元进行索引。适合用于过滤、排序和聚合操作。例如:
PUT /my_index
{
    "mappings": {
        "properties": {
            "product_id": {
                "type": "keyword"
            }
        }
    }
}
  1. number 类型:包括 byteshortintegerlongfloatdouble 等具体类型,用于存储数值数据。可以通过 index 参数控制是否对该字段进行索引,通过 store 参数控制是否存储该字段的值。例如:
PUT /my_index
{
    "mappings": {
        "properties": {
            "price": {
                "type": "float",
                "index": true,
                "store": true
            }
        }
    }
}

多字段映射

在某些情况下,一个字段可能需要以不同的方式进行索引和搜索。例如,一个字符串字段既需要进行全文本搜索,又需要进行精确匹配。这时可以使用多字段映射。

  1. 代码示例
PUT /my_index
{
    "mappings": {
        "properties": {
            "product_name": {
                "type": "text",
                "fields": {
                    "keyword": {
                        "type": "keyword"
                    }
                }
            }
        }
    }
}

在这个例子中,product_name 字段既是 text 类型,用于全文本搜索,又有一个 keyword 子字段,用于精确匹配。

性能相关参数优化

内存相关参数

  1. 堆内存设置:ElasticSearch 使用 Java 堆内存来存储索引数据和缓存查询结果。合理设置堆内存大小对于性能至关重要。一般建议将堆内存设置为服务器物理内存的一半,但不要超过 32GB。可以通过 ES_HEAP_SIZE 环境变量来设置堆内存大小,例如:
export ES_HEAP_SIZE=16g
  1. 字段数据缓存(Field Data Cache):字段数据缓存用于存储用于排序、聚合和脚本计算的字段值。可以通过 indices.fielddata.cache.size 参数设置缓存大小,例如:
PUT _cluster/settings
{
    "persistent": {
        "indices.fielddata.cache.size": "30%"
    }
}

这个设置表示将字段数据缓存大小设置为堆内存的 30%。

线程池参数

  1. 索引线程池(Indexing Thread Pool):用于处理索引请求。可以通过 index.indexing.thread_pool.sizeindex.indexing.thread_pool.queue_size 参数分别设置线程池的大小和队列大小。例如:
PUT /my_index/_settings
{
    "index": {
        "indexing": {
            "thread_pool": {
                "size": 8,
                "queue_size": 100
            }
        }
    }
}

这里设置索引线程池大小为 8,队列大小为 100。 2. 搜索线程池(Search Thread Pool):用于处理搜索请求。类似地,可以通过 index.search.thread_pool.sizeindex.search.thread_pool.queue_size 参数进行设置。

安全性相关参数调整

身份验证与授权参数

  1. 基本身份验证:可以通过 xpack.security.authc.realms 参数配置基本身份验证领域。例如,配置一个文件领域:
xpack.security.authc.realms:
  my_file_realm:
    type: file
    order: 0
  1. 角色与权限管理:通过 xpack.security.role_mapping 参数定义角色映射,将用户或组映射到特定的角色。例如:
xpack.security.role_mapping:
  my_role_mapping:
    roles: ["my_role"]
    users: ["user1", "user2"]

传输层安全(TLS)参数

  1. 启用 TLS:在 elasticsearch.yml 文件中,可以通过以下配置启用传输层 TLS:
xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.verification_mode: certificate
xpack.security.transport.ssl.keystore.path: /path/to/keystore
xpack.security.transport.ssl.truststore.path: /path/to/truststore
  1. 配置证书:需要为 ElasticSearch 节点配置有效的 SSL 证书,以确保通信的安全性。证书可以通过 xpack.security.transport.ssl.keystore.secure_passwordxpack.security.transport.ssl.truststore.secure_password 参数设置密码。

通过对上述各种 ElasticSearch 索引设置参数的深入理解和合理调整,可以优化 ElasticSearch 的性能、功能、安全性等方面,使其更好地满足不同应用场景的需求。在实际应用中,需要根据具体的业务需求、数据规模和硬件资源等因素进行综合考虑和测试,以找到最适合的参数配置。