Elasticsearch由浅入深

elasticsearch核心概念

elasticsearch与数据库的对比

elasticsearch 数据库
Document
Type
Index

elasticsearch的功能

  • 分布式的搜索引擎和数据分析引擎

  • 全文检索,数据化检索,数据分析

  • 处理海量的数据

elasticsearch对复杂的分布式机制的透明隐藏

  • 分片机制(随便一条插入document到es集群中没有care过数据如何分片的,数据到哪一个shard中)

  • cluster discovery(如果启动两个es集群进程后会自动的第二个加入第一个形成集群)

  • shard负载均衡(3个es几点,25个shard会自动分配保证负载请求)

shard和replicat机制

常见的ELK术语

  • 文档Document

  • 索引具有相同的文档列表组成

    • 一个index中只允许一个Type,在未来的版本后会把Type去掉,所以将index类比成database不合适,可以类比成Mysql中的table表
  • 节点Node
    • 一个Elasticsearch的运行实例,是集群的构成单元
  • 集群Cluster
    • 由于多个节点组成的对外提供服务ES运行实例

Document

  • JsonObject,由字段(Field)组成,常见的数据类型如下

  • 每一个文档都有一个ID唯一的标识

数据类型名称 类型
字符串 text,keyword
数据值 long,integer,short,byte,double,float,half_float,scaled_fload
布尔型 boolean
日期 date
二进制 binary
范围类 integer_range,float_range,long_range,double_range,date_range

Document MetaData

  • 元数据,用于标注文档的相关信息
数据的类型 功能介绍
_index 文档所在的索引
_type 文档所在的类型名
_id 文档的唯一ID
_uid 组合ID,由于_type和ID组成(6.x版本后_type不再起任何作用,同一个ID一样)
_source 文档的原始Json数据,可以从这里获取每一个字段的内容
_all 整合所有的字段内容到该字段,默认禁用

index

  • 索引中存储具有相同结构的文档(Document)
    • 每一个索引都拥有自己的mapping定义,用于定义字段名和类型
  • 一个集群可以有多个的索引
    • Nginx日志存储的时候可以按照日期每一天生成一个索引来存储

    • Nginx-log-time

Rest API

  • Elasticsearch集群对外提供REST API

    • REST – REpresontational State Transfer(表现层状态转移)

    • URL指定资源,如Index、Document

    • Http Method指明资源操作的类型,GET、POST、PUT、DELETE

  • 常用的交互方式

    • Curl 命令行

    • Kibana DevTools

Document API

  • es专有的Document API

    • 创建文档

    • 查询文档

    • 更新文档

    • 删除文档

创建文档

  • 指定ID创建文档api(指定ID和不指定ID的情况)

批量创建文档

  • es允许一次创建多个文档,从而减少网络传输的开销,提升写入的速率
    • endpoint为_bulk
POST _bulk
{"index":{"_index":"test_index","_type":"doc","_id":"3"}}
{"username":"ddy","age":20}
{"delete":{"_index":"test_index","_type":"doc","_id":"1"}}
{"update":{"_id":"2","_index":"test_index","_type":"doc"}}
{"doc":{"age":"20"}}

查询文档

  • 指定我们的路径和id获取文档的信息

  • 搜索所有的文档,用到_search

批量查询的文档

  • es允许一次查询多个文档
    • endpoint为_mget
GET /_mget
{"docs":[{"_index":"test_index","_type":"doc","_id":"1"},{"_index":"test_index","_type":"doc","_id":"2"}]}

目录与索引

  • 正排索引
    • 文档ID到文档内容、单词的关联关系

    • 根据文档的ID来关联相关内容

文档ID 文档的内容
1 elasticsearch是最流行的搜索引擎
2 php世界上最好的语言
3 python世界上最好的胶水语言
  • 倒排索引

    • 单词到文档ID的关联关系

什么是倒排索引?
倒排索引源于实际应用中需要根据属性的值来查找记录,这种索引表中的每一项都包括一个属性值和具有该属性的各记录的地址,由于不是由记录来决定的确定属性值,而是由于属性值来确定的记录的位置,因此称为倒排索引(inverted index),带有倒排索引的文件我们称为倒排索引文件,简称倒排文件(inverted file)

倒排索引的查询流程

  • 查询包含搜索引擎的文档
    • 通过倒排索引获得“搜索引擎”对应的文档ID

    • 通过正排索引查询对应的文档ID的完整内容

    • 返回用户最终结果

