柴少的官方网站 技术在学习中进步,水平在分享中升华

Elasticsearch集群监控和版本升级(六)

#Elasticsearch集群已经部署起来了,那么平时就需要了解一下集群的整体健康情况,当然开篇说的Cerebro插件就是一种查看集群状态的工具。

一、集群监控指标学习

Elasticsearch集群监控状态指标分三个级别:

集群级别:集群级别的监控主要是针对整个Elasticsearch集群来说,包括集群的健康状况、集群的状态等。

节点级别:节点级别的监控主要是针对每个Elasticsearch实例的监控,其中包括每个实例的查询索引指标和物理资源使用指标。

索引级别:索引级别的监控主要是针对每个索引来说,主要包括每个索引的性能指标。

The REST API:https://www.elastic.co/guide/en/elasticsearch/reference/current/rest-apis.html

      Elasticsearch提供了一个非常全面和强大的REST API,可以使用它来与群集进行交互。 可以用API完成的几件事情如下:

检查你的群集,节点和索引运行状况,状态和统计信息
管理你的群集,节点和索引数据和元数据
对索引执行CRUD(创建,读取,更新和删除)和搜索操作
执行高级搜索操作,如分页,排序,过滤,脚本,聚合等等

1.1 集群级别查看

查看集群健康状态:

# curl -X GET 'http://192.168.1.164:9200/_cat/'   #如果要看_cat有哪些子接口就这样什么子path都不带就能行

=^.^=
/_cat/allocation
/_cat/shards
/_cat/shards/{index}
/_cat/master
/_cat/nodes
/_cat/tasks
/_cat/indices
/_cat/indices/{index}
/_cat/segments
/_cat/segments/{index}
/_cat/count
/_cat/count/{index}
/_cat/recovery
/_cat/recovery/{index}
/_cat/health
/_cat/pending_tasks
/_cat/aliases
/_cat/aliases/{alias}
/_cat/thread_pool
/_cat/thread_pool/{thread_pools}
/_cat/plugins
/_cat/fielddata
/_cat/fielddata/{fields}
/_cat/nodeattrs
/_cat/repositories
/_cat/snapshots/{repository}
/_cat/templates
/_cat/ml/anomaly_detectors
/_cat/ml/anomaly_detectors/{job_id}
/_cat/ml/trained_models
/_cat/ml/trained_models/{model_id}
/_cat/ml/datafeeds
/_cat/ml/datafeeds/{datafeed_id}
/_cat/ml/data_frame/analytics
/_cat/ml/data_frame/analytics/{id}
/_cat/transforms
/_cat/transforms/{transform_id}

kibana查看:

image.png

命令行查看:

#curl -X GET 'http://192.168.1.164:9200/_cat/health?v'   #如果不加后面的v就不打印标题,v就是显示表头的意思。这里是查看集群的整体状态

  结果是:

epoch    timestamp cluster      status node.total node.data shards pri relo init unassign pending_tasks max_task_wait_time active_shards_percent
1475247709 17:01:49  elasticsearch green  3      3     784  392  0  0    0     0         -      100.0%

我们可以看到,我们的cluster为“elasticsearch”是green的。

green - 一切都很好(集群功能齐全)
yellow - 所有数据都可用,但一些副本尚未分配(群集完全可用)
red - 某些数据不管出于何种原因(群集部分功能)

#注意:当一个群集为red时,它将继续提供来自可用碎片的搜索请求,但是你可能需要尽快修复它,因为有未分配的碎片。

node.total(number_of_node):节点总数可以看到我们有3个节点
node.data(number_of_data_nodes):代表有3个数据节点
shards(active_shards):存活的数据分片是784
pri(active_primary_shards):存活的主分片是392个
relo(relocating_shards):迁移中的分片数量正常情况下就是0
init(initializing_shards):初始化中的分片数量,正常情况为0
unassign(unassigned_shards):未分配的分片正常情况也是0
pending_tasks(number_of_pending_tasks):准备中的任务,任务指迁移分片等 正常情况为0
max_task_wait_time(task_max_waiting_in_queue_millis):任务最长等待时间
active_shards_percent(active_shards_percent_as_number):正常分片百分比 正常情况为 100%

# curl -X GET 'http://192.168.1.164:9200/_cluster/health?pretty'  #查看集群的状态,跟上面展示的数据是一样的

{
  "cluster_name" : "elasticsearch",
  "status" : "green",
  "timed_out" : false,
  "number_of_nodes" : 3,
  "number_of_data_nodes" : 3,
  "active_primary_shards" : 392,
  "active_shards" : 784,
  "relocating_shards" : 0,
  "initializing_shards" : 0,
  "unassigned_shards" : 0,
  "delayed_unassigned_shards" : 0,  #延迟的未分配的分片数
  "number_of_pending_tasks" : 0,
  "number_of_in_flight_fetch" : 0,  #迁移中的分片数
  "task_max_waiting_in_queue_millis" : 0,
  "active_shards_percent_as_number" : 100.0
}

查看集群状态: 

# curl -X GET 'http://192.168.1.164:9200/_cluster/stats?pretty'   

关键指标说明:

indices.count:索引总数。
indices.shards.total:分片总数。
indices.shards.primaries:主分片数量。
docs.count:文档总数。
store.size_in_bytes:数据总存储容量。
segments.count:段总数。
nodes.count.total:总节点数。
nodes.count.data:数据节点数。
nodes. process. cpu.percent:节点CPU使用率。
fs.total_in_bytes:文件系统使用总容量。
fs.free_in_bytes:文件系统剩余总容量。

 1.2 节点级别查看

# curl -X GET 'http://192.168.1.164:9200/_nodes/?pretty'  #json格式显示Node节点的所有信息,显然信息太多了

# curl -X GET 'http://192.168.1.164:9200/_cat/nodes?v'    #获得集群中的节点列表

ip              heap.percent ram.percent cpu load_1m load_5m load_15m node.role master name
192.168.1.166       43          99       10    0.36    0.27     0.30 dilmrt      -      192.168.1.166
192.168.1.164       30          97       15    0.89    0.68     0.61 dilmrt      -      192.168.1.164
192.168.1.165       72          98        3    0.12    0.27     0.29 dilmrt      *      192.168.1.165

结果解释是:

heap.percent:堆内存占用百分比
ram.percent:内存占用百分比
cpu:CPU占用百分比
master:*表示节点是集群中的主节点
name:节点名

# curl -X GET 'http://192.168.1.164:9200/_cat/allocation?v'   #获得集群中节点的存储信息

shards disk.indices disk.used disk.avail disk.total disk.percent host          ip             node
   261     7.9gb     9.2gb    190.6gb    199.9gb        4      192.168.1.166 192.168.1.166 192.168.1.166
   261     8.7gb     8.9gb    190.9gb    199.9gb        4      192.168.1.164 192.168.1.164 192.168.1.164
   262     7.9gb     8.5gb    191.3gb    199.9gb        4      192.168.1.165 192.168.1.165 192.168.1.165

结果解释是:

shards:节点承载的分片数
disk.indices:索引占用的空间大小
disk.used :节点所在机器已使用磁盘空间
disk.avail:磁盘剩余空间
disk.total:磁盘总大小
disk.percent:磁盘使用百分比
host: 节点主机
ip:节点所属机器IP地址
node:节点名

#curl -X GET 'http://192.168.1.164:9200/_cluster/stats?pretty'  #集群中的节点状态监控,数据比较多。

关键指标说明:

name:节点名。
roles:节点角色。
indices.docs.count:索引文档数。
segments.count:段总数。
jvm.heap_used_percent:内存使用百分比。
thread_pool.{bulk, index, get, search}.{active, queue, rejected}:线程池的一些信息,包括bulk、index、get和search线程池,主要指标有active(激活)线程数,线程queue(队列)数和rejected(拒绝)线程数量。

