Elasticsearch学习笔记之一

学习Elasticsearch做的笔记之一。

目录

1、正排索引,正向索引。

2、创建索引。

3、添加数据。 

4、查询数据。

(1)查询一条记录。

(2)查询全部记录。

(3)查询某一种类别。

(4)分页查询。

(5)过滤字段,只查询显示title字段。

(6)查询排序。

(7)多条件查询。

(8)范围查询filter。

(9)匹配查询。

(10)完全匹配,短语查询。

(11)高亮查询。

(12)聚合查询。

5、映射关系。

6、核心概念。

(1)索引index。

(2)类型type。

(3)文档document。

(4)字段field。

(5)映射mapping。

(6)分片shards。

(7)副本replicas。

(8)分配allocation。

7、window集群部署。

8、单节点集群。

9、水平扩容。

10、应对故障。

11、路由计算。

(1)路由计算。

(2)查询时分片控制。

12、数据写流程。

13、数据写流程consistency参数,timeout参数。

14、数据读流程。

15、部分更新文档流程。

16、批量操作流程。

(1)用单个mget请求取回多个文档流程。

(2)Bulk API执行流程。

17、倒排索引。

18、文档搜索。

(1)倒排索引不可变。

(2)倒排索引不可改变的意义。

(3)如何在保留不变性的前提下实现倒排索引的更新。

19、文档刷新,文档刷写,文档合并。

(1)文档写入流程。

 (2)索引具体的写操作流程。

 20、文档分析。

(1)分析过程。

(2)分析器的功能。

(3)内置分析器

(4)分析器使用场景。

21、文档控制,文档处理。

(1)悲观锁并发控制。

(2)乐观锁并发控制。

(3)ES乐观并发控制。

22、Kibana。

23、spring data框架。

 (1)spring data框架介绍。

(2)spring data elasticsearch介绍。

24、elasticsearch优化。

(1)硬件选择。

(2)分片策略。

(3)怎样合理设置分片数。

(4)推迟分片分配。

25、路由选择。

 (1)查询路由选择。

(2)不带routing查询。

(3)带routing查询。

26、写入速度优化。

27、内存设置。

28、elasticsearch的一些重要配置。 


1、正排索引,正向索引。

关系型数据库表结构,表有主键,通过主键索引快速关联到记录。

搜索引擎对待搜索的文件都对应一个文件ID,搜索时将这个ID和搜索关键字进行对应,形成K-V对,然后对关键字进行统计计数。

例如:

id     content


1      my name is zhang san

2      my name is li si

2、创建索引。

  创建索引。

PUT /shopping

查看所有索引。

GET /_cat/indices?v

3、添加数据。 

POST /shopping/_doc/

{

  "title": "小米手机",

  "category": "小米",

  "images": "https://cdn.cnbj1.fds.api.mi-img.com/product-images/redminote11pro4515/680.png",

  "price": 1700.00

}



POST /shopping/_doc/1001

{

  "title": "小米手机1",

  "category": "小米",

  "images": "https://cdn.cnbj1.fds.api.mi-img.com/product-images/redminote11pro4515/680.png",

  "price": 1700.00

}



POST /shopping/_doc/1002

{

  "title": "小米手机2",

  "category": "小米",

  "images": "https://cdn.cnbj1.fds.api.mi-img.com/product-images/redminote11pro4515/680.png",

  "price": 1700.00

}





POST /shopping/_doc/1003

{

  "title": "小米手机3",

  "category": "小米",

  "images": "https://cdn.cnbj1.fds.api.mi-img.com/product-images/redminote11pro4515/680.png",

  "price": 1700.00

}





POST /shopping/_doc/1004

{

  "title": "华为手机1",

  "category": "华为",

  "images": "https://res.vmallres.com/pimages/detailImg/2020/12/14/A0DA35EDB0DC63CE04B66AB4345FEB39F0EFC06E392C09E4.jpg",

  "price": 4999.00

}

4、查询数据。

(1)查询一条记录。

GET /shopping/_doc/1001

(2)查询全部记录。