倒排索引的组成

  • 倒排索引是搜索引擎的核心
    • 单词词典(Term Dictionary)
      • 记录所有文档的单词,一般都比较大

      • 记录单词到倒排列表的关联信息

  • 倒排列表(Posting List)
    • es存储的是一个json格式的文档,其中包含了多个字段,每一个字段都会有自己的到排索引

    • 记录了单词对应的文档集合,由倒排索引项(Posting)组成

      • 文档ID,用于获取原始信息

      • 单词的频率(TF,Term Frequency),记录该单词在该文档中的出现次数,用于后续相关性算分

      • 位置(Position),记录单词在文档中的分词位置(多个),用于做词语搜索(Phrase Query)

      • 偏移(Offset),记录单词在文档的开始和结束位置,用于做高亮显示

分词器

  • 分词是指将文本转换成一系列的单词(term or token)的过程,也可以叫做文本的分析,在es里面称为Analysis

分词器是es中专门处理分词的组件,Analyzer

  • Character Filters
    • 针对原始的文本进行处理,比如去除html的特殊标记
  • Tokenizer
    • 将原始的文本按照一定的规则去切分单词
  • Token Filters
    • 针对Tokenizer处理的单词就行再次加工,如转换小写、删除或新增等处理

分词器的调用顺序

Analyzer API

  • es提供了一个测试分词的API接口,方便验证分词的效果,endpoint是_analyze
    • 可以直接指定analyzer进行测试

    • 可以直接指定索引中的字段进行测试

    • 可以自定义分词器进行测试

预定义的分词器

  • Standard Analyzer

  • simple Analyzer

  • stop

中文分词器

  • 难点
    • 中文分词指的是将一个汉子序列切分成一个个单独的词,在英文中,单词之间是以空格作为自然的分界符,汉语中词没有一个形式上的分界符

    • 上下文不同,分词结果也是迥异的,还有部分的交叉歧义

实际使用中应该使用的分词器

  • IK
    • 实现中英文单词的切分,支持ik_smart、ik_maxword这样的形式

    • 可以自定义词库、支持更新分词词典

    • https://github.com/medcl/elasticsearch-analysis-ik

  • jieba

    • python中最为流行的分词系统,支持分词和词性标注

    • 支持繁体分词、自定义词典、并行分词

    • https://github.com/sing1ee/elasticsearch-jieba-plugin

自然语言处理的分词系统

  • Hanlp
    • 由一系列模型与算法组成的JAVA工具包,目标是普及自然语言处理在生产环境中的应用

    • https://github.com/hankcs/HanLP

  • THULAC

    • THU Lexical Analyzer for Chinese,由清华大学自然语言处理与社会人文计算实验室研制推出的一套中文词法分析工具,具有中文分词器个词性标注的功能

    • https://github.com/microbun/elasticsearch-thulac-plugin

自定义分词器

当预定义分词器无法满足需求,就可以自定义分词器
通过自定义Character Filters、Tokenizer和Token Filter来实现

  • es自带的
    • HTML Strip去除html标签和转换html实体

    • Mapping 进行字符替换操作

    • Pattern Replace进行正则匹配替换

  • 会影响后续的tokenizer解析的postion和offset信息

  • Tokenizer
    • 将原始的文本按照一定的规则切分为单词(term or token)
名称 分词规则
standard 按照单词进行分割
letter 按照非字符类型进行分割
whitespace 按照空格进行分割
UAX URL Email 按照standard分割,但是不会分割邮件和url
NGram和Edge NGram 连词分割
Path Hierarchy 按照文件路径进行分割

  • tokenFilters
    • 对于tokenizer输出的单词(term)进行增加、删除、修改等

    • lowercase将所有的term转换为小写

    • stop 删除stop words

    • NGram和Edge NGram连词分割

    • Synonym添加近义词的trem

自定义分词的API

  • 例子 一

  • 例子 二

分词的使用

  • 创建或是更新文档的时候(Index Time),会对应相应的文档进行分词处理

  • 查询时候(Search Time),会对查询的语句进行分词

  • 明确字段是否需要分词,不需要分词的字段就将type设置为keyword,可以节省空间和提高性能

  • 善用_analyze API,查看文档的具体分词结果

索引时分词

  • 索引时分词时通过配置Index Mapping中的每一个字段的analyzer属性实现的
    • 不指定分词时候,使用默认standard
PUT test_index3
{
  "mappings": {
    "doc":{
      "properties": {
        "title":{
          "type": "text",
          "analyzer": "whitespace"//指定分词器
        }
      }
    }
  }
}

