type
status
date
urlname
summary
tags
category
icon
password
catalog
sort
💡
在Elasticsearch中Mapping Index是一个核心概念,它定义了索引中数据的结构,包括字段的名称、类型、属性等。用于定义索引中文档及其字段如何被存储和索引的过程。它类似于传统关系型数据库中的表结构定义。在 MySQL 中,表结构里包含了字段名称,字段的类型还有索引信息等。在 Mapping 里也包含了一些属性,比如字段名称、类型、字段使用的分词器、是否评分、是否创建索引等属性。
作用‌:
  • 定义索引下的字段名(Field Name)。
  • 定义字段的类型,如文本型(text)、关键字型(keyword)、数字型(integer、long、float、double等)等。
  • 定义字段的索引相关配置,如是否索引、是否记录位置信息等。
 

Mapping的组成

  • Properties‌:Mapping的核心部分,包含了索引中所有字段的定义。每个字段都可以指定其类型、索引方式、是否存储等属性 此部分内容我们将在下文详细解刨。
  • Dynamic Mapping‌:Elasticsearch还支持动态映射,即在不预先定义Mapping的情况下,根据文档的内容自动推断字段的类型和属性。然而,在生产环境中,为了避免潜在的问题,通常建议预先定义Mapping。
notion image
 

Index(索引)

  • 定义‌:在Elasticsearch中,索引是存储和组织文档(Document)的逻辑容器,类似于传统关系型数据库中的数据库(Database)或表(Table)的概念。每个索引都有一个唯一的名称,用于在Elasticsearch集群中标识和访问该索引。
  • 组成‌:索引由一个或多个分片(Shard)组成,每个分片都是一个完整的Lucene索引,包含自己的倒排索引和文档存储。分片可以在不同的节点上存储,以实现数据的水平扩展和负载均衡。
  • 作用‌:
    • 数据存储‌:索引是Elasticsearch中数据存储的基本单位。
    • 搜索和查询‌:索引支持快速的数据搜索和查询,通过倒排索引技术实现高效的文本搜索。
    • 数据聚合‌:索引还支持数据聚合操作,如计算平均值、求和、计数、分组等。
  • 配置参数‌:
    • number_of_shards:分片数量,在索引创建时指定,后续只能通过复杂操作(如Reindex)修改。
    • number_of_replicas:副本数量,用于提高数据的可用性和容错性,可以在索引创建后修改。

Store(存储)

  • 定义‌:在Elasticsearch中,store参数通常与字段的存储方式相关,特别是在Mapping定义中。它决定了字段的原始值是否应该与索引一起存储。
  • 作用‌:
    • 控制字段的原始值是否存储在Elasticsearch中。
    • 影响数据的检索效率和磁盘空间使用。
  • 配置‌:
    • 在Mapping定义中,可以为每个字段设置store: truestore: false。默认为false,即不存储原始值。
    • 如果设置为true,则可以在不执行查询的情况下直接检索字段的原始值。但需要注意的是,这会增加存储空间的消耗。
 
 
 
 

动态映射:Dynamic Mapping