GET /shopping/_doc/_search
GET /shopping/_search

{

  "query": {

    "match_all": {}

  }

}

(3)查询某一种类别。

GET /shopping/_search?q=category:小米
GET /shopping/_search

{

  "query": {

    "match": {

      "category": "小米"

    }

  }

}

(4)分页查询。

GET /shopping/_search

{

  "query": {

    "match_all": {}

  },

  "from": 0,

  "size": 2

}

from:从第几条记录开始查询。计算方式:(页码from-1) x 每页数据条数size。

size:每页数据条数。

(5)过滤字段,只查询显示title字段。

GET /shopping/_search

{

  "query": {

    "match_all": {}

  },

  "from": 0,

  "size": 2,

  "_source": ["title"]

}

(6)查询排序。

GET /shopping/_search

{

  "query": {

    "match_all": {}

  },

  "from": 0,

  "size": 10,

  "_source": ["title"],

  "sort": [

    {

      "price": {

        "order": "desc"

      }

    }

  ]

}

(7)多条件查询。

并且must查询。

GET /shopping/_search

{

  "query": {

    "bool": {

      "must": [

        {

          "match": {

            "category": "小米"

          }

        },

        {

          "match": {

            "price": 1700

          }

        }

      ]

    }

  }

}

或者should查询。

GET /shopping/_search

{

  "query": {

    "bool": {

      "should": [

        {

          "match": {

            "category": "小米"

          }

        },

        {

          "match": {

            "category": "华为"

          }

        }

      ]

    }

  }

}

(8)范围查询filter。

GET /shopping/_search

{

  "query": {

    "bool": {

      "should": [

        {

          "match": {

            "category": "小米"

          }

        },

        {

          "match": {

            "category": "华为"

          }

        }

      ],

      "filter": {

          "range": {

            "price": {

              "gte": 3000,

              "lte": 20000

            }

          }

        }

    }

  }

}

(9)匹配查询。

拆分成“小”“华”去查询。

GET /shopping/_search

{

  "query": {

    "match": {

      "category": "小华"

    }

  }

}

(10)完全匹配,短语查询。

“小华”作为一个整体查询不到记录。

GET /shopping/_search

{

  "query": {

    "match_phrase": {

      "category": "小华"

    }

  }

}

(11)高亮查询。

GET /shopping/_search

{

  "query": {

    "match_phrase": {

      "category": "小米"

    }

  },

  "highlight": {

    "fields": {

      "category": {}

    }

  }

}

(12)聚合查询。

# aggs:聚合操作。price_group:名称随便取名。terms:分组。field:分组字段。"size": 0 查询不显示原始数据。

GET /shopping/_search

{

  "aggs": {

    "price_group": {

      "terms": {

        "field": "price"

      }

    }

  },

  "size": 0

}

# aggs:聚合操作。price_avg:名称随便取名。avg:平均值。field:分组字段。

GET /shopping/_search

{

  "aggs": {

    "price_avg": {

      "avg": {

        "field": "price"

      }

    }

  },

  "size": 0

}

5、映射关系。

PUT /user

给索引字段添加映射。index为true可以索引,false不可以索引,不可以被查询。keyword不可分词。

PUT /user/_mapping

{

  "properties": {

    "name": {

      "type": "text",

      "index": true

    },

    "sex": {

      "type": "keyword",

      "index": true

    },

    "tel": {

      "type": "keyword",

      "index": false

    }

  }

}

查看字段映射。

GET /user/_mapping

可以查询到记录,name有分词效果。

GET /user/_search

{

  "query": {

    "match": {

      "name": "小"

    }

  }

}

查询不到记录,keyword不能分开,不可分词。

GET /user/_search

{

  "query": {

    "match": {

      "sex": "男"

    }

  }

}

查询不到记录,tel不能被索引,不能被查询,查询不到记录。

GET /user/_search

{

  "query": {

    "match": {

      "tel": "13800138000"

    }

  }

}

6、核心概念。

(1)索引index。

 一个索引就是一个拥有几分相似的文档的集合。例如:客户数据索引、产品目录索引、订单数据索引。