查询时分词

  • 查询的时候通过analyzer指定分词器

  • 通过index_mapping设置search_analyzer实现

官方的介绍地址

  • https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis.html

Mapping

  • 类似数据库中的表结构定义
    • 定义Index下的字段名(Field Name)

    • 定义字段的类型、比如数值型、字符串型、布尔型

    • 定义倒排索引相关的配置,例子:是否索引、记录position等

GET /test_index/_mapping
{
  "test_index": {
    "mappings"{
      "doc": {
        "properties": {
          "age": {
            "type": "integer"
          },
          "username": {
            "type": "keyword"
          }
        }
      }
    }
  }
}

自定义Mapping

  • Mapping中的字段类型一旦设置后,禁止直接修改

    • Lucene实现的倒排索引生成后不允许修改

    • 重新建立新的索引,然后reindex操作

PUT my_index4
{
  "mappings": { //关键词
    "doc":{ //type名称
      "properties": {
        "title":{
          "type": "text" //字段类型
        },
        "name":{
          "type": "keyword"
        },
        "age":{
          "type": "integer"
        }
      }
    }
  }
}
  • 允许新增字段

  • 通过dynamic参数来控制字段的新增

    • ture(默认)允许自动增加新的字段

    • false(禁止) 不允许自动新增加字段,但是文档可以正常写入,但是无法对字段进行查询等操作

    • strict(严格) 文档不能写入,并且报错

PUT my_index7
{
  "mappings": {
    "doc":{
      "properties": {
        "title":{
          "type": "text"
        },
        "name":{
          "type": "keyword"
        },
        "age":{
          "type": "integer"
        }
      }
    }
  }
}


GET my_index7/_mapping

DELETE my_index7

PUT my_index7/doc/1
{
  "title":"hello world",
  "desc":"erverwhere no"
}

GET my_index7/doc/_search
{
  "query":{
    "match": {
      "title": "hello"
    }
  }
}

copy_to

  • 将该字段的值复制到目标字段,实现类似_all的作用

  • 不会出现在_source中,只用来搜索

PUT my_index5
{
  "mappings": {
    "doc":{
      "properties": {
        "first_name":{
          "type": "text",
          "copy_to": "full_name"
        },
        "last_name":{
          "type": "text",
          "copy_to": "full_name"
        },
        "full_name":{
          "type": "text"
        }
      }
    }
  }
}

PUT my_index5/doc/1
{
  "first_name":"ddy",
  "last_name":"yes"
}

GET my_index5/_search
{
  "query":{
    "match": {
      "full_name": {
        "query": "ddy yes",
        "operator": "and"
      }
    }
  }
}

index_options

index

  • 控制当前字段是否索引,默认为True,记录索引,false不记录,不可搜索

  • 使用情况是在不想被查询到的index

PUT my_index5
{
  "mappings": {
    "doc":{
      "properties": {
        "first_name":{
          "type": "text",
          "copy_to": "full_name"
        },
        "last_name":{
          "type": "text",
          "index": false, //拒绝查询
          "copy_to": "full_name"
        },
        "full_name":{
          "type": "text",
          "index": false
        }
      }
    }
  }
}

index_options

用于控制倒排索引记录的内容

  • docs -> 只记录doc id

  • freqs -> 记录doc id和tem frequencies

  • posistions -> 记录doc id、term frequencies、term position

  • offsets -> 记录 doc id、term frequencies、term position、character offsets

  • text类型默认配置为positions,其他默认为docs

  • 记录内容越多,占用的空间越大

null_value

  • 当字段遇见NULL值时候处理策略,默认为null,空值,此时的es会忽略该值,可以通过设置该字段的默认值
PUT my_index6
{
  "mappings": {
    "my_type":{
      "properties": {
        "status_code":{
          "type": "keyword",
          "null_value": "NULL"
        }
      }
    }
  }
}

数据类型

  • 核心数据类型
数据类型名称 相关名
字符串型 text、keyword
数值型 long、integer、short、byte、double、float、half_float、scaled_float
日期类型 date
布尔型 boolean
二进制型 binary
范围型 integer_range、float_range、long_range、double_range、date_range
  • 复杂数据类型
数据类型名称 相关名
数组型 array
对象型 object
嵌套型 nested object
地理位置型 geo_point、geo_shape
  • 专用类型
  1. 记录IP地址 -> ip

  2. 实现自动补全 -> completion

  3. 记录分词数量 -> tken_count

  4. 记录字符串hash值 -> murmur3

  5. percolator

  6. join

