elastic的聚合搜索 集群认识

  • 我们先来举个栗子,一堆糖果,我们想按颜色分类

在这里插入图片描述

  • 我们也看来求一些最大值 最小值,平均值(注意:聚合内部是可以嵌套的)

在这里插入图片描述

冷热集群架构

  • elastic的节点是支持指定类型的,比如指定哪些节点是热节点和哪些是冷节点,配置方式有以下两种

通过elasticsearch.yml配置

node.attr.hotwarm_type: hot #热
node.attr.hotwarm_type: warm #冷
复制代码
  • 创建索引时指定
PUT /logs_2019-10-01
{
  "settings": {
    "index.routing.allocation.require.hotwarm_type": "hot",
    "number_of_replicas": 0
  }
}


PUT /logs_2019-08-01
{
  "settings": {
    "index.routing.allocation.require.hotwarm_type": "warm",
    "number_of_replicas": 0
  }
}
复制代码
  • 通过模板指定
PUT _template/logs_2019-08-template
{
  "index_patterns": "logs_2019-08-*",
  "settings": {
    "index.number_of_replicas": "0",
    "index.routing.allocation.require.hotwarm_type": "warm"
  }
}
PUT _template/logs_2019-10-template
{
  "index_patterns": "logs_2019-10-*",
  "settings": {
    "index.number_of_replicas": "0",
    "index.routing.allocation.require.hotwarm_type": "hot"
  }
}
复制代码

重新认识elastic集群

  • cluster

集群,一个ES集群由一个或多个节点(Node)组成,每个集群都有一个cluster name作为标识

  • node

节点,一个ES实例就是一个node,一个机器可以有多个实例,所以并不能说一台机器就是一个node,大多数情况下每个node运行在一个独立的环境或虚拟机上。

  • index

索引,即一系列documents的集合

  • shard

分片,ES是分布式搜索引擎,每个索引有一个或多个分片,索引的数据被分配到各个分片上,相当于一桶水用了N个杯子装,分片有助于横向扩展,N个分片会被尽可能平均地(rebalance)分配在不同的节点上(例如你有2个节点,4个主分片(不考虑备份),那么每个节点会分到2个分片,后来你增加了2个节点,那么你这4个节点上都会有1个分片,这个过程叫relocation,ES感知后自动完成),分片是独立的,对于一个Search Request的行为,每个分片都会执行这个Request.另外,每个分片都是一个Lucene Index,所以一个分片只能存放 Integer.MAX_VALUE - 128 = 2,147,483,519 个docs。建议单个分片大小设置在 30-50 GB 之间。一个分片默认最大文档数量是20亿。 宿主机内存大小的一半和31GB,取最小值。

  • replica

复制,可以理解为备份分片,相应地有primary shard(主分片),主分片和备分片不会出现在同一个节点上(防止单点故障),默认情况下一个索引创建5个分片一个备份(即5primary+5replica=10个分片),如果你只有一个节点,那么5个replica都无法分配(unassigned),此时cluster status会变成Yellow。replica的作用主要包括: 1.容灾:primary分片丢失,replica分片就会被顶上去成为新的主分片,同时根据这个新的主分片创建新的replica,集群数据安然无恙 2.提高查询性能:replica和primary分片的数据是相同的,所以对于一个query既可以查主分片也可以查备分片,在合适的范围内多个replica性能会更优(但要考虑资源占用也会提升[cpu/disk/heap]),另外index request只能发生在主分片上,replica不能执行index request。 对于一个索引,除非重建索引否则不能调整分片的数目(主分片数, number_of_shards),但可以随时调整replica数(number_of_replicas)。

存储空间