(2)类型type。

 在一个索引中,可以定义一种或多种类型。

 一个类型是索引的一个逻辑上的分类/分区,一般为一组具有共同字段的文档定义一个类型。

5.x 一个索引支持多种type。6.x一个索引只能有一种type。7.x默认不支持自定义索引类型,默认类型为_doc。

(3)文档document。

  一个文档是一个可以被索引的基础信息单元,一个文档是一条数据。例如:一个客户文档、某一个产品的一个文档、某一个订单的一个文档。

(4)字段field。

 用于对document文档数据根据不同属性进行的分类标识。相当于是数据库表的字段。

(5)映射mapping。

  索引的结构信息,处理数据的方式和规则,相当于数据库表的结构信息。例如:设置某个field字段的数据类型、默认值、分析器、是否被索引等。

(6)分片shards。

 一个索引可以存储超出单个节点硬件限制的大量数据。需要将一个索引的数据划分成多份,每一份放到不同的服务器上,合在一起是一个完整的数据,统一提供服务。相当于数据库中的分表。

(7)副本replicas。

 Elasticsearch创建分片primary shard的拷贝,拷贝就是复制分片,就是一个副本replica shard备份。

(8)分配allocation。

 将主分片或者副本分片分配给某个节点的过程,由master节点分配。

7、window集群部署。

elasticsearch.yml配置文件。

node-1001

cluster.name: elasticsearch

node.name: node-1001

node.master: true

node.data: true

network.host: localhost

http.port: 9201

transport.tcp.port: 9301

discovery.zen.fd.ping_timeout: 1m

discovery.zen.fd.ping_retries: 5

http.cors.enabled: true

http.cors.allow-origin: "*"

node-1002 

cluster.name: elasticsearch

node.name: node-1002

node.master: true

node.data: true

network.host: localhost

http.port: 9202

transport.tcp.port: 9302

discovery.seed_hosts: ["localhost:9301"]

discovery.zen.fd.ping_timeout: 1m

discovery.zen.fd.ping_retries: 5

http.cors.enabled: true

http.cors.allow-origin: "*"

node-1003

cluster.name: elasticsearch

node.name: node-1003

node.master: true

node.data: true

network.host: localhost

http.port: 9203

transport.tcp.port: 9303

discovery.seed_hosts: ["localhost:9301","localhost:9302"]

discovery.zen.fd.ping_timeout: 1m

discovery.zen.fd.ping_retries: 5

http.cors.enabled: true

http.cors.allow-origin: "*"

8、单节点集群。

 创建索引,3个主分片,每1个主分片有1个副本分片,一共6个分片shard。

PUT /users/

{

  "settings": {

    "number_of_shards": 3,

    "number_of_replicas": 1

  }

}

9、水平扩容。

主分片的数目在索引创建时已经确定,不能修改主分片的数量,只能修改副本分片的数量。

3个主分片,每个主分片有1个副本分片,一共6个分片shard。水平扩容最多只能扩容到6台服务器,每台服务器1个分片。如果要超过6台服务器,只能修改副本分片的数目。

修改副本分片数目,每1个主分片有2个副本分片,一共9个分片shard。

PUT /users/_settings

{

  "number_of_replicas": 2

}

如果只是在相同节点数目的集群上增加更多的副本分片并不能提高性能,因为每个分片从节点上获得的资源会变少。需要增加更多的硬件资源来提升吞吐量。

10、应对故障。

elasticsearch.yml的discovery配置。

3个node节点,原配置:

node-1001:无。

node-1002:

discovery.seed_hosts: ["localhost:9301"]

node1003:

discovery.seed_hosts: ["localhost:9301","localhost:9302"]

现在node-1001发生故障,掉线了。ES会重新选举出新的master。

如果node-1001重新加入集群,需要修改配置。

discovery.seed_hosts: ["localhost:9302","localhost:9303"]

11、路由计算。

(1)路由计算。

插入数据时计算出数据应该插入到哪个shard分片上。

hash(id)  % 主分片数量。