Elasticsearch还支持动态映射,即在不预先定义Mapping的情况下,根据文档的内容自动推断字段的类型和属性。然而,在生产环境中,为了避免潜在的问题,通常建议预先定义Mapping。
💡
关系型数据库: 先创建表 => 指定字段和字段类型 => 数据写入表
在 ES 中,索引就相当于表,文档就相当于记录,文档里面的字段就相当于表的字段,字段同样有数据类型。mapping 就用来定义文档有哪些字段,这些字段如何存储和索引。
ES 与关系型数据库不同之处在于: 其不需要先定义表结构,而可以根据写入文档的内容,来推断字段和数据类型,创建索引结构,这就是 dynamic mapping,动态映射的由来。这提供了极大的灵活性。
注:一个索引的字段数量有上限的,超过上限就会报错(默认单个索引创建最大 1000 个字段)
dynamic 参数设置:
按 dynamic 值,可分为下面三种模式
动态模式(dynamic:true),根据输入文档的内容,自动推断字段和类型,创建 mapping
非动态模式(dynamic:false),无法根据输入文档的内容,自动创建 mapping,需要手动创建 mapping
严格模式(dynamic:strict),同非动态模式,区别在于,非动态模式,输入的文档中如果有字段不在 mapping 中,依然可以存储和读取,但是该字段不在 mapping 中,因此也无法根据该字段进行检索;但严格模式,无法存储,会直接报错,严格模式实际上就类似于关系型数据库中的表了。
在动态模式下,ES 会根据插入的数据自动生成对应的字段类型,也可以通过动态模板(dynamic template)来覆盖这个规则,实现自定义推测规则,具体可以参考 ES官网 Dynamic-templates
自动映射关系如下:
field type
dynamic
true/false
boolean
小数
float
数字
long
object
object
数组
取决于数组中的第一个非空元素的类型
日期格式字符串
date
数字类型字符串
float/long
其他字符串
text + keyword
除了上述字段类型之外,其他类型都必须显式映射,也就是必须手工指定,因为其他类型ES无法自动识别。
这里有几点需要注意:
  • 数据类型识别:Elasticsearch会按照以下顺序判断数据类型:长整数、浮点数、布尔值、日期、字符串(字符串可能会进一步映射为text或keyword)。
  • 字段名称含义:Elasticsearch不会考虑字段名称的含义,它仅仅依靠字段的数据类型来生成mapping。
  • 关闭动态映射:如果你不希望Elasticsearch自动创建mapping,可以将index的dynamic设置为false
  • 动态模板:你可以使用动态模板来改变默认的mapping规则,例如,你可以将所有看起来像日期的字符串都映射为date类型。
  • 对象和嵌套字段:对于对象(object)和嵌套字段(nested),Elasticsearch也会递归地应用动态映射规则。
  • 更新映射:请注意,一旦字段的映射被创建,就不能再修改字段的数据类型了。因此,如果你要索引的文档中有新的字段,最好事先定义好mapping,避免让Elasticsearch自动映射可能产生不符合你期望的结果。
  • 当一个字段第一次出现时,Elasticsearch会使用先行数据类型来设置映射。如果后续数据类型与先前设置的映射类型不一致,Elasticsearch可能无法正确索引这些文档。
总的来说,虽然动态字段映射可以在某些情况下提供便利,但它也可能导致未预见的问题。因此,更推荐在开始索引文档之前就定义好mapping。
 

显式映射:Expllcit Field Mapping

在 Elasticsearch 中,显式映射(Explicit Field Mapping)是指为索引预定义的字段类型和行为。当你创建一个索引时,你可以定义每个字段的数据类型、分词器或者其他相关的配置。这就是显式映射。
以下是一些主要的显式映射类型:
  • 核心数据类型:包括 string(字符串)、integer(整型)、long(长整型)、double(双精度浮点型)、boolean(布尔型)等。
  • 复合数据类型:包括 object(对象),用于单个 JSON 对象,nested,用于 JSON 数组。
  • 地理数据类型:如 geo_point 和 geo_shape。
  • 专门用途的数据类型:例如 IP、自动完成、token count、join types 等。
通过显式映射,Elasticsearch 可以更准确地解析和索引数据,对查询性能优化起到关键作用。如果不提供显式映射,Elasticsearch 将会根据输入数据自动推断并生成隐式映射,但可能无法达到最理想的效果。
以下是一个示例,展示了怎么设置一个简单的显式映射:
PUT my_index
上述代码中,我们在 my_index 索引中定义了两个字段的映射,name 字段类型为 textage 字段类型为 integer
注意:在 Elasticsearch 7.0 之后,映射类型被废弃,所有的映射参数直接放在 "properties" 下。

映射参数