# curl -X GET 'http://192.168.1.164:9200/_nodes/stats/thread_pool?pretty'  #查看Node线程组的状态

1.3 索引级别查看

# curl -X GET 'http://192.168.1.164:9200/_cat/indices?v'  #查看索引信息

health status index                          uuid                   pri rep docs.count docs.deleted store.size pri.store.size
green  open   kube-eventer-2017.11.30        w-_2xAv9R0qUFXFiz27lXQ   1   1     838         0         1.5mb        805.8kb

结果内容解释:

health:索引健康状态
status:索引的开启状态
index: 索引名称
uuid:索引uuid
pri:索引的主分片数
rep:索引副本分片数量
docs.count:索引中文档总数
docs.deleted: 索引中删除状态的文档
store.size:主分片+副本分片的大小
pri.store.size:主分片的大小

#我擦那么多数据指标我哪知道哪个是哪个?

如果查看指标对应意思?

# curl -X GET 'http://192.168.1.164:9200/_cat/recovery?help'   #help显示命令返回的参数说明,这个接口是显示正在进行和先前完成的索引碎片恢复的视图

我如何只显示指定的字段?

# curl -X GET 'http://192.168.1.164:9200/_cat/thread_pool?v&h=node_name,name,active'   #如这个显示线程池信息,只显示了节点名称,线程池名称和活跃线程数

# curl -X GET 'http://192.168.1.164:9200/_cat/segments?v'   #显示分片中的分段信息

index                          shard prirep ip            segment generation docs.count docs.deleted     size    size.memory committed searchable version compound
kube-eventer-2017.11.30        0     r      192.168.1.165  _1f        51        335            0         296.4kb    16988       true      true       8.5.1   false

博文来自:www.51niux.com

下面是结果内容解释:

index:索引名称
shard:分片名称
prirep:主分片还是副本分片,p是主分片,r是副本分片
ip:所在节点IP
segment:segment段名
generation:分段生成
docs.count:段中的文档数
docs.deleted:段中删除的文档数
size:段大小,以字节为单位
size.memory:段内存大小,以字节为单位
committed:段是否以提交
searchable:段是否可搜索
version:版本
compound:是否分段合并

多个参数一起使用并按sort排序?

# curl -X GET 'http://192.168.1.164:9200/_cat/shards?v&s=docs:desc,store:asc'   #显多个参数一起使用用&连接,这里表示显示索引分片信息,先按docs数量排序然后再按大小排序

format设置返回的内容格式?

# curl -X GET 'http://192.168.1.164:9200/_cat/templates?format=json'   #以json格式显示模板信息,还支持json,yaml,text,smile,cbor