例如:主分片是3。

hash(id)  % 主分片数量 = 【0,1,2】。

(2)查询时分片控制。

查询时,控制请求发送到哪个分片。

用户可以访问任何一个节点获取数据,接收请求的这个节点称之为协调节点。例如:接收请求节点R3。

接收请求的节点可以处理请求,如果接收请求的节点很忙,也可以将请求转发给其他节点。例如:R3节点间请求转发给P3或R2节点。

 

12、数据写流程。

 

(1)、客户端请求集群任意节点,这个节点叫协调节点。

例如:请求node-1002节点。

(2)、协调节点将请求转发到经过路由计算后的指定节点的主分片primary shard。

例如:协调节点node-1002转发请求到node-1001节点的P0主分片primary shard。

(3)、主分片primary shard保存请求数据。

例如:P0主分片保存数据。

(4)、同步数据,主分片primary shard将数据发送到对应的副本切片replica shard。

例如:P0主分片将数据发送到副本切片R0。

(5)、副本切片replica shard保存主分片同步过来的数据。保存之后给主分片反馈副本已经保存好了。

例如:副本切片R0保存主分片P0发送过来的数据。

(6)、主分片primary shard接收到所有副本切片replica shard的通知后,进行反馈。

给协调节点反馈数据已经保存好了。

例如:主分片P0接收到R0的通知,然后通知协调节点node-1002

(7)、协调节点通知客户端,数据已经在主分片和所有副本分片保存成功。

例如:协调节点node-1002通知客户端。

13、数据写流程consistency参数,timeout参数。

 consistency一致性参数,有3个参数值one、all、quorum,默认quorum。

one:只要主分片保存数据成功,就认为是成功的,就可以查询了,其他副本慢慢更新。

all:主分片和所有的副本分片都保存数据成功,才认为是成功的,才可以查询。

quorum:默认值,超过半数,大部分分片副本保存数据成功,才认为是成功的,才可以查询。

quorum超过半数计算公式:int(primary + number_of_replicas/2) + 1。

number_of_replicas是索引中设置的副本分片数。

PUT /users/
{
  "settings": {
    "number_of_shards": 3,
    "number_of_replicas": 1
  }
}

例如:索引设置中指定了number_of_shards为3,number_of_replicas为1。3个主分片,每一个主分片有1个副本分片,一共有6个分片。

3个primary shard,number_of_shards=1,总共有3+3*1 = 6个shard。

计算:quorum = int( (3primary + 1replicas)/2 ) +1 = 3。

所以要求6个shard中必须至少有3个分片shard是活跃active状态的时候,才能执行写操作。

timeout参数:数据写入时,没有足够的副本分片,elasticsearch会等待出现足够的分片时,才写入数据,通过此参数设置等待时间。

14、数据读流程。

(1)、客户端发送查询请求到协调节点。

例如:发送请求到协调节点node-1001。

(2)、协调节点通过路由算法,计算数据所在的分片以及对于分片的全部副本位置。

例如:计算出数据在P0分片,以及副本分片R0。

(3)、为了能够负载均衡,轮询所有节点。

例如:轮询P0、R0分片。

(4)、接收请求的协调节点,将请求转发给具体执行查询操作的节点。

例如:P0分片将请求转发给R0副本分片。

(5)、执行查询操作的节点返回查询结果给协调节点。

例如:执行查询操作的节点node-1002,将查询结果返回给协调节点node-1001。

(6)、协调节点将结果反馈给客户端。

例如:协调节点node-1001接收到查询结果,返回给客户端。

15、部分更新文档流程。

 

1)客户端向node1节点发送更新请求。

2)通路由计算,node1节点将请求转发到node3节点的P0主分片。

3)node3节点从主分片查询出文档,修改文档_source字段中的json。然后重新查询文档,比较文档是否被其他进程修改,如果文档已经被其他进程修改,重试步骤3,超过设置的retry_on_conflict次数后放弃重试。