在Elasticsearch中,映射参数是用于定义如何处理文档和其包含的字段的规则。
主要参数有下:
  • index:是否对当前字段创建倒排索引,默认 true,如果不创建索引,该字段不会通过索引被搜索到,但是仍然会在 source 元数据中展示。
  • analyzer:指定分析器(character filter、tokenizer、Token filters)。
  • boost:对当前字段相关度的评分权重,默认1。
  • coerce:是否允许强制类型转换,为 true的话 “1”能被转为 1, false则转不了。虽然这个参数可以帮助我们强制类型转换,但是它可能会在数据质量管理中引起问题。如果原始数据包含错误的类型,使用 "coerce" 可能会隐藏这些问题,而不是将其暴露出来。
  • copy_to:该参数允许将多个字段的值复制到组字段中,然后可以将其作为单个字段进行查询。
  • doc_values:为了提升排序和聚合效率,默认true,如果确定不需要对字段进行排序或聚合,也不需要通过脚本访问字段值,则可以禁用doc值以节省磁盘空间,对于text字段和annotated_text字段,无法禁用此选项,因为这些字段类型在默认情况下不使用doc values。
  • dynamic:控制是否可以动态添加新字段
    • true :新检测到的字段将添加到映射中(默认)。
    • false :新检测到的字段将被忽略。这些字段将不会被索引,因此将无法搜索,但仍会出现在_source返回的匹配项中。这些字段不会添加到映射中,必须显式添加新字段。
    • strict :如果检测到新字段,则会引发异常并拒绝文档。必须将新字段显式添加到映射。
  • eager_global_ordinals:用于聚合的字段上,优化聚合性能,但不适用于 Frozen indices。
    • Frozen indices(冻结索引):有些索引使用率很高,会被保存在内存中,有些使用率特别低,宁愿在使用的时候重新创建,在使用完毕后丢弃数据,Frozen indices 的数据命中频率小,不适用于高搜索负载,数据不会被保存在内存中,堆空间占用比普通索引少得多,Frozen indices是只读的,请求可能是秒级或者分钟级。
  • enable:是否创建倒排索引,可以对字段操作,也可以对索引操作,如果不创建索引,仍然可以检索并在_source元数据中展示,谨慎使用,该状态无法修改。enable的作用和index类似,区别就是enable可以对全局进行设置。例如:
  • fielddata:查询时内存数据结构,在首次用当前字段聚合、排序或者在脚本中使用时,需要字段为fielddata数据结构,并且创建倒排索引保存到堆中。
  • fields:给field创建多字段,用于不同目的(全文检索或者聚合分析排序)。
  • format:格式化。例如:
  • ignore_above:这是一个针对keyword类型字段的设置,对于超过指定长度的字符串,ES 不会对其建立索引。
  • ignore_malformed:忽略类型错误。
  • index_options:控制将哪些信息添加到反向索引中以进行搜索和突出显示。仅用于text字段。
  • Index_phrases:提升 exact_value 查询速度,但是要消耗更多磁盘空间。
  • Index_prefixes:前缀搜索。
    • min_chars:前缀最小长度> 0,默认 2(包含)。
    • max_chars:前缀最大长度< 20,默认 5(包含)。
  • meta:附加元数据。
  • normalizer:normalizer 参数用于解析前(索引或者查询时)的标准化配置。
  • norms:是否禁用评分(在 filter 和聚合字段上应该禁用)。
  • null_value:为 null 值设置默认值。
  • position_increment_gap:对于数组或者列表类型的字段,在进行phrase query或者phrase suggest时,允许用户自定义同一字段内两个相邻元素间的位置增量,默认100。
  • properties:除了mapping还可用于object的属性设置。
  • search_analyzer:设置单独的查询时分析器,如果定义了analyzer而没有定义search_analyzer,则search_analyzer的值默认会和analyzer保持一致,如果两个都没有定义,则默认是:"standard"。analyzer针对的是元数据,而search_analyzer针对的是传入的搜索词。
  • similarity:为字段设置相关度算法,和评分有关。支持BM25、classic(TF-IDF)、boolean。
  • store:设置字段是否仅查询。
  • term_vector:运维参数。这个参数可以设置存储哪些信息用于更复杂的文本处理,例如在词向量建模或者更复杂的文本检索场景中使用。
 

更新与限制

  • 更新‌:由于Lucene实现的倒排索引生成后不允许修改,因此Mapping中字段的类型一旦设定后,禁止直接修改。如果需要修改Mapping,通常需要重新建立新的索引,并将旧索引的数据迁移到新索引中。
  • 限制‌:Elasticsearch对索引中的字段数量和字段名长度有一定的限制。例如,单个文档中所有嵌套类型的最大嵌套JSON对象数默认为10000,字段名的最大长度默认为无限制(但可以通过设置进行调整)。
 

高级特性

  • 自定义分词器‌:在Mapping中,可以为文本型字段指定自定义的分词器,以实现更复杂的文本处理需求。
  • 多字段(Multi-fields)‌:允许为单个字段定义多个索引方式,以满足不同的搜索需求。
  • 元数据字段‌:Elasticsearch还包含一些内置的元数据字段,如_id_index_type(在ES 7.x及更高版本中已弃用)等,这些字段在Mapping中不需要显式定义。
 
 

Properties

 
Properties是Mapping定义的核心部分,它详细描述了索引中各个字段的数据类型、索引方式、存储方式等属性。以下是Properties中各种组成的详细讲解,我将分点表示并归纳相关信息:

1. 字段名称(Field Name)

  • 定义‌:字段名称是索引中文档数据的唯一标识符。
  • 作用‌:用于在查询、聚合等操作中引用字段。

2. 字段类型(Field Type)

常见类型‌:
  • text‌:用于全文搜索的文本字段,如博客内容、新闻标题等。支持分词器进行文本分析。
  • keyword‌:用于精确值搜索的字段,如标签、邮箱地址等。不进行分词,直接存储原始值。
  • 数值类型‌(如integer、long、float、double等):用于存储数值数据,支持范围查询和排序。
  • 日期类型‌(date):用于存储日期和时间,支持日期范围查询和格式化。
  • 复合类型‌(如object、nested):用于存储嵌套对象或数组,支持复杂的文档结构。
  • 地理类型‌(如geo_point):用于存储地理位置信息,支持地理空间查询。
  • 作用‌:字段类型决定了字段的存储方式、索引方式以及查询能力。
映射的数据类型也就是 Elasticsearch 索引支持的数据类型,其概念和 MySQL 中的字段类型相似,但是具体的类型和 MySQL 中有所区别,最主要的区别就在于 ES 中支持可分词的数据类型,如:Text 类型,可分词类型是用以支持全文检索的,这也是 ES 生态最核心的功能。
 

3. 索引属性(Indexing Properties)

  • index‌:控制字段是否应该被索引。如果设置为false,则字段内容不会被索引,无法被搜索。
  • analyzer‌:为text类型的字段指定分词器,用于在索引和搜索时对文本进行分词处理。
  • search_analyzer‌:在搜索时使用的分词器,可以与索引时使用的分词器不同,以实现更灵活的搜索需求。
  • 作用‌:索引属性决定了字段的索引方式,影响搜索的准确性和性能。

4. 存储属性(Storing Properties)

  • store‌:控制字段的原始值是否应该与索引一起存储。默认为false,即不存储原始值。如果设置为true,则可以在不执行查询的情况下直接检索字段的原始值。
  • 作用‌:存储属性用于控制字段原始值的存储方式,影响数据的检索效率和磁盘空间使用。

5. 其他属性

  • null_value‌:为可能为null的字段指定一个默认值,以便在查询时能够正确处理null值。
  • ignore_above‌:对于text和keyword类型的字段,可以指定一个长度阈值。如果字段值的长度超过该阈值,则忽略该字段值,不进行索引。
  • coerce‌:对于数值类型的字段,控制是否应该尝试将非数值类型的值转换为数值类型。
  • 作用‌:这些属性提供了额外的灵活性和控制力,用于处理特殊的数据场景和需求。
 
Properties在Elasticsearch的Mapping定义中扮演着至关重要的角色,它详细描述了索引中各个字段的数据类型、索引方式、存储方式等属性。通过合理设置Properties中的各项参数,可以优化索引的存储结构、提高搜索的准确性和性能,从而满足各种复杂的数据搜索和分析需求。
 
 

字段类型(Field Type)

数字类型

  • long:64 位有符号整形。
  • short:16 位有符号整形。
  • byte:8位有符号整形。
  • double:双精度64位浮点类型。
  • float:单精度32位浮点类型。
  • scaled_float:缩放类型浮点数,按固定 double 比例因子缩放。
  • unsigned_long:无符号 64 位整数。

基本数据类型

  • binary:存储二进制字符串,经过Base64编码处理。
  • boolean:布尔类型,接收 ture 和 false 两个值。

Keywords 类型

  • keyword:这种类型被用来索引结构化数据,如 email 地址、主机名、状态码以及标签等。这类数据可以以精确值的形式进行搜索,并且可以用于过滤 (filtering),排序 (sorting) 和聚合 (aggregating)。关键词字段只和其确切的值匹配,它们的查询不会进行分词处理。
  • constant_keyword:这种类型适用于在所有文档中都始终有相同值的字段。比如在一次特定的索引操作中,所有的文档都需要包含一个常量字段,例如 env 的值可能为 "production"。
  • wildcard:这种类型的字段可以存储任何字符串,并且对于这种类型的字段进行的查询可以使用通配符表达式。这种类型的字段对于像 grep 这样的场景非常有用,即当你需要在一个长字符串中搜索一个较短的子串时。但是要注意,虽然 wildcard 字段提供了强大的模式匹配能力,但是这种能力是需要付出性能代价的。
