(六)elasticsearch之常见问题和原理(实在不知道起啥名了)

1、elasticsearch之脑裂问题

(一)背景分析:

  • 脑裂问题(split-brain),是分布式系统中的经典网络问题。
  • 比如集群有3个节点(node1,node2,node3)。如果此时由于网络问题,node1无法和node2,node3访问,则node2和node3会重新选举master,然后更新cluster state;
  • 而node1自己组成集群后,也会更新cluster state。
  • 同一个集群有2个master,而且维护不同的 cluster state,那么网络恢复后则会产生矛盾,无法选择正确的master。

(二)解决方案:

  • 可配置可选举master-eligible 节点数大于等于 quorum时才可以进行master选举。
  • quorum=master-eligible 节点数/2 + 1,例如 3个master_eligible 节点时,quorum是2.
  • 设定discovery.zen.minimum_master_nodes=quorum 即可避免脑裂问题。

(三)一些优化:

##一个节点多久ping一次,默认1s 

discovery.zen.fd.ping_interval: 1s 

##等待ping返回时间,默认30s 

discovery.zen.fd.ping_timeout: 10s 

##ping超时重试次数,默认3次 

discovery.zen.fd.ping_retries: 3 

##选举时需要的节点连接数 

discovery.zen.minimum_master_nodes=N/2+1

2、segment、refresh、translog、flush

(一)segment

  • lucene 构建的单个倒排索引称为 segment,合在一起称为 index。这里与es 的 index 概念不同。es中的一个shard 对应一个 lucene index。而其 es 的index是可分布在多个shard 上的。
  • lucene 会有一个专门的文件来记录所有的 segment 信息,称为 commit point。如下图所示:

在这里插入图片描述

(二)refresh

  • segment 写入磁盘过程很耗时,可以借助文件系统缓存的特性,先将 segment 在缓存中创建并开放查询来进一步提升实时性,该过程在es 中被称为 refresh。
  • 在refresh 之前文档会先存储一个在 buffer 中,refresh 时将 buffer 中的所有文档清空并生成 segment。
  • es默认每1秒执行一次refresh,因此文档的实时性被提高到1秒,这也是es被称为近实时(Near Real Time)的原因。如下图:

在这里插入图片描述

(三)translog

  • 如果在内存中的 segment还没有写入到磁盘前发生了宕机,那么其中的文档就无法恢复了,为解决这个问题,translog 产生了。
  • es引入translog机制。写入文档到 buffer 时,同时将该操作写入translog(操作记录)。
  • translog文件会即时写入磁盘(fsync,异步),6.x默认每个请求都会落盘,可以修改为每5秒写一次,这样的风险就是有可能会丢失5秒内的数据,这个可以通过配置修改,相关配置为index.translog.*(请自行查阅)。
  • es启动时会检查translog文件,并从中恢复数据。

在这里插入图片描述

(四)flush

flush 负责将内存中的 segment写入磁盘,主要作如下的工作:

  1. 将 translog 写入磁盘;
  2. 将index buffer清空,其中的文档生成一个新的 segment,相当于一个 refresh 操作;
  3. 更新 commit point并写入磁盘;
  4. 执行 fsync 操作,将内存中的 segment 写入磁盘;
  5. 删除旧的 translog文件。
  6. flush工作较多,耗时长。

在这里插入图片描述

(五)其他

1> refresh 发生的几种情况:

  • 间隔时间到达是,可通过index.settings.refresh_interval 来设定,默认是1秒;
  • index.buffer 占满时,其大小可通过 indices.memory.index_buffer_size来设定,默认为 jvm heap 的10%,所以shard共享。
  • flush 发生时会发生 refresh。

2> flush 发生的几种情况:

  • 间隔时间达到时,默认是30分钟,5.x之前可以通过 index.translog.flush_threshold_period 修改,之后无法修改;
  • translog 占满时,其大小可通过设置 index.translog.flush_threshold_size 控制,默认是 512mb,每个index 都有自己的translog。

3> 删除与更新文档

  • segment 一旦生成就不能更改,否则更多的io 造成性能不好。此时删除就出现问题了。
  • lucene为解决上述问题,专门维护了一个 .del的文件,记录所有已经删除的文档,注意 .del 上记录的是文档在 lucene内部的 id。
  • 然后在查询结果返回前会过滤掉 .del中的所有文档。
  • 更新文档其实es是先删除文档,再创建新文档。

4> segment merging

  • 随着 segment的增多,会造成查询效率下降(因为一次查询的segment太多了);
  • es会定时在后台进行 segment merge 操作,减少 segment 的数量;
  • 通过force_merge API可以手动强制做segment merge 的操作。

3、elasticsearch之ingest node

(一)、介绍:

  • 5.x新增的一个节点类型。
  • 在数据写入es前(bulk/index 操作)对数据进行处理
  • 可设置独立的ingest node 专门进行数据转换处理,node.ingest: true
  • api endpoint 为 pipeline

(二)、pipeline

(1)pipeline 是由一系列的 processor 组成,可看成是 logstash 的 filter plugin,结构如下:

{
    "description": "xxx",
    "processor": [ yyy ]
}

(2)pipeline api

PUT 创建,GET 获取,DELETE 删除,SIMULATE 模拟调试

举例:

1》
PUT _ingest/pipeline/test
{
    "description": "for test",
    "processor": [
        {
            "set": {					// 输出增加一个name字段,其值是 hahaha
                "field": "name",
                "value": "hahaha"
            }
        }
    ]
}
2》
GET _ingest/pipeline/test
3》
DELETE _ingest/pipeline/test
4》
POST _ingest/pipeline/_simulate
{
    "pipeline": {
    	"description": "for test",
        "processor": [
            {
                "set": {					// 输出增加一个name字段,其值是 hahaha
                    "field": "name",
                    "value": "hahaha"
                }
            }
        ]
    },
    "docs": [
        {							// 测试pipeline,展示my message 在你指定pipeline的表现
            "_source": {
            	"message": "my message"
            }
        }
    ]
}
5》
POST _ingest/pipeline/test/_simulate // 此处使用的 是test pipeline
{
 	"docs": [
        {							// 测试pipeline,展示my message 在你指定pipeline的表现
            "_source": {
            	"message": "my message"
            }
        }
    ]
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章