1.数据聚合

1.1.聚合的种类

聚合常见的有三类:
1.桶(Bucket)聚合:用来对文档分组
TermAggregation:按照文档字段值分组
Date Histogram:按照日期阶梯分组
2.度量(Metric)聚合:用以计算一些值,比如:最大值(Max)最小值(Min)平均值(Avg)
Stats:同时求max、min、avg、sum等
3.管道(pipeline)聚合:其他聚合的结果为基础做聚合
注意:参加聚合的字段必须是keyword、日期、数值、布尔类型

1.2.DSL实现聚合

举例:要统计所有数据中的酒店品牌有几种,其实就是按照品牌对数据分组。此时可以根据酒店品牌的名称做聚合,也就是Bucket聚合。

image.pngimage.png

1.2.2.聚合结果排序

默认情况下,Bucket聚合会统计Bucket内的文档数量,记为_count,并且按照_count降序排序。
我们可以指定order属性,自定义聚合的排序方式
image.png

1.2.3.限定聚合范围

只要添加query条件
image.png

1.2.4.Metric聚合语法

stat聚合:可以获取min、max、avg等结果

这次的score_stats聚合是在brandAgg的聚合内部嵌套的子聚合。因为我们需要在每个桶分别计算。
image.png
还可以给聚合结果做个排序,例如按照每个桶的酒店平均分做排序
image.png

1.3.RestAPI实现聚合

1.3.1.API语法

聚合条件与query条件同级别,因此需要使用request.source()来指定聚合条件。
聚合条件的语法
image.png
聚合的结果也与查询结果不同,API也比较特殊。不过同样是JSON逐层解析
image.png

2.自动补全

2.1.自定义分词器

elasticsearch中分词器(analyzer)的组成包含三部分:

  • character filters:在tokenizer之前对文本进行处理。例如删除字符、替换字符
  • tokenizer:将文本按照一定的规则切割成词条(term)。例如keyword,就是不分词;还有ik_smart
  • tokenizer filter:将tokenizer输出的词条做进一步处理。例如大小写转换、同义词处理、拼音处理等

    2.2.自动补全查询

    elasticsearch提供了Completion Suggester查询来实现自动补全功能。这个查询会匹配以用户输入内容开头的词条并返回。为了提高补全查询的效率,对于文档中字段的类型有一些约束

  • 参与补全查询的字段必须是completion类型。

  • 字段的内容一般是用来补全的多个词条形成的数组。

image.png
image.png

3.数据同步

3.1.思路分析

常见的数据同步方案有三种:

  • 同步调用
  • 异步通知
  • 监听binlog

    3.1.1.同步调用

    image.png

    3.1.2.异步通知

    image.png

    3.1.3.监听binlog

    image.png

    3.1.4.选择

    方式一:同步调用

  • 优点:实现简单,粗暴

  • 缺点:业务耦合度高

方式二:异步通知

  • 优点:低耦合,实现难度一般
  • 缺点:依赖mq的可靠性

方式三:监听binlog

  • 优点:完全解除服务间耦合
  • 缺点:开启binlog增加数据库负担、实现复杂度高

    4.集群

    单机的elasticsearch做数据存储,必然面临两个问题:海量数据存储问题、单点故障问题。

  • 海量数据存储问题:将索引库从逻辑上拆分为N个分片(shard),存储到多个节点

  • 单点故障问题:将分片数据在不同节点备份(replica )

ES集群相关概念:

  • 集群(cluster):一组拥有共同的 cluster name 的 节点。
  • 节点(node) :集群中的一个 Elasticearch 实例
  • 分片(shard):索引可以被拆分为不同的部分进行存储,称为分片。在集群环境下,一个索引的不同分片可以拆分到不同的节点中
  • image.png
  • 主分片(Primary shard):相对于副本分片的定义。
  • 副本分片(Replica shard)每个主分片可以有一个或者多个副本,数据和主分片一样。

数据备份可以保证高可用,但是每个分片备份一份,所需要的节点数量就会翻一倍,成本实在是太高了!
为了在高可用和成本间寻求平衡,我们可以这样做:
1) 首先对数据分片,存储到不同节点
2) 然后对每个分片进行备份,放到对方节点,完成互相备份
这样可以大大减少所需要的服务节点数量,如图,我们以3分片,每个分片备份一份为例:
image.png
现在,每个分片都有1个备份,存储在3个节点:

  • node0:保存了分片0和1
  • node1:保存了分片0和2
  • node2:保存了分片1和2

    4.1.集群脑裂问题

    4.1.1.集群职责划分

    elasticsearch中集群节点有不同的职责划分:
    image.png
    默认情况下,集群中的任何一个节点都同时具备上述四种角色
    但是真实的集群一定要将集群职责分离:

  • master节点:对CPU要求高,但是内存要求第

  • data节点:对CPU和内存要求都高
  • coordinating节点:对网络带宽、CPU要求高

职责分离可以让我们根据不同节点的需求分配不同的硬件去部署。而且避免业务之间的互相干扰。
一个典型的es集群职责划分如图:
image.png

4.1.2.脑裂问题

脑裂是因为集群中的节点失联导致的。
例如一个集群中,主节点与其它节点失联:
image.png
此时,node2和node3认为node1宕机,就会重新选主:
image.png
当node3当选后,集群继续对外提供服务,node2和node3自成集群,node1自成集群,两个集群数据不同步,出现数据差异。
当网络恢复后,因为集群中有两个master节点,集群状态的不一致,出现脑裂的情况:
image.png
解决脑裂的方案是,要求选票超过 ( eligible节点数量 + 1 )/ 2 才能当选为主,因此eligible节点数量最好是奇数。对应配置项是discovery.zen.minimum_master_nodes,在es7.0以后,已经成为默认配置,因此一般不会发生脑裂问题
例如:3个节点形成的集群,选票必须超过 (3 + 1) / 2 ,也就是2票。node3得到node2和node3的选票,当选为主。node1只有自己1票,没有当选。集群中依然只有1个主节点,没有出现脑裂。

4.2.集群分布式查询

elasticsearch的查询分成两个阶段:

  • scatter phase:分散阶段,coordinating node会把请求分发到每一个分片
  • gather phase:聚集阶段,coordinating node汇总data node的搜索结果,并处理为最终结果集返回给用户

    image.png

    4.3.集群故障转移

    集群的master节点会监控集群中的节点状态,如果发现有节点宕机,会立即将宕机节点的分片数据迁移到其它节点,确保数据安全,这个叫做故障转移。
    image.png
    image.png
    image.png
    image.png