Keyword 类型适用于不分词的字段,如姓名、Id、数字等。如果数字类型不用于范围查找,用 Keyword 的性能要高于数值类型。
当使用 Keyword 类型查询时,其字段值会被作为一个整体,并保留字段值的原始属性。
💡
注意事项
  • Keyword 不会对文本分词,会保留字段的原有属性,包括大小写等。
  • Keyword 仅仅是字段类型,而不会对搜索词产生任何影响。
  • Keyword 一般用于需要精确查找的字段,或者聚合排序字段。
  • Keyword 通常和 Term 搜索一起用。
  • Keyword 字段的 ignore_above 参数代表其截断长度,默认 256,如果超出长度,字段值会被忽略,而不是截断,忽略指的是会忽略这个字段的索引,搜索不到,但数据还是存在的。

日期类型

JSON 没有日期数据类型,因此 Elasticsearch 中的日期可以是以下三种:
  • 包含格式化日期的字符串:例如 "2024-10-19"、 "2024/10/19 16:10:30"。
  • 时间戳:表示自"1970年 1 月 1 日"以来的毫秒数/秒数。
  • date_nanos:此数据类型是对 date 类型的补充。但是有一个重要区别。date 类型存储最高精度为毫秒,而date_nanos 类型存储日期最高精度是纳秒,但是高精度意味着可存储的日期范围小,即:从大约 1970 到 2262。

对象类型

  • object:默认情况下,Elasticsearch 使用 object 数据类型来处理 JSON 对象。
  • flattened:这是用来索引对象数组或者具有未知结构的字段的特殊映射类型。其将整个JSON对象作为单个键值对存储,帮助降低索引大小和提高搜索速度。
  • nested:这是一个类似于 object 的数据类型,但它能保存并查询对象数组内部对象的独立性,因此可以用来处理更复杂的结构。
  • join:这是一个特殊数据类型,用于模拟在文档之间的父/子关系。这样可以创建一对多的连接,例如,在博客文章和评论这样的场景中使用。

空间数据类型

  • geo_point:表示地理位置的点,存储纬度和经度信息。
  • geo_shape:表示复杂的地理形状,如多边形、线、圆等。
  • shape:在笛卡尔空间中表示任意复杂的几何形状。

文档排名类型

  • dense_vector:记录浮点值的密集向量。这种类型常用于存储机器学习模型的输出,例如词嵌入、句子嵌入等。
  • rank_feature:记录单个数值特征以优化排名。当这个字段被查询时,Elasticsearch 会考虑其值来重新排序搜索结果。
  • rank_features:记录多个数值特征以优化排名。与rank_feature类似,但它能够处理包含多个特征的对象。当这些字段被查询时,Elasticsearch 会考虑它们的值来重新排序搜索结果。

文本搜索类(Text)

  • text:用于存储全文和进行全文搜索的数据类型。
  • annotated-text:这是一个特殊的文本字段,它支持包含标记的文本。这些标记表示文本中的命名实体或其他重要项,可以在后续搜索中使用。
  • completion :这是一个专门为自动补全和搜索建议设计的数据类型。
  • search_as_you_type: 这是一种特殊的文本字段,它被优化以提供按键查询时的即时反馈,从而提高用户输入时的搜索体验。
  • token_count:这是一种数值型字段,用于存储文本字段中的词元数量。此字段常用于信息检索场景,比如评估某个字段的长度。
当一个字段是要被全文检索时,比如 Email 内容、产品描述,这些字段应该使用 text 类型。设置 text 类型以后,字段内容会被分析,在生成倒排索引之前,字符串会被分析器分成一个个词项。text类型的字段不用于排序,很少用于聚合。
💡
注意事项
  • 适用于全文检索:如 match 查询。
  • 文本字段会被分词。
  • 默认情况下,会创建倒排索引。
  • 自动映射器会为 Text 类型创建 Keyword 字段。
 

Analyzer(分析器)

Analyzer是Elasticsearch中用于文本分析与处理的工具。它接收原始文本输入,按照特定的算法和规则将其转换为一系列可搜索的词项(Tokens),并存储在Elasticsearch的倒排索引中。这些词项是后续搜索和查询的基础

组成

Analyzer主要由三个部分组成:
  • Character Filters(字符过滤器)‌:接收原始文本,进行字符级别的预处理操作,如去除HTML标签、特殊字符替换等。Analyzer中可以包含零个或多个字符过滤器。
  • Tokenizer(分词器)‌:接收经过字符过滤器处理的文本,将其分割成一系列词项。Analyzer中只能有一个分词器。
  • Token Filters(分词过滤器)‌:接收分词器输出的词项列表,进行进一步的处理,如大小写转换、停用词过滤、同义词添加等。Analyzer中可以包含零个或多个分词过滤器。