[{"name":".monitoring-kibana","index_patterns":"[.monitoring-kibana-7-*]","order":"0","version":"7000199","composed_of":""},

下面是结果内容解释:

name:模板名称
index_patterns:模板匹配规则
order:模板优先级
version:模板版本

二、ES主机的系统指标监控

#系统级别的监控用zabbix\falcon\prometheus(node_exports)都可以,不过还是比较推荐后两个,这两个自带的监控指标比较多比较细。

2.1 这里用prometheus+grafana做秒级监控

#为什么做秒级监控,现在es在线上企业中的运用越来越普遍,作为底层服务队实时性要求很高,所以如果分钟级监控的话很多问题是发现不了的,比如段合并会导致IO突增进而引起请求调用延时,还是需要秒级监控去发现问题的。

#这里采用的是ES的Node节点部署node_exports,然后prometheus服务端使用file_sd自动发现的形式对es集群进行数据秒级采集的方式。

image.png

#如上图是一个秒级的IO状态图。

image.png

#首先Grafana的步长肯定是1s,然后就是用到了irate来做秒级出图,因为irate是取的最近两个数的速率,那么上图的意思就是取最后一秒和上一秒的两秒之间的速率了,就比较贴近于秒级的数据了。

#其他数据的出图也就是参照类似的意思出图就可以了,当然这种秒级对监控采集的CPU要求还是比较高的,可以用来做问题追踪或者核心es机器指标监控,没必要所有的节点都搞秒级监控,可以常规的采集除一些系统性能指标的监控图。

三、elasticsearch_exporter(非必须)

#上面第一部分咱们不是已经说了好多API接口可以获取集群的一些信息吗,elasticsearch_exporter就有点类似于我把指标都封装才加好了给你提供一个web接口,你的监控采集程序来收集这些信息就好了。github上面找一个星最多的和最佳推荐。

https://github.com/prometheus-community/elasticsearch_exporter   #就用这个吧哈哈,安装方式,指标意思都有说哦,源码里面都有干了啥

3.1 安装客户端采集程序

# wget https://github.com/prometheus-community/elasticsearch_exporter/releases/download/v1.2.1/elasticsearch_exporter-1.2.1.linux-amd64.tar.gz

# tar xf elasticsearch_exporter-1.2.1.linux-amd64.tar.gz

# cd elasticsearch_exporter-1.2.1.linux-amd64

# ./elasticsearch_exporter --help   #可以先看一下帮助说明

usage: elasticsearch_exporter [<flags>]

Flags:
  -h, --help                 Show context-sensitive help (also try --help-long and --help-man).
      --web.listen-address=":9114"  #监听地址和端口
      --web.telemetry-path="/metrics" #提供指标的path路径
      --es.uri="  #获取指标的ES的IP和端口 
      --es.timeout=5s  #从ES获取指标数据几秒超时
      --es.all   #导出群集中所有节点的统计数据。 如果使用,此标志将覆盖标志es.node。
      --es.node="_local"  #曝光节点指标的名称
      --es.indices  #导出群集中索引的统计数据。
      --es.indices_settings  #导出群集索引设置的统计数据。
      --es.indices_mappings  #导出群集所有索引的映射的统计数据。
      --es.cluster_settings  #导出群集设置的统计数据。
      --es.shards            #导出分片的统计信息(implies --es.indices).
      --es.snapshots         #导出群集快照的统计数据。
      --es.clusterinfo.interval=5m  #群集标签的群集信息更新间隔
      --es.ca=""         #PEM文件的路径包含Elasticsearch连接的可信证书权限。
      --es.client-private-key=""  #连接到Elasticsearch时包含客户端验证的私钥的PEM文件的路径。                         
      --es.client-cert=""    #PEM文件的路径包含连接到Elasticsearch的私钥的相应证书。
      --es.ssl-skip-verify   #连接到Elasticsearch时跳过SSL验证。
      --log.level="info"     #设置日志级别,有效值是debug, info, warn, error
      --log.format="logfmt"  #设置日志格式有效格式是json and logfmt
      --log.output="stdout"  #设置日志输出。 有效输出是stdout和stderr
      --version              #显示应用程序版本。

# nohup ./elasticsearch_exporter  --web.listen-address=":9114" --es.uri http://192.168.1.164:9200  &   #启动下客户端服务

# curl 127.0.0.1:9114/metrics   #可以看看能不能获取到数据信息,能获取到就说明部署成功了。具体指标的含义都有注释

#ES有很多的断路器,也就是circuit breaker,可以用来阻止各种操作导致OOM内存溢出。每个断路器都有一个限制,就是最多可以使用多少内存。
#此外,还有一个父断路器指定了所有断路器最多可以使用多少内存(indices.breaker.total.limit).
#fielddata断路器可以估算每一个field的所有数据被加载到内存中,需要耗费多大的内存。这个断路器可以避免fielddata加载到jvm内存时发生OOM问题。
#indices.breaker.fielddata.limit可以用这个参数来配置,默认的值是jvm heap的60%。indices.breaker.fielddata.overhead可以配置估算因子,估算出来的值会乘以这个估算因子,留一些buffer,默认是1.03。
#request circuit breaker可以阻止由于某个请求对应的一些数据结构造成的OOM(比如一个聚合请求可能会用jvm内存来做一些汇总计算)。
#indices.breaker.request.limit最大是jvm heap的60%indices.breaker.request.overhead估算因子,默认是1。
#flight request circuit breaker可以限制当前所有进来的transport或http层的请求超出一个节点的内存总量,这个内存的使用量就是请求自己本身的长度。
#network.breaker.inflight_requests.limit,默认是jvm heap的100%。network.breaker.inflight_requests.overhead,估算因子,默认是1.
#这个断路器可以阻止一段时间内的inline script编译的数量。script.max_compilations_per_minute,默认是1分钟编译15个。
elasticsearch_breakers_estimated_size_bytes  #guage类型,断路器的估计大小(以字节为单位),breaker有(accounting|fielddata|in_flight_requests|parent|request)
elasticsearch_breakers_limit_size_bytes #guage类型,断路器的限制大小(以字节为单位)
elasticsearch_breakers_overhead  #counter类型,断路器的开销
elasticsearch_breakers_tripped  #counter类型,断路器跳闸

##集群健康和节点可用性
elasticsearch_cluster_health_active_primary_shards  #gauge类型,集群中的主分片数。这是所有索引的总和。
elasticsearch_cluster_health_active_shards  #gauge类型,所有索引中所有分片(包括副本分片)的合计。
elasticsearch_cluster_health_delayed_unassigned_shards  #gauge类型,分片延迟数量以减少重新分配开销。
elasticsearch_cluster_health_initializing_shards  #gauge类型,新建的分片数量。
elasticsearch_cluster_health_json_parse_failures  #counter类型,解析JSON时错误数量
elasticsearch_cluster_health_number_of_data_nodes  #gauge类型,集群中数据节点的数量
elasticsearch_cluster_health_number_of_in_flight_fetch  #gauge类型,正在进行的分片信息请求的数量
elasticsearch_cluster_health_number_of_nodes #gauge类型,群集中的节点数量
elasticsearch_cluster_health_number_of_pending_tasks  #gauge类型,尚未执行的群集级别更改
elasticsearch_cluster_health_relocating_shards #gauge类型,当前从一个节点移动到另一个节点的分片数量
elasticsearch_cluster_health_status  #gauge类型,集群健康状态情况,状态有(green|red|yellow),谁为1说明属于那种状态
elasticsearch_cluster_health_task_max_waiting_in_queue_millis #gauge类型,任务在集群队列中最大等待时长(毫秒)
elasticsearch_cluster_health_total_scrapes  #counter类型,当前集群健康值得抓取次数
elasticsearch_cluster_health_unassigned_shards  #gauge类型,处于集群状态但在集群本身中找不到的分片数量
elasticsearch_cluster_health_up  #gauge类型,集群运行状况,最后一次抓取是否成功
elasticsearch_clusterinfo_last_retrieval_success_ts  #gauge类型,最后一次成功集群信息检索的时间戳
elasticsearch_clusterinfo_up  #gauge类型,群集信息收集器的度量标准
elasticsearch_clusterinfo_version_info  #gauge类型,以ES版本信息为标签的常量指标
elasticsearch_exporter_build_info  #gauge类型,一个度量标准,具有恒定的1值,该值由版本,修订版,分支和goversion标记,并以此为基础构建elasticsearch_exporter
elasticsearch_filesystem_data_available_bytes  #gauge类型,块设备上的可用空间以字节为单位
elasticsearch_filesystem_data_free_bytes  #gauge类型,块设备上的可用空间(以字节为单位)
elasticsearch_filesystem_data_size_bytes  #gauge类型,块设备的大小(以字节为单位)
elasticsearch_filesystem_io_stats_device_operations_count   #counter类型,磁盘操作计数
elasticsearch_filesystem_io_stats_device_read_operations_count  #counter类型,磁盘读取操作的计数
elasticsearch_filesystem_io_stats_device_read_size_kilobytes_sum  #counter类型,从磁盘读取kb大小
elasticsearch_filesystem_io_stats_device_write_operations_count #counter类型,磁盘写入操作的计数
elasticsearch_filesystem_io_stats_device_write_size_kilobytes_sum  #counter类型,从磁盘写入kb大小

###索引请求
elasticsearch_indices_completion_size_in_bytes  #counter类型,完成字节数
elasticsearch_indices_docs  #gauge类型,此节点上的docs计数
elasticsearch_indices_docs_deleted  #gauge类型,此节点上已删除文档的计数
elasticsearch_indices_fielddata_evictions  #counter类型,来自field数据的Evictions
elasticsearch_indices_fielddata_memory_size_bytes  #gauge类型,字段数据缓存的内存使用量(以字节为单位)
elasticsearch_indices_filter_cache_evictions  #counter类型,来自过滤器缓存的逐出
elasticsearch_indices_filter_cache_memory_size_bytes  #gauge类型,过滤缓存的内存使用量(以字节为单位)
elasticsearch_indices_flush_time_seconds  #counter类型,累积刷新时间(以秒为单位)
elasticsearch_indices_flush_total  #counter类型,刷新总数
elasticsearch_indices_get_exists_time_seconds  #counter类型,获得的总时间以秒为单位
elasticsearch_indices_get_exists_total  #counter类型,获取exists操作的总数
elasticsearch_indices_get_missing_time_seconds  #counter类型,花费在文档丢失的GET请求上的总时间以秒为单位
elasticsearch_indices_get_missing_total  #counter类型,文档丢失的GET请求总数
elasticsearch_indices_get_time_seconds  #counter类型,get总时间(以秒为单位)
elasticsearch_indices_get_total  #counter类型,get总数
elasticsearch_indices_indexing_delete_time_seconds_total  #counter类型,删除索引的总时间,以秒为单位
elasticsearch_indices_indexing_delete_total  #counter类型,索引删除总数
elasticsearch_indices_indexing_index_time_seconds_total  #counter类型,索引文档总时间    
elasticsearch_indices_indexing_index_total  #counter类型,索引调用总数
elasticsearch_indices_indexing_is_throttled  #gauge类型,索引限制
elasticsearch_indices_indexing_throttle_time_seconds_total  #counter类型,索引节流累计时间
elasticsearch_indices_merges_current  #gauge类型,当前的合并次数
elasticsearch_indices_merges_current_size_in_bytes  #gauge类型,当前合并的大小(以字节为单位)
elasticsearch_indices_merges_docs_total  #counter类型,累积文档合并次数
elasticsearch_indices_merges_total  #counter类型,合并总数
elasticsearch_indices_merges_total_size_bytes_total  #counter类型,总合并大小(以字节为单位)
elasticsearch_indices_merges_total_throttled_time_seconds_total  #counter类型,合并的总限制时间(以秒为单位)
elasticsearch_indices_merges_total_time_seconds_total  #counter类型,合并的总时间(以秒为单位)
elasticsearch_indices_query_cache_cache_size  #gauge类型,查询缓存的缓存大小
elasticsearch_indices_query_cache_count  #counter类型,查询缓存计数
elasticsearch_indices_query_cache_evictions  #counter类型,查询缓存中的逐出
elasticsearch_indices_query_cache_memory_size_bytes  #gauge类型,查询缓存内存用量以字节为单位
elasticsearch_indices_query_cache_total  #counter类型,查询缓存总数
elasticsearch_indices_query_miss_count  #counter类型,查询未命中计数
elasticsearch_indices_refresh_time_seconds_total  #counter类型,刷新所花费的总时间(以秒为单位)
elasticsearch_indices_refresh_total  #counter类型,刷新总数
elasticsearch_indices_request_cache_count  #counter类型,请求缓存数
elasticsearch_indices_request_cache_evictions #counter类型,请求缓存的逐出
elasticsearch_indices_request_cache_memory_size_bytes  #gauge类型,请求缓存内存用量以字节为单位
elasticsearch_indices_request_miss_count  #counter类型,请求miss计数

##搜索和索引性能
elasticsearch_indices_search_fetch_time_seconds  #counter类型,搜索时间以秒为单位
elasticsearch_indices_search_fetch_total  #counter类型,总搜索请求数
elasticsearch_indices_search_query_time_seconds  #counter类型,总搜索查询时间以秒为单位
elasticsearch_indices_search_query_total  #counter类型,查询总数
elasticsearch_indices_search_scroll_time_seconds  #counter类型,总滚动时间(以秒为单位
elasticsearch_indices_search_scroll_total  #counter类型,滚动总数
elasticsearch_indices_search_suggest_time_seconds  #counter类型,总搜索建议时间
elasticsearch_indices_search_suggest_total  #counter类型,搜索总数
elasticsearch_indices_segments_count  #guage类型,此节点上索引段的计数
elasticsearch_indices_segments_doc_values_memory_in_bytes  #gauge类型,doc值内存计数
elasticsearch_indices_segments_fixed_bit_set_memory_in_bytes  #gauge类型,固定位设置的内存计数
elasticsearch_indices_segments_index_writer_memory_in_bytes  #gauge类型,此节点上索引编写器的内存计数
elasticsearch_indices_segments_memory_bytes  #gauge类型,当前段的内存大小(以字节为单位)
elasticsearch_indices_segments_norms_memory_in_bytes  #gauge类型,规范使用的内存计数
elasticsearch_indices_segments_points_memory_in_bytes  #gauge类型,Point内存使用字节大小
elasticsearch_indices_segments_stored_fields_memory_in_bytes  #gauge类型,fields存储在内存的计数
elasticsearch_indices_segments_term_vectors_memory_in_bytesterm  #gauge类型,向量的内存使用量(以字节为单位)
elasticsearch_indices_segments_terms_memory_in_bytes  #gauge类型,此节点在内存中的terms计数
elasticsearch_indices_segments_version_map_memory_in_bytes  #gauge类型,版本map内存使用量(以字节为单位)
elasticsearch_indices_store_size_bytes  #gauge类型,当前存储的索引数据大小(以字节为单位)
elasticsearch_indices_store_throttle_time_seconds_total  #counter类型,索引存储的节流时间(以秒为单位)
elasticsearch_indices_translog_operationstranslog  #counter类型,总的translog操作
elasticsearch_indices_translog_size_in_bytes  #counter类型,总的translog大小(以字节为单位)
elasticsearch_indices_warmer_time_seconds_total  #counter类型,总warmer时间(以秒为单位)
elasticsearch_indices_warmer_total  #counter类型,warmer总数

##JVM内存和垃圾回收
elasticsearch_jvm_buffer_pool_used_bytes  #gauge类型,目前使用的JVM缓冲区,type(direct|mapped)
elasticsearch_jvm_gc_collection_seconds_count  #counter类型,JVM GC运行计数,gc(old|young)
elasticsearch_jvm_gc_collection_seconds_sum  #counter类型,JGC的运行时间(以秒为单位),gc(old|young)
elasticsearch_jvm_memory_committed_bytes  #gauge类型,当前按区域提交的JVM内存,area(head|non-heap)
elasticsearch_jvm_memory_max_bytes  #gauge类型,配置的最大jvm值    
elasticsearch_jvm_memory_pool_max_bytes  #counter类型,JVM内存最大池数pool(old|survivor|young)
elasticsearch_jvm_memory_pool_peak_max_bytes  #counter类型,最大的JVM内存峰值,pool(old|survivor|young)
elasticsearch_jvm_memory_pool_peak_used_bytes  #counter类型,池使用的JVM内存峰值,pool(old|survivor|young)
elasticsearch_jvm_memory_pool_used_bytes  #gauge类型,pool目前使用的JVM内存,pool(old|survivor|young)
elasticsearch_jvm_memory_used_bytes  #gaug类型当前区域使用的JVM内存,area(head|non-heap)

##资源饱和度
elasticsearch_node_stats_json_parse_failures  #counter类型,解析JSON时的错误数
elasticsearch_node_stats_total_scrapes  #counter类型,目前的Elasticsearch节点scrapes
elasticsearch_node_stats_up  #gauge类型,是Elasticsearch节点endpoint成功的最后一次scrapes
elasticsearch_nodes_roles  #gauge类型,Node角色,role(client|data|ingest|master)
elasticsearch_os_cpu_percent  #gauge类型,操作系统使用的CPU百分比
elasticsearch_os_load1  #gauge类型,1分钟负载平均值
elasticsearch_os_load15  #gauge类型
elasticsearch_os_load5  #gauge类型
elasticsearch_os_mem_actual_free_bytes  #gauge类型,可用物理内存量(以字节为单位)
elasticsearch_os_mem_actual_used_bytes  #gauge类型,已使用的物理内存量(以字节为单位)
elasticsearch_os_mem_free_bytes  #gauge类型,可用物理内存量(以字节为单位)
elasticsearch_os_mem_used_bytes  #gauge类型,已使用的物理内存量(以字节为单位)
elasticsearch_process_cpu_percent  #gauge类型,进程使用的CPU百分比
elasticsearch_process_cpu_time_seconds_sum  #counter类型,进程CPU时间(以秒为单位),type(sys|total|user)
elasticsearch_process_max_files_descriptors  #gauge类型,最大文件描述符
elasticsearch_process_mem_resident_size_bytes  #gauge类型,进程正在使用的驻留内存(以字节为单位
elasticsearch_process_mem_share_size_bytes  #gauge类型,进程正在使用的共享内存(以字节为单位)
elasticsearch_process_mem_virtual_size_bytes  #gauge类型,使用的总虚拟内存(以字节为单位)
elasticsearch_process_open_files_count  #gauge类型,打开文件描述符
elasticsearch_thread_pool_active_count  #gauge类型,线程池线程活动状态,tyepe(analyze|ccr|fetch_shard_started|fetch_shard_store|
flush|force_merge|feneric|get|gistener|lanagement|ml_datafeed|ml_job_comms|ml_utility|refresh|rollup_indexing|search|search_throttled|
security-token-key|snapshot|transform_indexing|warmer|watcher|write)
elasticsearch_thread_pool_completed_count  #counter类型线程池操作已完成,type(analyze|ccr|fetch_shard_started|fetch_shard_store|
flush|force_merge|generic|get|listener|management|ml_datafeed|ml_job_comms|ml_utility|refresh|rollup_indexing|search|search_throttled|
security-token-key|snapshot|transform_indexing|warmer|watcher|write)
elasticsearch_thread_pool_largest_count  #gauge类型,线程池最大线程数,type同上
elasticsearch_thread_pool_queue_count  #gauge类型,线程池操作排队,type同上
elasticsearch_thread_pool_rejected_count  #counter类型,线程池操作被拒绝,type同上
elasticsearch_thread_pool_threads_count  #gauge类型,线程池当前线程数,type同上
elasticsearch_transport_rx_packets_total  #counter类型,接收到的数据包总数
elasticsearch_transport_rx_size_bytes_total  #counter类型,接收的总字节数
elasticsearch_transport_tx_packets_total  #counter类型,发送的数据包总数
elasticsearch_transport_tx_size_bytes_total  #counter类型,发送的总字节数