4)node3节点主分片修改文档成功后,同步数据到对应的所有副本分片R0,所有副本分片保存更新数据返回成功后,node3节点向协调节点node1返回数据更新成功,协调节点node1向客户端返回成功。

16、批量操作流程。

 多文档数据读取和插入流程。

(1)用单个mget请求取回多个文档流程。

1)客户端向node1发送mget请求。

2)协调节点node1知道每个文档存在于那个分片中,将整个多文档请求分解成每个分片的多文档请求,为每个分片构建多文档获取请求,并且将这些请求并行转发到所需每个主分片或副本分片的节点上。

3)协调节点node1收到所有节点反馈后,node1构建响应并将其返回给客户端。

(2)Bulk API执行流程。

1)客户端向node 1 发送bulk请求。

2)node 1为每个节点(node1、node2、node3)创建一个批量请求,并将这些请求并行转发到每个包含主分片的节点主机(node1、node3)。

3)主分片P0、P1一个接一个按顺序执行每个操作。当每个操作成功时,主分片P0、P1并行转发新文档(或删除)到副本分片R0、R1,然后执行下一个操作。一旦所有的副本分片报告所有操作成功,主分片的节点将向协调节点报告成功,协调节点将这些响应收集整理并返回给客户端。

17、倒排索引。

分片是elasticsearch最小的工作单元。

elasticsearch使用倒排索引便于快速的全文搜索。

词条:索引中的最小存储和查询单元。

词典:字典,词条的集合。

倒排表:关键字出现在什么位置,出现的频率。每条记录称为倒排项。

18、文档搜索。

(1)倒排索引不可变。

倒排索引被写入磁盘后是不可改变的。

(2)倒排索引不可改变的意义。

1)不需要锁。不更新索引,不需要担心多进程同时修改数据的问题。

2)索引被读入内核的文件系统缓存,只要文件系统缓存中还有足够的空间,大部分读请求会直接请求内存,不会命中磁盘,提升了查询性能。

3)其他缓存在索引的生命周期内始终有效,不需要在每次数据改变时被重建。

4)写入单个大的倒排索引允许数据被压缩,减少IO,需要被缓存到内存的索引的使用量。

(3)如何在保留不变性的前提下实现倒排索引的更新。

用更多的索引,通过增加新的补充索引来反映最近的修改,而不是直接重写整个倒排索引,每一个倒排索引都会被轮流查询到,从最早的开始查询完成后再对结果进行合并。

elasticsearch基于Lucene,是按段搜索的,每一段本身都是一个倒排索引。

索引在Lucene中除表示所有段的集合外,还增加了提交点的概率,提交点是一个列出了所有已知段的文件。

19、文档刷新,文档刷写,文档合并。

(1)文档写入流程。

1)通过路由算法计算出请求应该到哪个分片。接收到请求的节点叫协调节点。R0分片所在节点是协调节点。

2)协调节点将请求转发给主分片节点。转发请求到P0。

3)主分片节点同步数据到所有副本节点。

4)写入操作延迟时间 = 主分片的延时 + 并行写入副本的最大延时。

等于主分片的写入时间,以及并行写入副本分片所需最长时间的那个副本分片的时间。

 (2)索引具体的写操作流程。

1)客户端将请求发送到主分片所在的节点,elasticsearch为了减少IO,保证读写性能,会在Memory内存中建立索引,创建对象,此时索引还在内存中。

2)索引在内存当中形成一个分段的数据对象Segment。

3)写入索引的时候,为了保证数据安全,防止出现问题,会将数据写入一个translog日志文件中,translog可以刷写入磁盘,translog保证了数据的安全。

4)每隔1秒将内存当中的数据refresh刷写到操作系统文件缓存区OS Cache。查询请求可以从文件缓存区查询数据,提高查询效率。

5)分段数据对象Segment需要落盘,每隔30分钟,或者translog文件大于512MB时,把文件缓冲区的数据flush刷写到DISK磁盘当中,然后清空translog。

6)不断的flush刷写,形成Segment文件到磁盘,磁盘文件比较多时,性能会比较差。刷写的数据文件可以合并。