如果你的 Elasticsearch 集群节点的磁盘空间不足,则会影响集群性能。 一旦可用存储空间低于特定阈值限制,它将开始阻止写入操作,进而影响数据进入集群。 不少同学可能会遇到过如下的错误:ElasticsearchStatusException[Elasticsearch exception [type=cluster_block_exception, reason=blocked by: [FORBIDDEN/12/index read-only / allow这就是磁盘快满了做的保护机制提示。

磁盘的三个默认警戒水位线。

  • 低警戒水位线

默认为磁盘容量的85%。Elasticsearch不会将新的分片分配给磁盘使用率超过85%的节点。它也可以设置为绝对字节值(如500mb),以防止 Elasticsearch 在小于指定的可用空间量时分配分片。此设置不会影响新创建的索引的主分片,特别是之前从未分配过的分片。

cluster.routing.allocation.disk.watermark.low
复制代码
  • 高警戒水位线

默认为磁盘容量的90%。Elasticsearch 将尝试对磁盘使用率超过90%的节点重新分配分片(将当前节点的数据转移到其他节点)。它也可以设置为绝对字节值,以便在节点小于指定的可用空间量时将其从节点重新分配。此设置会影响所有分片的分配,无论先前是否分配。

cluster.routing.allocation.disk.watermark.high
复制代码
  • 洪水警戒水位线

默认为磁盘容量的95%。Elasticsearch对每个索引强制执行只读索引块(index.blocks.read_only_allow_delete)。这是防止节点耗尽磁盘空间的最后手段。只读模式待磁盘空间充裕后,需要人工解除。因此,监视集群中的可用存储空间至关重要。

cluster.routing.allocation.disk.watermark.flood_stage
复制代码

文档的删除

elasticsearch中的文档无法修改,并且是不可改版的,所以所有的更新操作都会将已有的文档标记为删除状态,包括删除文档,其实也不会马上就得对文档进行删除,而是标记为删除状态。当我们再次搜索的时候,会搜索全部然后过滤掉有删除标记的文档。因此,该索引所占的空间并不会随着该API的操作磁盘空间会马上释放掉,只有等到下一次段合并的时候才真正被物理删除,这个时候磁盘空间才会释放。相反,在被查询到的文档标记删除过程同样需要占用磁盘空间,这个时候,你会发现触发该API操作的时候磁盘不但没有被释放,反而磁盘使用率上升了。

一般生产环境中,使用该API操作的索引都很大,文档都是千万甚至数亿级别。索引大小在几百G甚至几个T,因此,这个操作建议在业务低峰期或者晚上进行操作,因为大数据量情况下删除的需要消耗较多的i/o CPU 资源,容易对生产集群造成影响。在删除过程中要确定集群磁盘有一定的余量,因为标记删除需要占用磁盘空间。如果磁盘空间不够,这个操作的失败率还是很大的。

Elasticsearch会有后台线程根据lucene的合并规则定期进行段合并操作,一般不需要用户担心或者采取任何行动。被删除的文档在合并时,才会被真正删除掉。再次之前,它仍然会占用着JVM heap和操作系统的文件cache、磁盘等资源。在某些特定情况下,我们需要ES强制进行段合并,以释放其占用的大量系统、磁盘等资源。POST /index_name/_forcemerge。

_forcemerge 命令可强制进行segment合并,并删除所有标记为删除的文档。Segment merging要消耗CPU,以及大量的I/O资源,所以一定要在你的ElasticSearch集群处于维护窗口期间,并且有足够的I/O空间的(如:SSD)的条件下进行;否则很可能造成集群崩溃和数据丢失。

文档的刷新

Elasticsearch refresh 刷新操作是使文档可搜索的过程。 默认情况下,每秒刷新一次。如果主要目标是调整摄取速度的索引,则可以将 Elasticsearch 的默认刷新间隔从1秒更改为30秒。30秒后,这将使文档可见以供搜索,从而优化索引速度。

  • 也可以对某个索引指定刷新频率
PUT my_index/_settings
{
  "index": {
    "refresh_interval": "30s"
  }
}
复制代码

副本

副本为了避免主分片出现问题导致数据丢失的问题,主分片和副本不会出现在同一个节点上。但是这样势必影响写的效率,对吧,因为副本是需要从主分片去同步数据的,所以在数据初始化的时候,可以先禁用副本,初始化完毕再开启副本

字段类型的选择

在这里插入图片描述

慢查询日志的开启

建议你在 Elasticsearch 集群中启用慢速查询日志,以解决性能问题并捕获运行时间较长或超过设置阈值的查询。 例如,如果您的搜索SLA为 2 秒,则可以按以下方式配置搜索查询,超过该阈值的任何查询都将被记录。

PUT my_index/_settings
{
    "index.search.slowlog.threshold.query.warn" : "2s"
}
复制代码

设置用户名密码【单机版】

  • 使用docker启动单机服务
zhangguofu@zhangguofudeMacBook-Pro Downloads $ docker run -d --name es -p 9212:9200 -p 9313:9300 -e "discovery.type=single-node"   elasticsearch:7.2.0
be9b65b0aa5770c5421752e935c54343c17cd9b86edfbe9f09b721a6e2d3bbca 
复制代码
  • 进入容器配置文件
zhangguofu@zhangguofudeMacBook-Pro Downloads $ docker exec -it be bash
[root@be9b65b0aa57 elasticsearch]# ls
LICENSE.txt  NOTICE.txt  README.textile  bin  config  data  jdk  lib  logs  modules  plugins 
复制代码

在这里插入图片描述

  • 重启容器并增加用户名密码(如果之前没设置过,需要重启,如果没有更改过elastic.yml 文件,则不需要重启)

在这里插入图片描述

多节点配置

  • 给elastic 多个节点配置用户名密码的话,我们需要通过颁发证书的方式参考文章

  • 下载elastic包,并解压,并复制出一份,来做一个elastic集群,我们大概看一下目录

  • 在这里插入图片描述

  • 我们配置一下elastic1,也就是节点1的elasticsearch.yml(在 elasticsearch1/config/elasticsearch.yml)

# 集群的名字
cluster.name: cluster2 
#节点的名字
node.name: node1
# 可以作为主节点
node.master: true 
#可以作为数据节点
node.data: true 
# 不支持远程连接
cluster.remote.connect: false 
# 本机的地址(如果需要外网访问,请填写具体ip,127.0.0.1局域网访问不到)
network.host: 172.16.131.4
# 对外服务的端口
http.port: 9200
# 集群数据交换的段开口
transport.port:9300
# 种子节点 9201 9301是 其他节点的端口号
discovery.seed_hosts: ["172.16.131.4:9300","172.16.131.4:9301"]
# 初始化的主节点(此处注意,后面会有变化)
cluster.initial_master_nodes: ["172.16.131.4:9300","172.16.131.4:9301"]
复制代码
  • 配置节点2
# 集群的名字
cluster.name: cluster2 
#节点的名字
node.name: node2
# 可以作为主节点
node.master: true 
#可以作为数据节点
node.data: true 
# 不支持远程连接
cluster.remote.connect: false 
# 本机的地址(如果需要外网访问,请填写具体ip,127.0.0.1局域网访问不到)
network.host: 172.16.131.4
# 对外服务的端口
http.port: 9201
# 集群数据交换的段开口
transport.port:9301
# 种子节点
discovery.seed_hosts: ["172.16.131.4:9300","172.16.131.4:9301"]
# 初始化的主节点(此处注意,后面会有变化)
cluster.initial_master_nodes: ["172.16.131.4:9300","172.16.131.4:9301"]
复制代码

配置完毕后,我们分别启动节点

  • 注意,由于我之前有一次没有配置节点,直接启动,后来再加入新的节点加不进去,后来删除 elastic1/data/nodes 目录后重新启动生效,估计如果第一次启动如果是单机启动,后面启动新的节点也不会被发现

生成证书

  • 关停各个服务节点
  • 讲单机版加密的时候我们也说过,需要在elasticsearch.yml里面加入以下配置信息
xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true

复制代码
  • 那么在集群中,我们需要先加入xpack.security.enabled: true 这个配置,来说明 这个集群是要使用安全加密的。
  • 生成证书
# 生成证书
bin/elasticsearch-certutil ca
# 生成证书和私钥
bin/elasticsearch-certutil cert --ca elastic-stack-ca.p12

复制代码
  • 这个时候在elastic1目录下会生成elastic-certificates.p12文件,我们把这个文件复制到各个节点的config目录下,并在每个elasticsearch.yml里面配置,然后启动各个节点
xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.verification_mode: certificate 
# 这个就是我们刚才生成证书,放在了config目录下,如果你想指定 相对或者绝对路径都可以(相对 默认目录是config)
xpack.security.transport.ssl.keystore.path: elastic-certificates.p12 
xpack.security.transport.ssl.truststore.path: elastic-certificates.p12 

复制代码
  • 在我启动的时候,发现报了一个错误
{"error":{"root_cause":[{"type":"master_not_discovered_exception","reason":null}],"type":"master_not_discovered_exception","reason":null},"status":503}
复制代码
  • 就是主节点没有发现,那么这个时候就要指定一下主节点,我使用elasticsearch2,也就是2节点为主节点,看一下节点2的配置
cluster.name: cluster2 
node.name: node2
node.master: true 
node.data: true 
cluster.remote.connect: false 
network.host: 172.16.131.4
http.port: 9201
transport.port:9301
discovery.seed_hosts: ["172.16.131.4:9300","172.16.131.4:9301"]
#是这里直接指定为主节点 
cluster.initial_master_nodes: node2
xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.verification_mode: certificate
xpack.security.transport.ssl.keystore.path: elastic-certificates.p12
xpack.security.transport.ssl.truststore.path: elastic-certificates.p12 

复制代码
  • 全部启动完毕后,我在主节点的目录下生成密码,在我测试过程中,如果主节点发生变化,比如变成节点1了,那么就要对节点1设置用户名密码
bin/elasticsearch-setup-passwords interactive

复制代码

在这里插入图片描述

  • 设置完毕密码,当你再次访问9200的时候,就需要输入用户名密码了,用户名就是elastic,密码就是你设置的那个密码

在这里插入图片描述

猜你喜欢

转载自juejin.im/post/7032263763780878367