Dynamic Mapping

  • es可以自动识别文档字段类型,从而降低用户使用的成本

  • es是依靠JSON文档的字段类型来实现自动识别的字段类型

Json类型 es类型
null 忽略
boolean boolean
浮点类型 float
整数 long
object object
array 由第一个非null值类型决定
string 匹配为日期则设置为date类型(默认开启)、匹配为数字的话设置为float或long(默认关闭)、设置为text,并附带keyword的子字段

日期类型识别

  • 日期的自动识别可以自行配置日志格式

PUT my_index4
{
  "mappings": {
    "my_type":{
      "numeric_detection": true
    }
  }
}

PUT my_index4/my_type/1
{
  "my_float":"1.0",
  "my_integer":"1"
}

GET my_index4/_mapping

Dynamic Templates API

  • 允许es自动识别的数据类型、字段名等来动态的实现
    • 所有字符串类型都设定为keyword类型,默认部分词

    • 所有的message开头的字段都设置为text类型,分词

    • 所有的以long_开头的字段都设定为long类型

    • 所有自动匹配为double类型的都是设定为float类型,节省空间

  • 匹配的规则

    • match_mapping_type匹配es自动识别的字段类型,如boolean、long、string

    • match,unmatch匹配字段

    • path_match、path_unmatch匹配路径

匹配到字符串转换成keyword

PUT test_index
{
  "mappings": {
    "doc": {
      "dynamic_templates":[
        {
          "strings_as_keywords":{
            "match_mapping_type":"string",
            "mapping":{
              "type":"keyword"
            }
          }
        }
      ]
    }
  }
}

匹配到message开头type为text

DELETE test_index

PUT test_index
{
  "mappings": {
    "doc": {
      "dynamic_templates":[
        {
          "message_as_text":{
            "match_mapping_type":"string",
            "match":"message*",
            "mapping":{
              "type":"text"
            }
          }
        }
      ]
    }
  }
}

PUT test_index/doc/1
{
  "name":"message hello"
}

GET test_index/_mapping

自定义mapping方案

  • 写入一条文档到es的临时索引中,获取es自动生成的mapping

  • 修改上步骤得到mapping,自定义相关配置

  • 使用上步骤获得实际的索引

索引模板API

  • 索引模板,英文为Index Temptate,主要用于在新建索引时候自动应用预先设定好的配置来简化索引的操作步骤

    • 可以设定索引的配置和mapping

    • 可以有多个模板,根据order设置,order大的覆盖小的配置

PUT _template/test_templates1
{
  "index_patterns":["te*","bar*"],
  "order":0,
  "settings": {
    "number_of_shards": 1
  },
  "mappings": {
    "doc":{
      "_source":{
        "enabled":false
      },
      "properties":{
        "name":{
          "type":"keyword"
        }
      }
    }
  }
}

PUT _template/test_templates2
{
  "index_patterns":["test*"],
  "order":1,
  "settings": {
    "number_of_shards": 1
  },
  "mappings": {
    "doc":{
      "_source":{
        "enabled":true
      }
    }
  }
}

GET _template
DELETE _template/test_templates2
DELETE _temolate/test_templates1

PUT foo_index
GET foo_index/_mapping

PUT bar_index
GET bar_index/_mapping

PUT test_index8
GET test_index8/_mapping

Search

  • 实现对ES中存储的数据进行查询分析,endpoint为_search
GET /_search //查询所有的
GET /my_index/_search
GET /my_index1,my_index2/_search //一次性查询多个逗号分割
GET /my_*/_search //对匹配的全部进行扫描
  • URI Search

    • 操作简便,方便通过命令进行测试

    • 仅包含部分查询语法

  • Request Body Search

    • es提供的完备查询语法Query DSL(Domain Specific Language)

URI Search

  • 通过url query参数来实现搜索,常用的参数
    • q 指定查找的语句,语法为Query String Syntax

    • df q 中不指定字段时默认查询的字段,如果不指定,es会查询所有的字段

    • sort 排序

    • timeout 指定超时的时间,默认不超时

    • from,size 用于分页

GET /my_index/_search?q=ddy&df=user&sort=age:asc&from=4&size=10&timeout=1s
//查询user字段包含ddy的文档,结果按照age升序排列,返回第5到14个文档,如果超过1s没有结束,则以上操作超时结束

Query String Syntax

Request body search

  • 将查询语句通过http request body发送到es
    • query符合Query DSL语法的查询语句

    • from,size

    • timeout

    • sort