##主机级别的系统和网络指标
process_cpu_seconds_total  #counter类型花费的总用户和系统CPU时间(以秒为单位)
process_max_fds  #gauge类型,打开文件描述符的最大数量
process_open_fds  #gauge类型,打开文件描述符的数量
process_resident_memory_bytes  #gauge类型,驻留内存大小(以字节为单位)
process_start_time_seconds  #gauge类型,自UNIX纪元以来的进程开始时间(以秒为单位)
process_virtual_memory_bytes  #gauge类型,虚拟内存大小(以字节为单位)
process_virtual_memory_max_bytes  #gauge类型,以字节为单位可用的最大虚拟内存量。
promhttp_metric_handler_requests_in_flight  #gauge类型,正在提供目前的scrapes数
promhttp_metric_handler_requests_total  #counter类型,HTTP状态代码的scrapes总数,code(200|500|503)

#了解采集的监控指标才能更好的出图和坐报警

3.2 监控采集端采集数据

#prometheus的配置

# vim prometheus.yml

    - job_name: 'es-exports'
      honor_labels: true
      file_sd_configs:
        - files:
          - file_sd/es_exports.yml

# vim file_sd/es_exports.yml

[
    {
        "targets": [ "192.168.1.164:9114" ],
        "labels": {
            "instance": "192.168.1.164"
        }
    },
    {
        "targets": [ "192.168.1.165:9114" ],
        "labels": {
            "instance": "192.168.1.165"
        }
    },
    {
        "targets": [ "192.168.1.166:9114" ],
        "labels": {
            "instance": "192.168.1.166"
        }
    }
]