7)Segment文件段合并,提高效率。倒排索引不可变,每一次更新,每一次删除,都会体现在新的索引段当中,会增加.del状态文件,Segment文件段合并的时候会把.del文件的数据删除。

 20、文档分析。

(1)分析过程。

1)将一块文档分成适合于倒排索引的独立的词条。

2)将这些词条统一化为标准格式以提高它们的可搜索性,或者recall。

(2)分析器的功能。

1)字符过滤器。

字符串按顺序通过每个字符过滤器,在分词之前整理字符串。字符过滤器可以用来去掉HTML,将&转化为and。

2)分词器。

分词器可以按照某种分词规则分词,字符串被分词器分为单个的词条,一个简单的分词器遇到空格和标点的时候,可能会将文本拆分成词条。

3)Token过滤器。

将数据转换为特定的要求和格式,词条按顺序通过每个token过滤器。例如:改变词条:转换成小写字母;删除词条:删除a、and、the等无用词;增加词条:增加jump、leap同义词。

(3)内置分析器

Elasticsearch的内置分析器:标准分析器standard analyzer;简单分析器simple analyzer;空格分析器whitespace analyzer;语言分析器language analyzer等。

分析器会从下面的字符串得到哪些词条:

"Set the shape to semi-transparent by calling set_trans(5)"

1)标准分析器standard analyzer。

默认分词器,按词切分,小写处理。

标准分析器是Elasticsearch默认使用的分析器。它是分析各种语言文本最常用的选择。

它根据 Unicode 联盟 定义的 单词边界 划分文本。删除绝大部分标点。最后,将词条小写。

分词结果:

set, the, shape, to, semi, transparent, by, calling, set_trans, 5

2)简单分析器simple analyzer。

按照非字母切分(符号被过滤),小写处理。

简单分析器在任何不是字母的地方分隔文本,将词条小写。

分词结果:

set, the, shape, to, semi, transparent, by, calling, set, trans

3)空格分析器whitespace analyzer。

空格分析器在空格的地方划分文本。

分词结果:

Set, the, shape, to, semi-transparent, by, calling, set_trans(5)

4)语言分析器language analyzer。

提供了30多种常见语言的分词器。

特定语言分析器可用于很多语言。它们可以考虑指定语言的特点。

英语分析器附带了一组英语无用词(常用单词,例如 and 或者 the ,它们对相关性没有多少影响),它们会被删除。

由于理解英语语法的规则,这个分词器可以提取英语单词的词干 。

分词结果:

set, shape, semi, transpar, call, set_tran, 5

transparent、 calling 和 set_trans 已经变为词根格式。

(4)分析器使用场景。

在全文检索的时候,将文本进行拆解,拆解后放到倒排索引进行匹配查询,存储数据时是怎样分词的,查询时需要使用相同的分词方式进行查询,保证我们搜索的词条格式与索引中的词条格式一致。

21、文档控制,文档处理。

 文档冲突。

(1)悲观锁并发控制。

 假设有变更冲突可能发生,堵塞访问资源以防止冲突。例如:读取一行数据之前先将其锁住,确保只有放置锁的线程能够对这行数据进行修改。

(2)乐观锁并发控制。

 假设冲突是不可能发生的,并且不会堵塞正在尝试的操作。如果源数据在读写当中被修改,更新将会失败。可以重试更新。一般用版本号version控制。

(3)ES乐观并发控制。

 创建索引。

PUT /shopping/_create/1001
{
  
}

更新文档。

POST /shopping/_update/1001
{
  "doc": {
    "title": "华为手机"
  }
}

之前旧版本ES可以使用version控制。

POST /shopping/_update/1001?version=1
{
  "doc": {
    "title": "华为手机"
  }
}

新版本使用if_seq_no和if_primary_term控制。

POST /shopping/_update/1001?if_seq_no=1&if_primary_term=1
{
  "doc": {
    "title": "华为手机"
  }
}

version_type=external外部系统版本控制,使用自定义版本号version。

POST /shopping/_doc/1001?version=4&version_type=external
{
  "doc": {
    "title": "华为手机1"
  }
}