类型

Elasticsearch提供了多种类型的Analyzer,以满足不同的文本处理需求:
  • Built-in Analyzer(内置分析器)‌:
    • Standard Analyzer‌:默认分析器,按词边界分割文本,删除标点符号,将大写转为小写。
    • Simple Analyzer‌:按非字母字符分割文本,将大写转为小写。
    • Whitespace Analyzer‌:仅按空白字符分割文本,不删除标点符号,不转换大小写。
    • Stop Analyzer‌:与Simple Analyzer类似,但可以删除停用词。
    • Keyword Analyzer‌:将整个文本视为一个词项,不进行分割。
    • Pattern Analyzer‌:根据正则表达式分割文本。
    • Language Analyzer‌:针对特定语言的分析器,如English Analyzer、French Analyzer等。
  • Custom Analyzer(自定义分析器)‌:当内置分析器无法满足需求时,可以创建自定义分析器。通过组合不同的字符过滤器、分词器和分词过滤器来实现特定的文本处理逻辑。

配置和使用

Analyzer的配置可以在创建索引时通过Mapping进行指定,也可以在查询时通过_analyze API进行临时指定。配置Analyzer时,需要指定其包含的字符过滤器、分词器和分词过滤器的名称及顺序。
例如,在创建索引时配置Custom Analyzer的示例如下:
在上述示例中,我们创建了一个名为my_custom_analyzer的自定义分析器,它使用standard分词器,并包含了一个自定义的分词过滤器my_custom_filter,该过滤器用于删除指定的停用词。然后,我们将这个自定义分析器应用到了my_text_field字段上。

总结

Analyzer是Elasticsearch中实现文本分析和处理的关键组件,它通过字符过滤器、分词器和分词过滤器的组合,将原始文本转换为可搜索的词项,并存储在倒排索引中。Elasticsearch提供了多种内置分析器和自定义分析器的支持,以满足不同的文本处理需求。合理配置和使用Analyzer,可以显著提高搜索的准确性和效率。
 

Index Settings (索引设置)

在Elasticsearch中,创建索引时的settings配置是定义索引行为和性能的关键参数。这些设置可以分为静态设置和动态设置,静态设置只能在索引创建时或在索引关闭状态下进行修改,而动态设置则可以在索引运行时通过API进行修改。下面是对settings中一些重要配置的详细分析与讲解:

静态设置

  1. index.number_of_shards
      • 定义‌:索引的主分片数。
      • 默认值‌:5
      • 最大值‌:1024
      • 说明‌:分片是Elasticsearch分布式存储和搜索的基础,一旦索引创建,分片数不能更改(除非重新索引)。
  1. index.number_of_replicas
      • 定义‌:每个主分片的副本数。
      • 默认值‌:1
      • 说明‌:副本用于提高数据的可用性和容错性。副本数可以在索引创建后通过API进行修改。
  1. index.codec
      • 定义‌:数据压缩算法。
      • 可选值‌:default(默认,使用LZ4压缩)、best_compression(更高的压缩比,但会降低存储性能)。
      • 说明‌:压缩算法影响索引的存储空间和查询性能。
  1. index.auto_expand_replicas
      • 定义‌:基于可用节点的数量自动分配副本数量。
      • 默认值‌:false
      • 说明‌:当设置为true时,Elasticsearch会根据集群中节点的数量自动调整副本数。
  1. index.refresh_interval
      • 定义‌:执行刷新操作的频率,使索引的最近更改可以被搜索。
      • 默认值‌:1s
      • 说明‌:可以设置为1以禁用自动刷新,但这会影响新数据的可见性。
  1. index.max_result_window
      • 定义‌:索引搜索的from+size的最大值。
      • 默认值‌:10000
      • 说明‌:限制分页查询的深度,防止对集群造成过大压力。