GET /my_index/_search
{
  "query":{
    "term":{"user":"alfred"}
  }
}

Query DSL

  • 基于JSON定义的查询语句

    • 字段查询
      • term、match、range,只针对一个字段进行查询
    • 复合查询
      • bool查询,包含一个或者多个字段类型查询或复合查询语句
  • 全文匹配
    • 针对text类型的字段进行全文检索,会对查询语句先进行分词处理
  • 单词匹配
    • 不会对查询的语句做分词处理,直接去匹配字段的倒排索引

Match Query

  • 通过operator参数可以控制单词健的匹配关系,可选择项目为or和and

  • 通过mininum_should_match参数可以控制需要匹配的单词数量

流程图

相关性算分

  • 相关性算分指文档与查询语句间的相关度(relevance)

  • 通过倒排索引可以获取与查询语句匹配的文档列表

  • 如何将最符合的用户查询需求的文档放到前列呢?

    • 本质是一个排序的问题,排序的依据是相关性算分

重要的概念

  • Term Frequency(词频),词在该文档中出现的最大次数,词频率越高,相关度越大

  • Document Frequency(DF,文档频率),单词出现的文档数

  • Inverse Document Frequency(IDF,逆向文档频率),与DF相反,简单说1/df,单词数量越少越相关

  • Field-length Norm 文档越短,相关性越大

es目前使用的算分模型

  • TF/IDF 模型

  • BM25 模型 5.x版本后默认的模型

查看详细的计算

  • 可以通过explain参数查看具体的计算方法
    • es的算分是按照shard进行的,即使shard的分数计算是相互独立的,使用exp;ain时要注意分片数

    • 可以通过设置索引的分片数为1来避免这个问题

Match Phrase Query

  • 对字段作检索,有顺序的要求

  • 通过slop控制差异的大小

GET test_search_index/_search
{
  "query": {
    "match_phrase": {
      "job": "java engineer",
      "slop":1 //允许java 和engineer之间有一个单词的差异
    }
  }
}

query string query

GET test_search index/_search
{
  "query":{
    "query_string":{
      "fields":["username","job"]  //指定查找的字段
      "query":"ddy or (ccy and ruby)" //or和and共用,只要满足ddy或ccy ruby就是为真
    }
  }
}

Simple Query String Query

  • 类似Query String,但是会忽视错误的查询语句,并且仅仅支持部分查询语法

  • 常用的逻辑符合为,不能使用AND\OR、NOT

    • “+” 指 AND

    • “|” 指 OR

    • “-” 指 NOT

GET text_search_index/_search
{
  "query:{
    "simple_query_string:{
      "query":"alfred+way"
      "fields":"username"
    }
  }
}

Term Query

  • 将查询语句作为整一个单词来查询,不对查询语句做分词处理

  • Terms 就是对多个单词进行来查询

GET test_search_index/_search
{
  "query":{
    "term":{
      "username":"alfred"
    }
  }
}

复杂查询

  • 符合查询是指包含字段类型或复合查询类型

    • constant_score query

    • bool query

    • dis_max query

    • function_sore query

    • boosting query

constant score query

  • 该查询将其中内部的查询结果文档分成设定为1或者boot的值

  • 多用于结合bool查询实现自定义的得分

Bool Query

  • 布尔查询一般由一个或者多个组成查询语句
bool名称 相关作用解释
filter 只过率复合条件的文档,部计算相关性得分
must 文档必须符合must中的所有条件,会影响相关性的得分
must_net 文档必须不合符中的所有条件
shouled 文档可以符合should中的条件,会影响相关性得分
  • must的阶层号

should的使用

  • bool查询中只包含should,不包含must查询

  • bool查询中同时包含should和must查询

  • minimum_should_match可以控制满足条件的个数或百分比

  • 同时包含should和must时,文档不必满足should中的条件,但是如果满足条件,会增加相关性得分

GET test_search_index/_search
{
  "query": {
    "bool": {
      "should": [ //关键词
        {"term":{"job":"java"}},
        {"term":{"jpb":"ruby"}},
        {"term":{"job":"specialist"}}
      ],
      "minimum_should_match": 2 //最少满足的个数
    }
  }
}

Query Context VS Filter Context

  • 当一个查询语句位于Query或者Filter上下文时候,es执行的结果会不同的