#curl -XPOST http://localhost:9090/-/reload

#最后查看一下prometheus的web页面的targets那里此job是否已经正常开始获取数据了

博文来自:www.51niux.com

3.3 出图展示

#解压包里面已经带了grafana的dashboard.json,我们只需要导入便可以了。

image.png

#如果图没有展示出来或者图修改就按照自己的理解来弄了。

#这里有个有意思的图可以展示一下,就是比Green/Yellow/Red不是三种状态码,但是这三种状态只能由一个是1其他都是0,如何在一个如图中展示当前集群属于某一种状态呢?其实也很简单promql虽然没有if判断,但是又+-*/运算符啊,稍微修改下结合grafana就可以了。

promql语句:

(sum(elasticsearch_cluster_health_status{cluster="$cluster",color="green"})+sum(elasticsearch_cluster_health_status{cluster="$cluster",color="yellow"}*2)+sum(elasticsearch_cluster_health_status{cluster="$cluster",color="red"}*3))/count(elasticsearch_cluster_health_status{cluster="$cluster",color="green"})

image.pngimage.png

#下面是最后的效果图(为展示效果估计关停了一个es服务):

image.png=>image.png

3.4 altermanager报警

#这个软件包里面带着例子呢,可以根据自己的实际情况设置报警,如软件包中的例子:

# alert if too few nodes are running
ALERT ElasticsearchTooFewNodesRunning
  IF elasticsearch_cluster_health_number_of_nodes < 3
  FOR 5m
  LABELS {severity="critical"}
  ANNOTATIONS {description="There are only {{$value}} < 3 ElasticSearch nodes running", summary="ElasticSearch running on less than 3 nodes"}

# alert if heap usage is over 90%
ALERT ElasticsearchHeapTooHigh
  IF elasticsearch_jvm_memory_used_bytes{area="heap"} / elasticsearch_jvm_memory_max_bytes{area="heap"} > 0.9
  FOR 15m
  LABELS {severity="critical"}
  ANNOTATIONS {description="The heap usage is over 90% for 15m", summary="ElasticSearch node {{$labels.node}} heap usage is high"}

四、Elasticsearch集群升级

官网地址:https://www.elastic.co/guide/en/elasticsearch/reference/current/setup-upgrade.html

4.1 官网翻译升级介绍