希望使用数据库中的版本号作为elasticsearch的version版本,版本号是大于0的整数。

检查当前_version 是否 小于 指定的版本号。 如果请求成功,外部的版本号作为文档的新 _version 进行存储。

22、Kibana

 config/kibana.yml文件。

# 默认端口

server.port: 5601

# ES 服务器的地址

elasticsearch.hosts: ["http://localhost:9200"]

# 索引名

kibana.index: ".kibana"

# 支持中文

i18n.locale: "zh-CN"

23、spring data框架。

 (1)spring data框架介绍。

spring data是一个用于简化数据库、非关系型数据库、索引库访问,并支持云服务的开源框架。对数据的访问变得方便快捷。

(2)spring data elasticsearch介绍。

 基于spring data API简化elasticsearch的操作,将原始操作elasticsearch的客户端API进行封装。为elasticsearch项目提供集成搜索引擎。

24、elasticsearch优化。

(1)硬件选择。

 使用SSD硬盘。

 使用RAID 0,条带化RAID提高磁盘I/O。

 使用多块硬盘。

 不使用远程挂载的存储。

(2)分片策略。

  为什么需要合理设置分片数。

1)一个分片的底层即为一个Lucene索引,会消耗一定文件句柄、内存、以及CPU运转。

2)每一个搜索请求都需要命中索引中的每一个分片,如果每一个分片都处于不同的节点还好,但如果多个分片都需要在同一个节点上竞争使用相同的资源就有些糟糕了。

(3)怎样合理设置分片数。

1)控制每个分片占用的硬件容量不超过elasticsearch的最大JVM的堆空间设置,一般设置不超过32G。

例如:索引的总容量在500G左右,那么分片的大小在16个左右即可。

2)考虑node节点数量,一般设置分片数不超过节点数的3倍。

     有时候一般一个节点是一台服务器,如果分片数量超过节点数量过多,一个节点上会存在多个分片,如果一个节点出现故障,即使保持了1个以上的副本,同样有可能会导致数据丢失,集群无法恢复。

3)主分片、副本分片、节点数量之间的关系。

  节点数量 <= 主分片数量 x (副本数量+1)

(4)推迟分片分配。

  节点瞬间中断,离线了,可以通过设置参数推迟elasticsearch自动开始平衡分片的时间。

  修改配置文件参数delayed_timeout全局设置,延长在平衡的时间。

   也可以在索引中修改设置。

PUT /_all/_settings
{
     “settings”: {
        “index.unassigned.node_left.delayed_timeout” : “5m”
     }
}

25、路由选择。

 (1)查询路由选择。

数据文档的时候,elasticsearch通过计算知道文档应该存放在那个分片。

 计算公式: shard = hash(routing) % number_of_primary_shards。 

  routing默认值是文档id,也可以使自定义的值。例如用户userid。

(2)不带routing查询。

在查询的时候因为不知道要查询的数据具体在哪个分片上,所以整个过程分为两个步骤。

分发:请求到达协调节点后,协调节点将查询请求分发到每个分片上。

聚合:协调节点搜集到每个分片上查询结果,在将查询的结果进行排序。然后返回结果给客户端。

(3)带routing查询。

 查询的时候,根据routing信息直接定位到某个分片,不需要经过协调节点,不用查询所有的分配。

例如:用户查询,自定义routing,查询时带上参数routing,设置为userid,可以直接查询出数据。

26、写入速度优化。

(1)写入要求较高的场景

搜索性能要求不高,写入要求较高的场景,可以从以下几个方面提升写索引的性能。

2)加大Translog Flush,目的是降低Iops、Writeblock。

3)增加Index Refresh间隔,目的是减少Segment Merge的次数。

4)调整Bulk线程池和队列。

5)优化节点间的任务分布。

6)优化Lucene层的索引建立,目的是降低CPU、IO。

(2)批量数据提交。

 bulk api支持批量操作,可以用来进行批量写入。bulk默认设置批量提交的数据量大小不超过100M。

