晓我课堂

Elasticsearch初探

2022-02-23  本文已影响0人  wavefreely

Elasticsearch是什么

Elasticsearch是一个基于Apache Lucene(TM)的一个分布式的开源搜索和分析引擎

Elasticsearch实现的功能

使用场景

全文搜索方案对比

两者者之间的一个联系:solr和Elasticsearch都是基于Lucene实现的

区别:

核心概念

索引(index)

ElasticSearch将它的数据存储在一个或多个索引(index)中。用SQL领域的术语来类比,索引就像数据库,可以向索引写入文档或者从索引中读取文档,并通过ElasticSearch内部使用Lucene将数据写入索引或从索引中检索数据。

类型(type)

类型是模拟mysql中的table概念,一个索引库下可以有不同类型的索引,比如商品索引,订单索引,其数据格式不同。不过这会导致索引库混乱,因此未来版本中会移除这个概念

ES中每个大版本的type类型有很大区别

ES 5.x 中index可以又多种type

ES 6.x 中一个index只能有一个type

ES 7.x以后要逐渐移除这个概念

文档(document)

文档(document)是ElasticSearch中的主要实体。对所有使用ElasticSearch的案例来说,他们最终都可以归结为对文档的搜索。文档由字段构成。

在一个index/type里面,你可以存储任意多的文档。注意,尽管一个文档,物理上存在于一个索引之中,文档必须被索引/赋予一个索引的type。

字段Field

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

映射 mapping

mapping就相当于我们关系型数据库中的表结构,是处理数据的方式和规则方面做一些限制,如某个字段的数据类型、默认值、分析器、是否被索引等等,这些都是映射里面可以设置的,其它就是处理es里面数据的一些使用规则设置也叫做映射,按着最优规则处理数据对性能提高很大,因此才需要建立映射,并且需要思考如何建立映射才能对性能更好。

集群 cluster

一个集群就是由一个或多个节点组织在一起,它们共同持有整个的数据,并一起提供索引和搜索功能。一个集群由一个唯一的名字标识,这个名字默认就是“elasticsearch”。这个名字是重要的,因为一个节点只能通过指定某个集群的名字,来加入这个集群

可以通过get请求查看集群状态:

http://es地址:9200/_cat/health?v

返回数据:

epoch      timestamp cluster status node.total node.data shards pri relo init unassign pending_tasks max_task_wait_time active_shards_percent
1645155625 11:40:25  sxjyes  green           3         3    252 126    0    0        0             0                  -                100.0%

参数说明:

cluster:集群名称
status:集群状态 green代表健康;yellow代表分配了所有主分片,但至少缺少一个副本,此时集群数据仍旧完整;red代表部分主分片不可用,可能已经丢失数据。
node.total:代表在线的节点总数量
node.data:代表在线的数据节点的数量
shards, active_shards: 存活的分片数量
pri,active_primary_shards: 存活的主分片数量 正常情况下 shards的数量是pri的两倍。
relo, relocating_shards :迁移中的分片数量,正常情况为 0
init, initializing_shards: 初始化中的分片数量 正常情况为 0
unassign, unassigned_shards: 未分配的分片 正常情况为 0
pending_tasks:准备中的任务,任务指迁移分片等 正常情况为 0
max_task_wait_time:任务最长等待时间
active_shards_percent:正常分片百分比 正常情况为 100%

节点 node

一个节点是集群中的一个服务器,作为集群的一部分,它存储数据,参与集群的索引和搜索功能。和集群类似,一个节点也是由一个名字来标识的,默认情况下,这个名字是一个随机的漫威漫画角色的名字,这个名字会在启动的时候赋予节点。这个名字对于管理工作来说挺重要的,因为在这个管理过程中,你会去确定网络中的哪些服务器对应于Elasticsearch集群中的哪些节点。