Elasticsearch通常可以使用滚动升级过程升级,因此升级不会中断服务。 支持滚动升级:在小版本之间从5.6到6.8,从6.8到7.14.0,对于主要版本(例如,5.6至6.8)之间的滚动升级,建议使用Kibana升级助手(https://www.elastic.co/guide/en/kibana/7.14/upgrade-assistant.html)。升级助手识别群集中已弃用的设置,并通过解决问题的过程指导你,包括reindexing。

image.png

#要从6.7或更早之前直接升级到7.14.0,必须关闭群集,安装7.14.0并重新启动。

       Elasticsearch可以读取在以前的主要版本中创建的索引。 如果你有5.x或以前在5.x中创建了索引,则必须在升级到7.14.0之前reindex或删除它们。 如果存在不兼容的指标,Elasticsearch nodes将无法启动。 即使由6.x群集创建,也无法将5.x或更早版本的索引恢复到7.x群集。 有关升级旧指数的信息,请参阅reindex升级。升级到Elasticsearch的新版本时,您需要升级Elastic Stack中的每个产品。

4.2 跟着官网滚动升级下集群

       滚动升级允许一次升级Elasticsearch集群一次升级一个节点,因此升级不会中断服务。 不支持在同一群集中运行多个版本的Elasticsearch,超出升级的持续时间,因为不能从升级的节点复制碎片到运行旧版本的节点。官网强烈建议升级群集的节点将群集节点划分为以下两组,并按此顺序升级组:

1. 不符合master-eligible的节点。可以使用GET /_nodes/_all,master:false或通过查找配置的所有节点来检索这些节点的列表。
2. Master-eligible节点,即剩余节点。 可以使用GET /_nodes/master:true。

可以按任何顺序升级每个组中的每个组内的节点。

      以此顺序升级节点可确保主设备且始终运行一个版本,至少是新的作为主符合条件的节点。 较新的节点总是可以与旧主机一起加入群集,但较旧的节点不能总是与较新的主站联接群集。 通过升级master-eligible条件的节点,可以确保所有主统计资格的节点都能够加入群集,无论是否已升级主符合资格的节点。 如果在主统计资格的节点之前升级任何主符合条件的节点,那么旧节点将离开群集的风险将无法重新加入,直到它们升级到升级。

准备升级

       在开始升级之前仔细准备很重要。 一旦开始将群集升级到版本7.14.0,必须完成升级。 一旦群集包含版本7.14.0的节点,它可能会更改其内部状态无法恢复。 如果无法完成升级,则应丢弃部分升级的群集,请在升级之前部署一个空群集,并从快照中恢复其内容。

     在开始将群集升级到版本7.14.0之前,你应该执行以下操作。

1. 检查弃用日志以查看您是否使用任何已弃用功能并相应地更新代码。
2. 查看Breaking更改,并对版本7.14.0进行对代码和配置进行必要的更改。
3. 如果使用任何插件,请确保有一个版本的每个插件,它与Elasticsearch版本7.14.0兼容。
4. 在升级生产群集之前在孤立环境中测试升级。
5. 通过拍摄快照备份你的数据!

升级Clusteredit

禁用分片分配

关闭数据节点时,分配过程等待index.unassigned.node_left.delayed_timeout(默认情况下,一分钟)在开始将该节点上的分片复制到群集中的其他节点之前,这可能涉及我很多I/O。 由于节点很快将重新启动,因此不需要此I/O. 可以通过在关闭数据节点之前禁用副本的分配来避免clock。

PUT _cluster/settings{
  "persistent": {
    "cluster.routing.allocation.enable": "primaries"
  }}

image.png

关闭一个节点并升级其软件包和插件

#kill掉一个Node节点上面的服务

#然后下载最新的软件包,使用elasticsearch-plugin把插件升级为最新的插件,并把elasticsearch.yml和jvm.options设置成跟原来一致。

# curl -X GET 'http://192.168.1.164:9200/_cat/nodes?v'   #可以看到升级的Node节点已经加入进集群了

启用分片分配

对于数据节点,一旦节点已加入群集,请删除cluster.routing.allocation.Enable设置以启用分片分配并使用该节点开始:

# curl -H "Content-Type: application/json" -XPUT 'http://192.168.1.164:9200/_cluster/settings' -d '{"persistent": {"cluster.routing.allocation.enable": null}}'

{"acknowledged":true,"persistent":{},"transient":{}}

# curl -XGET "http://192.168.1.164:9200/_cluster/health?pretty=true"  #过一段时间可以看到staus变成了green了。

在滚动升级期间,分配给运行新版本的节点的主要分片不能将其副本分配给具有旧版本的节点。 新版本可能具有旧版本不了解的不同数据格式。如果无法将副本分配给另一个节点(群集中只有一个升级的节点),则副本分片仍保持未分配,状态保持黄色。在这种情况下,一旦没有初始化或重新分配碎片(检查init和Relo列),就可以继续。一旦升级另一个节点,可以分配副本,并且状态将更改为绿色。

#然后其他节点重复此操作就行版本升级就可以了。都升级完了检查下health状态没问题es版本就算升级完了,就要升级其他产品了。kibana的升级记得别乱删索引,kibana做的那些图标啥的设置都在.kibana开头的索引里面呢,不然要悲剧了。

kibana的升级链接:https://www.elastic.co/guide/en/kibana/current/upgrade.html

五、官网翻译一些索引的简单操作(可直接忽略)

5.1 索引的操作

创建一个索引:

现在让我们创建一个名为“customer”的索引,然后再列出所有的索引:

PUT /customer?pretty
GET /_cat/indices?v

#第一个命令使用PUT动词创建名为“customer”的索引。 我们只是简单地追加到调用结束,告诉它漂亮地打印JSON响应(如果有的话)。结果是:

health status index    uuid                   pri rep docs.count docs.deleted store.size pri.store.size
yellow open   customer 95SQ4TSUT7mWBT7VNHH67A   5   1          0            0       260b           260b

#第二个命令的结果告诉我们,现在我们有一个名为customer的索引,它有5个主分片和1个副本(默认值),它包含0个文档。可能还会注意到,客户索引标有黄色的健康状况。 回想一下我们之前的讨论,黄色意味着一些复制品还没有被分配。 这个索引发生的原因是因为Elasticsearch默认为这个索引创建了一个副本。由于此刻我们只有一个节点正在运行,因此,在另一个节点加入集群的较晚时间点之前,尚无法分配一个副本(以获得高可用性)。 一旦该副本被分配到第二个节点上,该索引的健康状态将变成绿色。

索引和查询文档

现在让我们把东西放入我们的客户索引。 我们会将一个简单的客户文档编入客户索引,ID为1,如下所示:

PUT /customer/doc/1?pretty
{
  "name": "John Doe"
}

结果是:

{
  "_index" : "customer",
  "_type" : "doc",
  "_id" : "1",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 0,
  "_primary_term" : 1
}

从上面我们可以看到客户索引里面成功创建了一个新的客户文档。 该文件也有一个我们在索引时间指定的内部ID。

请注意,Elasticsearch不需要你先指定文档,然后再明确地创建一个索引。 在前面的例子中,Elasticsearch将自动创建客户索引,如果事先不存在的话。现在我们来检索我们刚编入索引的那个文档:

GET /customer/doc/1?pretty

结果是:

{
  "_index" : "customer",
  "_type" : "doc",
  "_id" : "1",
  "_version" : 1,
  "found" : true,
  "_source" : { "name": "John Doe" }
}

#没有什么比这里发现的字段,发现,我们发现一个文件与所要求的ID 1和另一个field, _source,它返回从上一步索引完整的JSON文档。

删除索引

现在让我们删除刚刚创建的索引,然后再次列出所有索引:

DELETE /customer?pretty
GET /_cat/indices?v

结果是:

health status index uuid pri rep docs.count docs.deleted store.size pri.store.size

这意味着索引已经成功删除了,现在我们回到我们在集群中没有任何东西的地方。在我们继续之前,让我们再仔细看看迄今为止学到的一些API命令:

PUT /customer
PUT /customer/doc/1
{
  "name": "John Doe"
}
GET /customer/doc/1
DELETE /customer

如果我们仔细研究上面的命令,我们实际上可以看到我们如何在Elasticsearch中访问数据的模式。 这种模式可以概括如下:

<REST Verb> /<Index>/<Type>/<ID>

#这种REST访问模式在所有的API命令中都非常普遍,如果你能简单地记住它,你将在掌握Elasticsearch方面有一个良好的开端。

5.2 修改数据

      Elasticsearch几乎实时提供数据操作和搜索功能。 默认情况下,从索引/更新/删除数据开始,直到搜索结果中显示的时间为止,你可以预期会有一秒的延迟(刷新间隔)。 这是与SQL等其他平台的重要区别,其中数据在交易完成后立即可用。

索引/替换文档

我们以前看过我们如何索引一个文档。 让我们再次回忆起那个命令:

PUT /customer/doc/1?pretty
{
  "name": "John Doe"
}

再次,上面将索引指定的文件到客户索引,ID为1.如果我们然后用不同的(或相同的)文件再次执行上述命令,Elasticsearch将取代(即重新索引) 现有的ID为1:

PUT /customer/doc/1?pretty
{
  "name": "Jane Doe"
}

以上将ID号为1的文档的名称从“John Doe”改为“Jane Doe”。 另一方面,如果我们使用不同的ID,则新文档将被索引,并且索引中已经存在的文档将保持不变。

PUT /customer/doc/2?pretty
{
  "name": "Jane Doe"
}

#以上索引ID为2的新文档。

索引时,ID部分是可选的。 如果未指定,Elasticsearch将生成一个随机ID,然后用它来索引文档。 Elasticsearch生成的实际ID(或者我们前面例子中明确指定的)会作为索引API调用的一部分返回。

下面这个例子展示了如何索引没有显式ID的文档:

POST /customer/doc?pretty
{
  "name": "Jane Doe"
}

#请注意,在上述情况下,我们使用POST动词而不是PUT,因为我们没有指定一个ID。

更新文档

      除了能够索引和替换文档之外,我们还可以更新文档。 请注意,虽然Elasticsearch实际上并没有在原地进行更新。 无论何时我们进行更新,Elasticsearch都会删除旧文档,然后索引一个新文档,一次性应用更新。

      此示例显示如何通过将名称字段更改为“Jane Doe”来更新以前的文档(ID为1):

POST /customer/doc/1/_update?pretty
{
  "doc": { "name": "Jane Doe" }
}

这个例子展示了如何通过改变名称字段为“Jane Doe”来更新我们以前的文档(ID为1),同时给它添加一个年龄字段:

POST /customer/doc/1/_update?pretty
{
  "doc": { "name": "Jane Doe", "age": 20 }
}

更新也可以通过使用简单的脚本来执行。 此示例使用脚本将年龄增加5:

POST /customer/doc/1/_update?pretty
{
  "script" : "ctx._source.age += 5"
}

#在上面的例子中,ctx._source引用了即将被更新的当前源文档。Elasticsearch提供了在给定查询条件(如SQL UPDATE-WHERE语句)的情况下更新多个文档的能力。 请参阅docs-by-query API(https://www.elastic.co/guide/en/elasticsearch/reference/6.0/docs-update-by-query.html)。

删除文档

删除文件相当简单。 此示例显示如何删除我们以前的客户,其ID为2:

DELETE /customer/doc/2?pretty

请参阅_delete_by_query API(https://www.elastic.co/guide/en/elasticsearch/reference/6.0/docs-delete-by-query.html)以删除与特定查询匹配的所有文档。 值得注意的是,删除整个索引而不是使用Delete By Query API删除所有文档会更有效率。

批处理

     除了能够索引,更新和删除单个文档外,Elasticsearch还提供了使用_bulk API批量执行上述任何操作的功能。 这个功能很重要,因为它提供了一个非常有效的机制,尽可能快地完成多个操作,尽可能少的网络往返。

     作为一个简单的例子,下面的调用在一个批量操作中索引两个文档(ID 1 - John Doe和ID 2 - Jane Doe):

POST /customer/doc/_bulk?pretty
{"index":{"_id":"1"}}
{"name": "John Doe" }
{"index":{"_id":"2"}}
{"name": "Jane Doe" }

      本示例更新第一个文档(ID为1),然后在一个批量操作中删除第二个文档(ID为2):

POST /customer/doc/_bulk?pretty
{"update":{"_id":"1"}}
{"doc": { "name": "John Doe becomes Jane Doe" } }
{"delete":{"_id":"2"}}

#请注意,对于删除操作,之后没有对应的源文档,因为删除操作只需要删除文档的标识。

批量API不会因其中一个操作失败而失败。 如果一个动作因任何原因失败,它将继续处理其余的动作。 批量API返回时,它将为每个操作提供一个状态(与发送的顺序相同),以便您可以检查特定操作是否失败。

博文来自:www.51niux.com

5.3 搜索你的数据

现在我们已经看到了一些基本知识,让我们尝试一下更加真实的数据集。 我准备了一个关于客户银行账户信息的虚构的JSON文档样本。 每个文档都有以下模式:

{
    "account_number": 0,
    "balance": 16623,
    "firstname": "Bradshaw",
    "lastname": "Mckenzie",
    "age": 29,
    "gender": "F",
    "address": "244 Columbus Place",
    "employer": "Euron",
    "email": "bradshawmckenzie@euron.com",
    "city": "Hobucken",
    "state": "CO"
}

#这些数据是使用www.json-generator.com/生成的,所以请忽略数据的实际值和语义,因为这些数据都是随机生成的。

加载示例数据集,可以从这里下载示例数据集(accounts.json)。 将其解压到我们当前的目录,并将其加载到我们的集群中,如下所示:

curl -H "Content-Type: application/json" -XPOST 'localhost:9200/bank/account/_bulk?pretty&refresh' --data-binary "@accounts.json"
curl 'localhost:9200/_cat/indices?v'

下面是结果:

health status index uuid                   pri rep docs.count docs.deleted store.size pri.store.size
yellow open   bank  l7sSYV2cQXmu6_4rJWVIww   5   1       1000            0    128.6kb        128.6kb

#这意味着我们只是成功将1000个文件批量索引到银行索引(在帐户类型下)。

搜索API

      有两种运行搜索的基本方法:一种是通过REST请求URI发送搜索参数,另一种是通过REST请求主体发送搜索参数。 请求主体方法允许你更具表现力,并以更易读的JSON格式定义你的搜索。 我们将尝试请求URI方法的一个例子,但在本教程的剩余部分中,我们将专门使用请求主体方法。

      用于搜索的REST API可从_search端点访问。 本示例返回银行索引中的所有文档:

GET /bank/_search?q=*&sort=account_number:asc&pretty

#我们首先解析搜索调用。 我们在银行索引中搜索(_search endpoint),并且q=*参数指示Elasticsearch匹配索引中的所有文档。 sort = account_number:asc参数指示使用每个文档的account_number字段按升序对结果进行排序。 漂亮的参数再次告诉Elasticsearch返回漂亮的JSON结果。下面是部分响应结果:

{
  "took" : 63,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 1000,
    "max_score" : null,
    "hits" : [ {
      "_index" : "bank",
      "_type" : "account",
      "_id" : "0",
      "sort": [0],
      "_score" : null,
      "_source" : {"account_number":0,"balance":16623,"firstname":"Bradshaw","lastname":"Mckenzie","age":29,"gender":"F","address":"244 Columbus Place","employer":"Euron","email":"bradshawmckenzie@euron.com","city":"Hobucken","state":"CO"}
    }, {
      "_index" : "bank",
      "_type" : "account",
      "_id" : "1",
      "sort": [1],
      "_score" : null,
      "_source" : {"account_number":1,"balance":39225,"firstname":"Amber","lastname":"Duke","age":32,"gender":"M","address":"880 Holmes Lane","employer":"Pyrami","email":"amberduke@pyrami.com","city":"Brogan","state":"IL"}
    }, ...
    ]
  }
}

至于回应,我们看到以下部分:

took    #Elasticsearch花费了几毫秒的时间来执行搜索
timed_out #告诉我们搜索是否超时
_shards   #告诉我们搜索了多少碎片,以及搜索碎片成功/失败的次数
hits  #搜索结果
hits.total #符合我们搜索条件的文档总数
hits.hits   #实际的搜索结果数组(默认为前10个文档)
hits.sort   #结果排序键(按分数排序时缺失)
hits._score和max_score #现在忽略这些字段

以上是使用替代请求主体方法的上述相同的确切搜索:

GET /bank/_search
{
  "query": { "match_all": {} },
  "sort": [
    { "account_number": "asc" }
  ]
}

#这里的区别在于,不是在URI中传递q=*,而是将JSON风格的查询请求主体发布到_search API。

#重要的是要明白,一旦你得到你的搜索结果,Elasticsearch完成与请求,并没有维护任何种类的服务器端资源或打开游标到你的结果。 这与许多其他平台(如SQL)形成鲜明对比,其中最初可能会首先获得查询结果的部分子集,然后如果要获取(或翻阅)其余部分,则必须连续返回到服务器的结果使用某种有状态的服务器端游标。

介绍查询语句

     Elasticsearch提供了一种JSON风格的域特定语言,可以用来执行查询。 这被称为查询DSL。 查询语言非常全面,可以乍一看吓人,但实际学习的最好方法是从几个基本的例子开始。回到我们的最后一个例子,我们执行了这个查询:

GET /bank/_search
{
  "query": { "match_all": {} }
}

#解析上述内容,查询部分告诉我们我们的查询定义是什么,match_all部分只是我们想要运行的查询的类型。 match_all查询只是搜索指定索引中的所有文档。

     除查询参数外,我们还可以传递其他参数来影响搜索结果。 在上面的例子中我们通过sort,在这里我们传递的size:

GET /bank/_search
{
  "query": { "match_all": {} },
  "size": 1   #请注意,如果未指定大小,则默认为10。
}

下面这个例子做一个match_all并返回文档11到20:

GET /bank/_search
{
  "query": { "match_all": {} },
  "from": 10,
  "size": 10
}

#from参数(从0开始)指定从哪个文档索引开始,size参数指定从from参数开始返回多少个文档。 在实现分页搜索结果时,此功能非常有用。 请注意,如果from不指定,则默认为0。

下面这个例子做了一个match_all,以降序的方式对结果进行排序,并返回前10(默认大小)文档。

GET /bank/_search
{
  "query": { "match_all": {} },
  "sort": { "balance": { "order": "desc" } }
}

执行搜索

      现在我们已经看到了一些基本的搜索参数,让我们再深入查询DSL。 我们先来看看返回的文档字段。 默认情况下,完整的JSON文档作为所有搜索的一部分返回。 这被称为源(搜索匹配中的_source字段)。 如果我们不希望整个源文档返回,我们有能力只需要返回源内的几个字段。

      此示例显示如何从搜索中返回两个字段account_number和balance(在_source之内):

GET /bank/_search
{
  "query": { "match_all": {} },
  "_source": ["account_number", "balance"]
}

#请注意,上面的例子简单地减少了_source字段。 它仍然只会返回一个名为_source的字段,但在其中只包含字段account_number和balance。

#现在我们来看看查询部分。 以前,我们已经看过如何使用match_all查询来匹配所有文档。 现在我们来介绍一个称为匹配查询的新查询,它可以被看作是一个基本的搜索查询(即针对特定字段或字段集合进行的搜索)。此示例返回编号为20的帐户:

GET /bank/_search
{
  "query": { "match": { "account_number": 20 } }
}

此示例返回地址中包含术语“mill”的所有帐户:

GET /bank/_search
{
  "query": { "match": { "address": "mill" } }
}

此示例返回地址中包含“mill”或“lane”的所有帐户:

GET /bank/_search
{
  "query": { "match": { "address": "mill lane" } }
}

这个例子是match(match_短语)的变体,它返回包含在地址中的“mill lane”的所有帐户:

GET /bank/_search
{
  "query": { "match_phrase": { "address": "mill lane" } }
}

bool查询允许我们使用布尔逻辑将更小的查询组合成更大的查询。此示例组成两个匹配查询,并返回地址中包含“mill”和“lane”的所有帐户:

GET /bank/_search
{
  "query": {
    "bool": {
      "must": [
        { "match": { "address": "mill" } },
        { "match": { "address": "lane" } }
      ]
    }
  }
}

#在上面的例子中,bool must子句指定了一个文档被认为是匹配的所有查询。

#相反,这个例子组成两个匹配查询,并返回地址中包含“mill”或“lane”的所有帐户:

GET /bank/_search
{
  "query": {
    "bool": {
      "should": [
        { "match": { "address": "mill" } },
        { "match": { "address": "lane" } }
      ]
    }
  }
}

#在上面的例子中,bool should子句指定了一个查询列表,其中任何一个查询都必须是真的才能被认为是匹配的文档。

本示例组成两个匹配查询,并返回地址中既不包含“mill”也不包含“lane”的所有帐户:

GET /bank/_search
{
  "query": {
    "bool": {
      "must_not": [
        { "match": { "address": "mill" } },
        { "match": { "address": "lane" } }
      ]
    }
  }
}

#在上面的例子中,bool must_not子句指定了一个查询列表,其中任何一个查询都不可以被认为是匹配的。

可以在一个bool查询中同时结合must,should和must_not子句。 此外,可以在任何这些bool子句中编写布尔查询来模拟任何复杂的多级布尔逻辑。这个例子返回所有40岁但不是ID(aho)的人的账号:

GET /bank/_search
{
  "query": {
    "bool": {
      "must": [
        { "match": { "age": "40" } }
      ],
      "must_not": [
        { "match": { "state": "ID" } }
      ]
    }
  }
}

执行过滤器

      在前一节中,我们跳过了一个小细节,称为文档score(搜索结果中的_score字段)。分数是一个数字值,它是对文档与我们指定的搜索查询匹配程度的相对度量。分数越高,文档越相关,分数越低,文档的相关性越小。

      但是查询并不总是需要产生分数,特别是当它们仅用于“过滤”文档集时。弹性搜索可以检测到这些情况,并自动优化查询执行,而不是计算无用的分数。

      我们在前一节介绍的bool查询还支持过滤子句,它允许使用查询来限制将被其他子句匹配的文档,而不改变计算得分的方式。 作为一个例子,我们来介绍一下范围查询,它允许我们通过一系列值来过滤文档。 这通常用于数字或日期过滤。

      本示例使用bool查询返回余额在20000和30000之间的所有帐户。 换句话说,我们要查找大于或等于20000且小于等于30000的帐户。

GET /bank/_search
{
  "query": {
    "bool": {
      "must": { "match_all": {} },
      "filter": {
        "range": {
          "balance": {
            "gte": 20000,
            "lte": 30000
          }
        }
      }
    }
  }
}

#解析上述内容,bool查询包含一个match_all查询(查询部分)和一个范围查询(过滤器部分)。 我们可以将其他查询替换为查询和过滤器部分。 在上述情况中,范围查询是非常有意义的,因为落入该范围的文档全部匹配“平等”,即没有文档比另一个更相关。

除了match_all,match,bool和range查询之外,还有很多其他查询类型可用,我们不会在这里介绍它们。 由于我们已经对其工作原理有了一个基本的了解,所以将这些知识应用于其他查询类型的学习和实验并不难。

执行聚合

      聚合提供了从数据中分组和提取统计数据的能力。考虑聚合的最简单方法是将其大致等同于SQL GROUP BY和SQL聚合函数。 在Elasticsearch中,你可以执行搜索并返回匹配,同时还可以在一个响应中返回与匹配不同的聚合结果。 这是非常强大和高效的,因为可以运行查询和多个聚合,并一次性获得两个(或两个)操作的结果,从而避免使用简洁和简化的API进行网络往返。

     首先,本示例按状态对所有帐户进行分组,然后返回按降序(也是默认值)排序的前10个(默认)状态:

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "group_by_state": {
      "terms": {
        "field": "state.keyword"
      }
    }
  }
}