(3)优化存储设备。

 elasticsearch是一种密集使用磁盘的应用,在段合并的时候会频繁操作磁盘。磁盘速度提升,集群整体性能提升。使用固态硬盘,速度会提高很多。

(4)合理使用合并。

 Lucene以段的形式存储数据,当有新的数据写入索引时,Lucene就会自动创建一个新的段。

 数据量的增加,段的数量会越来越多,消耗多文件句柄、CPU就越多,查询效率就会下降。

 elasticsearch默认在后台定期进行段合并。

(5)减少refresh的次数。

 Lucene在新增数据时,采用了延迟写入的策略,默认情况下索引的refresh_interval为1秒。

 Lucene将待写入的数据先写入内存分钟,超过1秒时就会触发一次refresh。

 然后refresh会把内存中的数据刷新到操作系统的文件缓存系统中。

如果对搜索的实效性要求不高,可以将refresh周期延长,减少了段的刷新次数,需要消耗更多的heap内存。

(6)加大flush设置。

 flush的主要目的是把文件缓存系统中的段持久化到硬盘,当translog的数据量达到512MB,或者30分钟,会触发一次flush。

index.translog.flush_threshold_size参数默认值是512MB。

(7)减少副本的数量。

 大批量进行写操作时,可以先禁止replica复制,设置index.number_of_replicas:0关闭副本,在写入完成后,replica修改会正常状态。

27、内存设置。

(1)elasticsearch默认安装后设置的内存是1GB,修改jvm.option文件来设置堆的大小,Xms表示堆的初始大小,Xmx表示可分配的最大内存,Xms、Xmx设置成相同的大小。

(2)elasticsearch的堆内存的分配需要满足以下两个原则。

1)、不超过物理内存的50%。

Lucene把底层OS里的数据缓存到内存中,如果设置的堆内存过大,Lucene可用的内存将会减少,会影响降低Lucene的全文本查询性能。

2)、堆内存的大小最好不要超过32GB。在java中,所有对象都分配在堆上,有一个klass pointer指针指向它的类元数据。

例如:有一台64G内存的服务器,一般设置堆内存为31G。

-Xms 31g

-Xmx 31g

28、elasticsearch的一些重要配置。 

参数名

参数值

说明

cluster.name

elasticsearch

配置 ES 的集群名称,默认值是 ES,建议改成与所存数据相关的名称,ES 会自动发现在同一网段下的集群名称相同的节点

node.name

node-1

集群中的节点名,在同一个集群中不能重复。节点

的名称一旦设置,就不能再改变了。当然,也可以

设 置 成 服 务 器 的 主 机 名 称 , 例 如

node.name:${HOSTNAME}

node.master

true

指定该节点是否有资格被选举成为 Master 节点,默

认是 True,如果被设置为 True,则只是有资格成为

Master 节点,具体能否成为 Master 节点,需要通

过选举产生。

node.data

true

指定该节点是否存储索引数据,默认为 True。数据

的增、删、改、查都是在 Data 节点完成的。

index.number_of_shards

1

设置都索引分片个数,默认是 1 片。也可以在创建

索引时设置该值,具体设置为多大都值要根据数据

量的大小来定。如果数据量不大,则设置成 1 时效

率最高

index.number_of_replicas

1

设置默认的索引副本个数,默认为 1 个。副本数越

多,集群的可用性越好,但是写索引时需要同步的

数据越多。

transport.tcp.compress

true

设置在节点间传输数据时是否压缩,默认为 False

不压缩

discovery.zen.minimum_master_nodes

1

设置在选举 Master 节点时需要参与的最少的候选 主节点数,默认为 1。如果使用默认值,则当网络 不稳定时有可能会出现脑裂。

合理的数值为 (master_eligible_nodes/2)+1 ,其中 master_eligible_nodes 表示集群中的候选主节点数

discovery.zen.ping.timeout

3s

设置在集群中自动发现其他节点时 Ping 连接的超 时时间,默认为 3 秒。

在较差的网络环境下需要设置得大一点,防止因误判该节点的存活状态而导致分片的转移

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值