上下文的类型 执行的类型 使用的方式
Query 查找与查询语句最为匹配的文档,对所有文档进行相关性算分并且排序 query bool中的must和should
Filter 查找与查询语句相互匹配的文档 bool中的filter与must_not constant_score中的filter
GET test_search_index/_search
{
  "query":{
    "bool": {
      "must": [
        {"match":{"title":"search"}},
        {"match":{"contant":"Elasticsearch"}}
      ],
      "filter": [
        {"term":{"status":"published"}},
        {"range:{"publish_date":{"gte:"2018-08-01"}"}"}
      ]
    }
  }
}

es分布式特性

  • es支持集群模式,是一个分布式系统
    • 增大系统的容量,内存、磁盘让es集群可以支持PB级别的数据

    • 提高系统的可用性,即使部分节点停止运行服务,整个集群依然正常的运行

  • es集群由多个es实例组成

    • 不同集群通过集群名字来区分,可以通过cluster.name进行修改,默认为elasticsearch

    • 每一个es集群本质上是一个jvm进程,且有自己的名字,通过node.name命名

cerebro可视化集群管理

  • https://github.com/lmenezes/cerebro
docker run -itd -p 5601:5601 -p 9200:9200 -p 5044:5044 --name elk-learn --network elk-learn elk

docker run -itd -p 9000:9000 --name java_env -v /root/cerebro-0.8.0:/root openjdk

docker exec -it java_env  nohup bash /root/bin/cerebro &

故障转移

读取方式

脑裂问题

  • 脑裂(split-brain)

  • 倒排索引一旦生成不可修改
    • 不用考虑并发写文件的问题,杜绝了锁机制带来的性能问题

    • 由于文件不能再次修改,可以充分利用文件系统缓存,只需要载入一次,主要内存足够多对该文件的读取都会从内存中,性能高

    • 利于生成缓存数据

    • 利于对文件进行压缩,节省磁盘和内存存储空间

    • 缺点需要写入新的文档时候,必须重新构建倒排索引文件,然后替换老文件后新的文档才能被检索。导致实时性差

shard详细

refresh与发生时机

  • segment写入磁盘的过程依然很耗时间,可以借助文件系统缓存的特性,先将segment在缓存中创建并且开放查询来进一步的提高实时性,这个过程叫做refresh

  • 在refresh中前文档会先存储在一个buffer中,refresh时将buffer中的所有文档清空并生成segment

  • es默认每一秒执行一次refresh,因此文档的实时性被提高到了1秒

refresh发生时机主要有以下的几种情况

  • (1)间隔的时间达到时候,通过index_settings.refresh_interval来设定,默认为1秒

  • (2)index.buffer占用满了时候,其大小通过indices.memory.index_buffer_size来设置,默认为jvm heap的10%,所有shard共享

  • (3)flush发生时候也会refresh

translog

如果在内存中segment还没有写入磁盘前发生了宕机,name其中的文档就无法恢复了

  • es引入了trashlog机制,写入文档到buffer时,同时将该操作写入到translog

  • translog温江会即使写入到磁盘中(fsync),6.x版本默认每一个请求都会写磁盘,可以修改为5s写一次,这样风险就是丢失5秒内的数据index_trashslog

  • es启动时候会检查translog文件,并从中恢复丢失的文件

flush

  • flush负责将内存中的segment写入磁盘中
    • 将translog写入磁盘

    • 将index buffer清空,其中的文档生成一个新的的segment,相当于一个refresh操作

    • 更新commit point并且写入

    • 执行fsync操作,将内存中的segment写入磁盘

    • 删除旧的translog文件

  • flush发生时机
    • 间隔时间到达时,默认30分钟,5.X之前可以用index.translog.flush_threshold_period修改,之后版本不行

    • translog占用满时,其大小可以通过index.translog.flush_threshold_seize控制,默认512MB,每一个index都有自己的translog

删除和更新文档

  • Lucene专门维护一个.del的文件,记录所有已经删除的文档,.del上记录的是文档在Lucenene内部的ID

  • 在查询结果返回前会过滤掉.del中的所有文档

  • 更新文档就是先删除旧的文档,再创建新的文档

Segment Merging

  • 随着segment的增多,由于一次查询的segment的数据多,查询的速度会变慢

  • es会定时的去执行segment merging,去清理segment的数量

  • 通过force_merge api可以手动的强制做segment merge操作

Elasticsearch由浅入深》有3个想法

  1. Thanks for your whole effort on this website. Kate delights in conducting investigation and it’s easy to understand why. I know all regarding the compelling tactic you deliver effective things on this website and in addition welcome participation from some others about this idea plus my princess is learning a great deal. Take advantage of the rest of the new year. You have been conducting a fabulous job.

发表评论