Elasticsearch 集群与聚合

1. 聚合aggregations

Elasticsearch的聚合主要用于实现对数据的统计、分析,包含多种类型。

  • 一个为桶,类似于group by,表示按照某种方式对数据进行分组,每一组数据在ES中称为一个桶,划分桶的方式有多种
    • Date Histogram Aggregation:根据日期阶梯分组,例如给定阶梯为周,会自动每周分为一组
    • Terms Aggregation:根据词条内容分组,词条内容完全匹配的为一组
    • Range Aggregation:数值和日期的范围分组,指定开始和结束,然后按段分组
    • Histogram Aggregation:根据数值阶梯分组,与日期类似,需要知道分组的间隔(interval
  • 一个是度量,用于metrics aggregations,分组完成以后,一般会对组中的数据进行聚合运算,如求最大值、最小值、平均值等,这种聚合叫度量
    • Avg Aggregation:求平均值
    • Max Aggregation:求最大值
    • Min Aggregation:求最小值
    • Percentiles Aggregation:求百分比
    • Stats Aggregation:同时返回avgmaxminsumcount
    • Sum Aggregation:求和
    • Top hits Aggregation:求前几
    • Value Count Aggregation:求总数

  ES中,需要进行聚合、排序、过滤的字段其处理方式比较特殊,因此不能被分词,必须使用keyword 数值类型

数据准备:

1.1 聚合为桶

  • 按照汽车的颜色 color划分,使用TermAggregation类型,按照颜色的名称来分桶
    • size: 查询条数,这里设置为0,因为我们不关心搜索到的数据,只关心聚合结果,提高效率
    • aggs:声明这是一个聚合查询,是aggregations的缩写
    • popular_colors:给这次聚合起一个名字,可任意指定。
    • terms:聚合的类型,这里选择terms,是根据词条内容(这里是颜色)划分
    • field:划分桶时依赖的字段

      

 

 

 

    • hits:查询结果为空,因为我们设置了size0
    • aggregations:聚合的结果
    • popular_colors:我们定义的聚合名称
    • buckets:查找到的桶,每个不同的color字段值都会形成一个桶
      • key:这个桶对应的color字段的值
      • doc_count:这个桶中的文档数量

1.2 桶内度量

通常,我们的应用需要提供更复杂的文档度量度量的运算会基于内的文档进行,度量也是一个聚合

  • 为刚刚的聚合结果添加 求价格平均值的度量
    • aggs:我们在上一个aggs(popular_colors)中添加新的aggs
    • avg_price:聚合的名称
    • avg:度量的类型,这里是求平均值
    • field:度量运算的字段结果

   

 


可以看到每个桶中都有自己的 avg_price 字段,这是度量聚合的结果

2.Elasticsearch集群

2.1.单点的问题

  • 单台机器存储容量有限,无法实现高存储
  • 单服务器容易出现单点故障,无法实现高可用
  • 单服务的并发处理能力有限,无法实现高并发

2.2.集群的结构

  • 数据分片shard:单点存储量有限,可以把数据拆分成多份,每一份存储到不同机器节点(node),从而实现减少每个节点数据量的目的。这就是数据的分布式存储
  • 数据备份:单点故障问题,可以给每个分片数据进行备份,存储到其它节点,防止数据丢失,即数据副本
  • 数据备份可以保证高可用,但是每个分片备份一份,所需要的节点数量就会翻一倍,为了在高可用和成本间寻求平衡,首先对数据分片,存储到不同节点;然后对每个分片进行备份,放到对方节点,完成互相备份

 

 这样可以大大减少所需要的服务节点数量,如图,我们以3分片,每个分片备份一份为例:在这个集群中,如果出现单节点故障,并不会导致数据缺失,所以保证了集群的高可用,同时也减少了节点中数据存储量。并且因为是多个节点存储数据,因此用户请求也会分发到不同服务器,并发能力也得到了一定的提升。

 

2.3.搭建集群

用一台机器来模拟elasticsearch集群

  • 将我们的ES的安装包复制三份,修改端口号,datalog存放位置的不同,实际开发中:将每个ES节点放在不同的服务器上
  • 集群名称为:lagou-elastic,部署3elasticsearch节点,分别是
    • node-01http端口9201TCP端口9301
    • node-02http端口9202TCP端口9302
    • node-03http端口9203TCP端口9303
  • http:表示使用http协议进行访问时使用 端口,elasticsearch-headkibanapostman,默认端口号是9200
  • tcp:集群间的各个节点进行通讯的端口,默认9300

步骤

  • 复制es软件粘贴3次,分别改名

  • 修改每一个节点的配置文件 config下的elasticsearch.yml,依次修改
#允许跨域名访问
http.cors.enabled: true
#当设置允许跨域,默认为*,表示支持所有域名
http.cors.allow-origin: "*"
#允许所有节点访问
network.host: 0.0.0.0
# 集群的名称,同一个集群下所有节点的集群名称应该一致
cluster.name: lagou-elastic
#当前节点名称 每个节点不一样
node.name: node-01
#数据的存放路径 每个节点不一样,不同es服务器对应的data和log存储的路径不能一样
path.data: d:\class\es-9201\data
#日志的存放路径 每个节点不一样
path.logs: d:\class\es-9201\logs
# http协议的对外端口 每个节点不一样,默认:9200
http.port: 9201
# TCP协议对外端口 每个节点不一样,默认:9300
transport.tcp.port: 9301
#三个节点相互发现,包含自己,使用tcp协议的端口号
discovery.zen.ping.unicast.hosts:
["127.0.0.1:9301","127.0.0.1:9302","127.0.0.1:9303"]
#声明大于几个的投票主节点有效,请设置为(nodes / 2) + 1
discovery.zen.minimum_master_nodes: 2
# 是否为主节点
node.master: true
#允许跨域名访问
http.cors.enabled: true
http.cors.allow-origin: "*"
network.host: 0.0.0.0
# 集群的名称
cluster.name: lagou-elastic
#当前节点名称 每个节点不一样
node.name: node-02
#数据的存放路径 每个节点不一样
path.data: d:\class\es-9202\data
#日志的存放路径 每个节点不一样
path.logs: d:\class\es-9202\logs
# http协议的对外端口 每个节点不一样
http.port: 9202
# TCP协议对外端口 每个节点不一样
transport.tcp.port: 9302
#三个节点相互发现
discovery.zen.ping.unicast.hosts:
["127.0.0.1:9301","127.0.0.1:9302","127.0.0.1:9303"]
#声明大于几个的投票主节点有效,请设置为(nodes / 2) + 1
discovery.zen.minimum_master_nodes: 2
# 是否为主节点
node.master: true
#允许跨域名访问
http.cors.enabled: true
http.cors.allow-origin: "*"
network.host: 0.0.0.0
# 集群的名称
cluster.name: lagou-elastic
#当前节点名称 每个节点不一样
node.name: node-03
#数据的存放路径 每个节点不一样
path.data: d:\class\es-9203\data
#日志的存放路径 每个节点不一样
path.logs: d:\class\es-9203\logs
# http协议的对外端口 每个节点不一样
http.port: 9203
# TCP协议对外端口 每个节点不一样
transport.tcp.port: 9303
#三个节点相互发现
discovery.zen.ping.unicast.hosts:
["127.0.0.1:9301","127.0.0.1:9302","127.0.0.1:9303"]
#声明大于几个的投票主节点有效,请设置为(nodes / 2) + 1
discovery.zen.minimum_master_nodes: 2
# 是否为主节点
node.master: true
  • 三个节点的配置文件几乎一致,除了:node.namepath.datapath.loghttp.porttransport.tcp.port,记得去掉中文注释
  • 启动集群:把三个节点分别启动,启动时不要着急,要一个一个地启动
  • 使用head插件查看

 

2.4.测试集群中创建索引库

  •  修改head目录的vendor.js文件
    • 6886行   contentType: "application/x-www-form-urlencoded,改成:contentType: "application/json;charset=UTF-8"
    • 7574行 var inspectData = s.contentType === "application/x-www-form-urlencoded" &&,改成:var inspectData = s.contentType === "application/json;charset=UTF-8" &&
  • 建立索引,设置索引名称,分片数和副本

2.5.集群工作原理

  • shadreplica机制
    • 一个index包含多个shard,也就是一个index存在多个服务器上
    • 每个shard都是一个最小工作单元,承载部分数据,比如有三台服务器,现在有三条数据,这三条数据在三台服务器上各放置一条.
    • 增减节点时,shard会自动在nodes中负载均衡
    • primary shard(主分片)和replica shard(副本分片),每个document肯定只存在于某一个primary shard以及其对应的replica shard中,不可能存在于多个primary shard
    • replica shardprimary shard的副本,负责容错,以及承担读请求负载
    • primary shard的数量在创建索引的时候就固定了,replica shard的数量可以随时修改
    • primary shard的默认数量是5replica默认是1(每个主分片一个副本分片),默认有10个shard5primary shard5replica shard
    • primary shard不能和自己的replica shard放在同一个节点上(否则节点宕机,primary shard和副本都丢失,起不到容错的作用),但是可以和其他primary shardreplica shard放在同一个节点
  • 集群上写入数据
    • 客户端选择一个node发送请求过去,这个node就是coordinating node (协调节点)
    • coordinating node,对document进行路由,将请求转发给对应的node。(根据一定的算法选择对应的节点进行存储)
    •  实际上的node上的primary shard处理请求,将数据保存在本地,然后将数据同步到replica node
    •  coordinating node,如果发现primary node和所有的replica node都搞定之后,就会返回请求到客户端
    • 这个路由简单的说就是取模算法,比如说现在有3太服务器,这个时候传过来的id5,那么5%3=2,放在第2台服务器
  • ES查询数据
    • 倒排序算法:简单的说就是:通过分词把词语出现的id进行记录下来,再查询的时候先去查到哪id包含这个数据,然后再根据id把数据查出来
    • 客户端发送一个请求给coordinate node
    • 协调节点将搜索的请求转发给所有的shard对应的primary shard replica shard
    • query phase(查询阶段):每一个shard 将自己搜索的结果(其实也就是一些唯一标识),返回给协调节点,协调节点进行数据的合并,排序,分页等操作,产出最后的结果
    • fetch phase(获取阶段) ,接着由协调节点,根据唯一标识去各个节点进行拉取数据,最终返回给客户端

 

posted @ 2021-09-02 22:24  forever_fate  阅读(154)  评论(0)    收藏  举报