动态设置

  1. index.blocks.read
      • 定义‌:控制对索引的读取操作是否被阻塞。
      • 可设置值‌:true(禁用读取)、false(允许读取)
      • 说明‌:在需要维护索引时,可以临时禁用读取操作。
  1. index.blocks.write
      • 定义‌:控制对索引的写入操作是否被阻塞。
      • 可设置值‌:true(禁用写入)、false(允许写入)
      • 说明‌:在索引重建或数据迁移时,可以禁用写入操作。
  1. index.number_of_replicas‌(虽然是静态设置,但可通过API动态修改)
      • 如前所述,副本数可以在索引运行时动态调整。
  1. index.routing.allocation.enable
      • 定义‌:控制索引的分片分配。
      • 可设置值‌:all(允许所有类型的分配)、primaries(仅允许主分片分配)、none(不允许任何分配)
      • 说明‌:在节点维护或扩容时,可以通过调整此设置来控制分片的分配。

其他重要设置

  • index.shard.check_on_startup‌:控制索引打开前是否检查分片损坏。
  • index.max_rescore_window‌:在搜索此索引中rescore的window_size的最大值。
  • index.store.type‌:索引数据的存储方式,如fs(文件系统)、mmapfs(内存映射存储)等。
Elasticsearch的索引settings配置非常丰富,涵盖了从数据分片、副本管理、压缩算法到读写控制等多个方面。合理配置这些参数对于优化索引性能、提高数据可用性和确保集群稳定至关重要。在实际应用中,应根据具体需求和集群状况进行灵活配置和调整。
 
 
 

增删改查时分片的交互

在上一篇文章中我们讲解了 Elasticsearch的节点分片,那么在我们实际操作索引时的分片交互是什么样的呢?
Es 如何分片保持数据一致性 es 的分片,路由文档到分片文档路由到分片上:一个索引由多个分片构成,当添加(删除、修改)一个文档时,Elasticsearch 就需要决定这个文档存储在哪个分片上,这个过程就称为数据路由(routing)。

路由文档到分片

  1. 文档路由到分片上:一个索引由多个分片构成,当添加(删除、修改)一个文档时,Elasticsearch 就需要决定这个文档存储在哪个分片上,这个过程就称为数据路由(routing)。
  1. 路由算法:
示例:一个索引,3 个 primary shard
  1. 每次增删改查时,都有一个 routing 值,默认是文档的 _id 的值。
  1. 对这个 routing 值使用 hash 函数进行计算。
  1. 计算出的值再和主分片个数取余数,余数的取值范围永远是(0 ~ number_of_primary_shards - 1)之间,文档就在对应的 shard 上。routing 值默认是文档的 _id 的值,也可以手动指定一个值,手动指定对于负载均衡以及提升批量读取的性能都有帮助。
  1. 正是这种路由机制,导致了 primary shard(主分片)的个数为什么在索引建立之后不能修改。对已有索引主分片数目的修改直接会导致路由规则出现严重问题,部分数据将无法被检索

分片如何交互

假设有三个节点的集群。它包含一个叫做 bblogs 的索引并拥有两个主分片。每个主分片有两个复制分片。相同的分片不会放在同一个节点上,所以我们的集群是这样的:
notion image
我们能够发送请求给集群中任意一个节点。每个节点都有能力处理任意请求。每个节点都知道任意文档所在的节点,所以也可以将请求转发到需要的节点。下面的例子中,我们将发送所有请求给 Node 1,这个节点我们将会称之为请求节点 (requesting node)
notion image

新建索引与删除一个文档

新建、索引和删除请求都是写 (write) 操作,它们必须在主分片上成功完成才能复制到相关的复制分片上。
notion image
  1. 客户端发送了一个索引或者删除的请求给 node 1。
  1. node 1 通过请求中文档的 _id 值判断出该文档应该被存储在 shard 0 这个分片中(node 1 知道 shard 0 的 primary shard 位于 node 3 节点上),node 1 会把这个请求转发到 node 3。
  1. node 3 在 shard 0 的 primary shard 上执行请求。如果请求执行成功,它 node 3 将并行地将该请求发给 shard 0 的其余所有 replica shard 上,也就是存在于 node 1 和 node 2 中的 replica shard。如果所有的 replica shard 都成功地执行了请求,那么将会向 node 3 回复一个成功确认,当 node 3 收到了所有 replica shard 的确认信息后,则最后向用户返回一个 Success 的消息。
客户端接收到成功响应的时候,文档的修改已经被应用于主分片和所有的复制分片。此时修改已经生效。
有很多可选的请求参数允许你更改这一过程。你可能想牺牲一些安全来提高性能。这一选项很少使用因为 Elasticsearch 已经足够快,下面将一一阐述。