在SQL中,上面的聚合在概念上类似于:

SELECT state, COUNT(*) FROM bank GROUP BY state ORDER BY COUNT(*) DESC

下面是部分显示:

{
  "took": 29,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped" : 0,
    "failed": 0
  },
  "hits" : {
    "total" : 1000,
    "max_score" : 0.0,
    "hits" : [ ]
  },
  "aggregations" : {
    "group_by_state" : {
      "doc_count_error_upper_bound": 20,
      "sum_other_doc_count": 770,
      "buckets" : [ {
        "key" : "ID",
        "doc_count" : 27
      }, {
        "key" : "TX",
        "doc_count" : 27
      }, {

请注意,我们将size = 0设置为不显示搜索命中,因为我们只想看到响应中的聚合结果。在前面的汇总基础上,本示例按状态计算平均账户余额(再次仅按前几位按降序排列的状态):

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "group_by_state": {
      "terms": {
        "field": "state.keyword"
      },
      "aggs": {
        "average_balance": {
          "avg": {
            "field": "balance"
          }
        }
      }
    }
  }
}

注意我们如何在group_by_state聚合内嵌套average_balance聚合。这是所有聚合的常见模式。你可以任意地在聚合中嵌套聚合,以从数据中提取所需的pi表决摘要。在前面的集合上建立,现在让我们按降序排列平均余额:

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "group_by_state": {
      "terms": {
        "field": "state.keyword",
        "order": {
          "average_balance": "desc"
        }
      },
      "aggs": {
        "average_balance": {
          "avg": {
            "field": "balance"
          }
        }
      }
    }
  }
}

下面这个例子演示了我们如何按年龄段(20-29岁,30-39岁和40-49岁)进行分组,然后按性别进行分组,然后最终得到每个性别的年龄段平均账户余额:

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "group_by_age": {
      "range": {
        "field": "age",
        "ranges": [
          {
            "from": 20,
            "to": 30
          },
          {
            "from": 30,
            "to": 40
          },
          {
            "from": 40,
            "to": 50
          }
        ]
      },
      "aggs": {
        "group_by_gender": {
          "terms": {
            "field": "gender.keyword"
          },
          "aggs": {
            "average_balance": {
              "avg": {
                "field": "balance"
              }
            }
          }
        }
      }
    }
  }
}

#更多的聚合功能:https://www.elastic.co/guide/en/elasticsearch/reference/6.0/search-aggregations.html

作者:忙碌的柴少 分类:ELK 浏览:9027 评论:0
留言列表
发表评论
来宾的头像