一个节点可以通过配置集群名称的方式来加入一个指定的集群。默认情况下,每个节点都会被安排加入到一个叫做“elasticsearch”的集群中,这意味着,如果你在你的网络中启动了若干个节点,并假定它们能够相互发现彼此,它们将会自动地形成并加入到一个叫做“elasticsearch”的集群中。

在一个集群里,只要你想,可以拥有任意多个节点。而且,如果当前你的网络中没有运行任何Elasticsearch节点,这时启动一个节点,会默认创建并加入一个叫做“elasticsearch”的集群。

分片和复制 shards&replicas

一个索引可以存储超出单个结点硬件限制的大量数据。比如,一个具有10亿文档的索引占据1TB的磁盘空间,而任一节点都没有这样大的磁盘空间;或者单个节点处理搜索请求,响应太慢。为了解决这个问题,Elasticsearch提供了将索引划分成多份的能力,这些份就叫做分片。当你创建一个索引的时候,你可以指定你想要的分片的数量。每个分片本身也是一个功能完善并且独立的“索引”,这个“索引”可以被放置到集群中的任何节点上。分片很重要,主要有两方面的原因:
1)允许你水平分割/扩展你的内容容量。
2)允许你在分片(潜在地,位于多个节点上)之上进行分布式的、并行的操作,进而提高性能/吞吐量。

至于一个分片怎样分布,它的文档怎样聚合回搜索请求,是完全由Elasticsearch管理的,对于作为用户的你来说,这些都是透明的。

在一个网络/云的环境里,失败随时都可能发生,在某个分片/节点不知怎么的就处于离线状态,或者由于任何原因消失了,这种情况下,有一个故障转移机制是非常有用并且是强烈推荐的。为此目的,Elasticsearch允许你创建分片的一份或多份拷贝,这些拷贝叫做复制分片,或者直接叫复制。

复制之所以重要,有两个主要原因: 在分片/节点失败的情况下,提供了高可用性。因为这个原因,注意到复制分片从不与原/主要(original/primary)分片置于同一节点上是非常重要的。扩展你的搜索量/吞吐量,因为搜索可以在所有的复制上并行运行。总之,每个索引可以被分成多个分片。一个索引也可以被复制0次(意思是没有复制)或多次。一旦复制了,每个索引就有了主分片(作为复制源的原来的分片)和复制分片(主分片的拷贝)之别。分片和复制的数量可以在索引创建的时候指定。在索引创建之后,你可以在任何时候动态地改变复制的数量,但是你事后不能改变分片的数量。

默认情况下,Elasticsearch中的每个索引被分片5个主分片和1个复制,这意味着,如果你的集群中至少有两个节点,你的索引将会有5个主分片和另外5个复制分片(1个完全拷贝),这样的话每个索引总共就有10个分片。

Elasticsearch概念和关系型数据库的对比

关系型数据库(如mysql) Elasticsearch
数据库 索引index
表(table) 索引index类型(原为type)
数据行row 文档(document)
数据列(column) 字段Field
约束 schema 映射 mapping

字段类型

字段类型分为基本类型和复合类型‘

基本类型

字符串类型
数字类型

数字类型有long、integer、short、byte、double、float、half_float、scaled_float。

日期类型

由于 JSON 中没有日期类型,所以 es 中的日期类型形式就比较多样:2020-11-11 或者 2020-11-11 11:11:11,一个从 1970.1.1 零点到现在的一个秒数或者毫秒数。es 内部将时间转为 UTC,然后将时间按照 millseconds-since-the-epoch 的长整型来存储。

boolean类型

逻辑类型(布尔类型)可以接受true/false/”true”/”false”值

二进制类型(binary)

二进制字段是指用base64来表示索引中存储的二进制数据,可用来存储二进制形式的数据,例如图像。默认情况下,该类型的字段只存储不索引。二进制类型只支持index_name属性。

范围类型(range)

数据范围类型,一个字段表示一个范围,具体包含以下类型:

所谓的范围类型,就是一个值自身就表明一个范围,如:

PUT range_index
 {
   "mappings": {
     "_doc": {
       "properties": {
        "expected_attendees": {
           "type": "integer_range"
        }
      }
   }
  }
}

复合类型

数组类型(array)

es 中没有专门的数组类型。默认情况下,任何字段都可以有一个或者多个值。需要注意的是,数组中的元素必须是同一种类型。添加数组是,数组中的第一个元素决定了整个数组的类型。

对象类型(object)

由于 JSON 本身具有层级关系,所以文档包含内部对象。内部对象中,还可以再包含内部对象。

IK分词器

Elasticsearch自带的标准分词器是针对英文的,所以我们在日常开发中都是使用ik分词器,它是一个针对中文的分词器。

从2016年12月推出1.0版本开始,IKAnalyzer已经推出了三个大版本,最初他是以开源项目Lucene为应用主题的,结合词典分词和文法分析算法的中文分词组件,新版的IKAnalyzer3.0则发展为面向java的公用分词组件,独立于Lucene项目,同时提供了对Lucene的默认优化实现

IKAnalyzer3.0版本特性如下:

IK分词器有两种分词模式:ik_max_word和ik_smart模式。

ik_max_word

会将文本做最细粒度的拆分,比如会将“中华人民共和国人民大会堂”拆分为“中华人民共和国、中华人民、中华、华人、人民共和国、人民、共和国、大会堂、大会、会堂等词语。

ik_smart

会做最粗粒度的拆分,比如会将“中华人民共和国人民大会堂”拆分为中华人民共和国、人民大会堂。

IK分词器扩展词典

停用词扩展
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
        <comment>IK Analyzer 扩展配置</comment>
        <!--用户可以在这里配置自己的扩展字典 -->
        <entry key="ext_dict">ext_dic.dic</entry>
         <!--用户可以在这里配置自己的扩展停止词字典-->
        <entry key="ext_stopwords"></entry>
        <!--用户可以在这里配置远程扩展字典 -->
        <!-- <entry key="remote_ext_dict">words_location</entry> -->
        <!--用户可以在这里配置远程扩展停止词字典-->
        <!-- <entry key="remote_ext_stopwords">words_location</entry> -->
</properties>
<entry key="ext_stopwords">my_ext_stopword.dic</entry>
扩展字典
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
        <comment>IK Analyzer 扩展配置</comment>
        <!--用户可以在这里配置自己的扩展字典 -->
        <entry key="ext_dict">ext_dic.dic</entry>
         <!--用户可以在这里配置自己的扩展停止词字典-->
        <entry key="ext_stopwords"></entry>
        <!--用户可以在这里配置远程扩展字典 -->
        <!-- <entry key="remote_ext_dict">words_location</entry> -->
        <!--用户可以在这里配置远程扩展停止词字典-->
        <!-- <entry key="remote_ext_stopwords">words_location</entry> -->
</properties>
<entry key="ext_dict">my_ext_dict.dic</entry>
同义词词典

Elasticsearch 自带一个名为 synonym 的同义词 filter。为了能让 IK 和 synonym 同时工作,我们需要定义新的 analyzer,用 IK 做 tokenizer,synonym 做 filter。

index:  
  analysis:  
    analyzer:  
      ik_syno:  
          type: custom  
          tokenizer: ik_max_word  
          filter: [my_synonym_filter]  
      ik_syno_smart:  
          type: custom  
          tokenizer: ik_smart  
          filter: [my_synonym_filter]  
    filter:  
      my_synonym_filter:  
          type: synonym  
          synonyms_path: analysis/synonym.txt  

以上配置定义了 ik_syno 和 ik_syno_smart 这两个新的 analyzer,分别对应 IK 的 ik_max_word 和 ik_smart 两种分词策略

上一篇 下一篇

猜你喜欢

热点阅读