replication

  • 复制默认的值是 sync(同步操作)。这将导致主分片得到复制分片的成功响应后才返回。
  • 当 replication 设置为 async(异步操作),请求在主分片上被执行后就会返回给客户端。它依旧会转发请求给复制节点,但你将不知道复制节点成功与否。
  • 该选项不建议使用。默认的 sync 复制允许 Elasticsearch 强制反馈传输。async 复制可能会因为在不等待其它分片就绪的情况下发送过多的请求而使 Elasticsearch 过载。

consistency(写一致性原理和 quorum 机制)

  • 默认主分片在尝试写入时需要 ** 规定数量 (quorum)** 或过半的分片(可以是主节点或复制节点)可用。这是防止数据被写入到错的网络分区。规定的数量计算公式如下:
  • consistency 允许的值为 one(只有一个主分片),all(所有主分片和复制分片)或者默认的 quorum 或过半分片。
  • 注意 number_of_replicas 是在索引中的的设置,用来定义复制分片的数量,而不是现在活动的复制节点的数量。如果你定义了索引有 3 个复制节点,那规定数量是:
• 但如果你只有 2 个节点,那你的活动分片不够规定数量,也就不能索引或删除任何文档。
 

timeout

当分片副本不足时会怎样?
  • Elasticsearch 会等待更多的分片出现。默认等待一分钟。如果需要,你可以设置 timeout 参数让它终止的更早:100 表示 100 毫秒,30s 表示 30 秒。
💡
注意
新索引默认有 1 个复制分片,这意味着为了满足 **quorum(规定数量)** 的要求需要两个活动的分片。当然,这个默认设置将阻止我们在单一节点集群中进行操作。为了避开这个问题,规定数量只有在 number_of_replicas 大于一时才生效。

局部更新文档

update API 结合了之前提到的读和写模式。
notion image
该过程可以分为四个阶段来描述:
  1. 客户端给 node 1 发送更新请求。
  1. 它转发请求到主分片所在节点 node 3。
  1. node 3 从主分片检索出文档,修改_source 字段的 JSON,然后在主分片上重建索引。如果有其他进程修改了文档,它以 retry_on_conflict 设置的次数重复步骤 3,都未成功则放弃。
  1. 如果 node 3 成功更新文档,它同时转发文档的新版本到 Node 1 和 Node 2 上的复制节点以重建索引。当所有复制节点报告成功,node 3 返回成功给请求节点,然后返回给客户端。
update API 还接受 新建、索引和删除 提到的 routing、replication、consistency 和 timout 参数。
基于文档的复制
当主分片转发更改给复制分片时,并不是转发更新请求,而是转发整个文档的新版本。记住这些修改转发到复制节点是异步的,它们并不能保证到达的顺序与发送相同。如果 Elasticsearch 转发的仅仅是修改请求,修改的顺序可能是错误的,那得到的就是个损坏的文档。

检索文档

文档能够从主分片或任意一个复制分片被检索。
notion image
下面我们罗列在主分片或复制分片上检索一个文档必要的顺序步骤:
  1. 客户端给 node 1 发送 get 请求,node1 节点就成了 coordinating node(协同节点),该节点使用路由算法算出文档所在的 primary shard;协调节点把请求转发给 primary shard ,也可以转发给 replica shard(使用轮询调度算法 [Round-Robin Scheduling,把请求平均分配至 primary shard 和 replica shard] ,场景在于多个相同请求进入时)。
  1. 节点使用文档的_id 确定文档属于分片 0。分片 0 对应的复制分片在三个节点上都有。此时,它转发请求到 node 2。
  1. node 2 返回文档 (document) 给 node 1 然后返回给客户端。
对于读请求,为了平衡负载,请求节点会为每个请求选择不同的分片——它会循环所有分片副本。
特殊情况:一个被索引的文档已经存在于主分片上却还没来得及同步到复制分片上。这时复制分片会报告文档未找到,主分片会成功返回文档。一旦索引请求成功返回给用户,文档则在主分片和复制分片都是可用的。
Java IO — IO/NIO模型Elasticsearch — 如何存储数据并保持一致性?
Loading...
Honesty
Honesty
人道洛阳花似锦,偏我来时不逢春
最新发布
Java IO — NIO Buffer
2024-10-21
Java IO — NIO Channel
2024-10-21
Java IO — IO/NIO模型
2024-10-21
Java异步编程方式介绍
2024-10-21
Elasticsearch — 索引(Mapping Index)
2024-10-19
Elasticsearch — 如何存储数据并保持一致性?
2024-10-19