1、什么是Elasticsearch?

1.1、介绍

Elasticsearch(简称ES)是一个基于Apache Lucene构建的开源、分布式、RESTful接口的全文搜索引擎,Elasticsearch通过对Lunece的封装,隐藏了复杂性,提供了使用简单的RESTful Api。

Elasticsearch还是一个分布式文档数据库,其中每个字段均可被索引,而且每个字段的数据均可被搜索,因为对文档进行了分词处理。ES能够横向扩展至数以百计的服务器存储以及处理PB级的数据,可以在极短的时间内存储、搜索和分析大量的数据。

Elasticsearch 是用 Java 开发的,并作为 Apache 许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。

注:PB是数据存储容量的单位,它等于2的50次方个字节,或者在数值上大约等于1000个TB。

1.2、为什么要使用它

在业务开发中,基于ES的特性,通常有下面这些场景需要使用它:

  • 存储大量数据。通过在使用mysql存储的时候,数据的单位是G。使用ES的时候,数据的单位是T。由此可以看出ES使用于大数据量的存储场景,基于分布式特性,它也支持备份和容灾,并且可以很容易水平扩展容量。
  • 分词搜索引擎。ES具有强大的分词能力,可以支持高性能的实时搜索。
  • 高效数据分析。ES提供的聚合分析功能,可实现对保存的大量数据的近实时统计分析。

1.3、特性

  • 分布式的实时文件存储,每个字段都被索引并可被搜索;
  • 分布式的实时分析搜索引擎;
  • 可以扩展到成百上千台服务器,处理PB级结构化或非结构化数据。

1.4、使用场景

  • 搜索领域: 如百度、谷歌,全文检索等。
  • 门户网站: 访问统计、文章点赞、留言评论等。
  • 广告推广: 记录员工行为数据、消费趋势、员工群体进行定制推广等。
  • 信息采集: 记录应用的埋点数据、访问日志数据等,方便大数据进行分析。

1.5、ElasticSearch与Solr的比较

  • ES和Solr都是是基于Lucene的,它们都是成熟的产品,拥有强大而广泛的用户社区;
  • Solr 利用 Zookeeper 进行分布式管理,而 Elasticsearch 自身带有分布式协调管理功能;
  • Solr 支持更多格式的数据,而 Elasticsearch 仅支持json文件格式;
  • Solr 官方提供的功能更多,而 Elasticsearch 本身更注重于核心功能,高级功能多由第三方插件提供;
  • Solr 在传统的搜索应用中表现好于 Elasticsearch,但在处理实时搜索应用时效率明显低于 Elasticsearch。

2、elasticsearch相关概念

es底层无更新数据操作,上层封装的更新实际是删除后再新增。

ES 和传统的关系型数据库有这么一种关系:

RDMS Elasticsearch
数据库(database) 索引(index)
表(table) 类型(type)
行(row) 文档(document)
列(column) 字段(field)
表结构 映射
索引 全文索引
SQL 查询DSL
SELECT * FROM tablename GET http://...
UPDATE table SET PUT http://...
DELETE DELETE http://...

Elasticsearch是面向文档型数据库,一条数据在这里就是一个文档,用JSON作为文档序列化的格式,比如下面这条用户数据:

{"name": "John","sex": "Male","age": 25,"birthDate": "1990/05/01","about": "I love to go rock climbing","interests": ["sports","music"]
}

2.1、Index 索引

Elasticsearch 数据管理的顶层单位就叫做 Index(索引),相当于关系型数据库里的database的概念。另外,每个Index的名字必须是小写。一个索引是一个文档的集合(等同于solr中的集合)。每个索引有唯一的名字,通过这个名字来操作它。一个集群中可以有任意多个索引。

Elasticsearch的索引原理是通过倒排索引来实现的。

2.2、type 类型

这里指的是文档的类型,而不是字段的类型。type类似于MySQL数据库中 表 的概念。而ES中没有表的概念,这是ES和数据库的一个区别。在6.0版本之前,ES中有Type的概念,但是后来官方说这是一个设计上的失误。所以这个 type 从 7.x 开始就被移除了!系统默认使用_doc(现在8.x 版本就也不再支持修改这个类型了), 因为这个设计会降低 Lucene 压缩数据的能力,导致数据稀疏。

我们都知道elasticsearch是基于Lucene开发的搜索引擎,而ES中不同type下名称相同的filed最终在Lucene中的处理方式是一样的。举个例子,两个不同type下的两个user_name,在ES同一个索引下其实被认为是同一个filed,你必须在两个不同的type中定义相同的filed映射。否则,不同type中的相同字段名称就会在处理中出现冲突的情况,导致Lucene处理效率下降。从本质上来看,这个 Type是对索引进行逻辑分区,使用文档类型_type 和文档_id 组成_uid ,形成文档的唯一ID,对索引进行细分。而在 Lucene 中,我们这个字段域在索引中是唯一的,所以原本的字段也会被细分,导致字段域增多的同时,数据的密度也就降低了,压缩效率也就降低了,导致ES查询效率的降低。

在 5.X 版本中,一个 index 下可以创建多个 type;

在 6.X 版本中,一个 index 下只能存在一个 type(即:"_type" : "doc");

在 7.X 版本中,直接去除了 type 的概念,就是说 index 不再会有 type。

8.0开始,将移除接受类型的API

ES 的Type 被废弃后,库表合一,Index 既可以被认为对应 MySQL 的 Database,也可以认为对应 table。

也可以这样理解:

  • ES 实例:对应 MySQL 实例中的一个 Database。
  • Index 对应 MySQL 中的 Table 。
  • Document 对应 MySQL 中表的记录。

2.3、Document 文档

文档在ES中相当于传统数据库中的行的概念,即每一行的数据,ES中的数据都以JSON的形式来表示,在MySQL中插入一行数据和ES中插入一个JSON文档是一个意思。文档是Elasticsearch中的最小单位,每个索引都是有数量众多的文档组成的。文档由多个字段组成,每个字段的类型由mapping定义,每个字段的类型,可以是文本、数值、日期等。字段类型也可以是复杂类型,一个字段包含其他子文档或者数组,但 Elasticsearch 的文档中,相同字段必须有相同类型。下面的JSON数据表示一个包含7个字段的文档。

{"_index": "user","_type": "_doc","_id": "qbuOs4AB1VH6WaY_OsFW","_version": 1,"_score": 1,"_source": {"name": "张三","address": "广东省深圳市","remark": "他是一个程序员","age": 28,"salary": 8800,"birthDate": "1991-10-05","createTime": "2019-07-22T13:22:00.000Z"}
}

上面为 ES 一条文档数据,而一个文档不只有基础数据,它还包含了元数据(metadata)——关于文档的信息,也就是用下划线开头的字段,它是官方提供的字段:

  • _index :文档所属索引名称,即文档存储的地方。
  • _type :文档所属类型名(此处已默认为_doc)。
  • _id :文档的唯一标识。在写入的时候,可以指定该 Doc 的 ID 值,如果不指定,则系统自动生成一个唯一的 UUID 值。
  • _score :顾名思义,得分,也可称之为相关性,在查询是 ES 会 根据一些规则计算得分,并根据得分进行倒排。除此之外,ES 支持通过 Function score query 在查询时自定义 score 的计算规则。
  • _source :文档的原始 JSON 数据。

2.4、字段Field

相当于是数据表的字段,字段在ES中可以理解为JSON数据的键,是文档中的基本单位,以键值对的形式存在。在下面的JSON数据中,键都是一个字段。

{"name": "张三","address": "广东省深圳市","remark": "他是一个程序员","age": 28,"salary": 8800,"birthDate": "1991-10-05","createTime": "2019-07-22T13:22:00.000Z"
}

2.5、映射mapping

相当于数据库中的schema,用来约束字段的数据类型,每一种数据类型都有对应的使用场景。mapping 中定义了一个文档所包含的所有 field 信息,每个文档都有映射,但是在大多数使用场景中,我们并不需要显示的创建映射,因为ES中实现了动态映射。我们在索引中写入一个下面的JSON文档:

{"name":"jack","age":18,"birthDate": "1991-10-05"
}

在动态映射的作用下,name会映射成text类型,age会映射成long类型,birthDate会被映射为date类型,映射的索引信息如下。

{"mappings": {"_doc": {"properties": {"age": {"type": "long"},"birthDate": {"type": "date"},"name": {"type": "text","fields": {"keyword": {"type": "keyword","ignore_above": 256}}}}}}
}

自动判断的规则如下:

JSON Type Field Type
Boolean:true、flase boolean
Whole number:123、456、876 long
Floating point:123.43、234.534 double
String,valid date:"2022-05-15" date
String:"Hello Elasticsearch" string

常见的ELasticSearch数据类型如下:

数据类型 具体类型
字符串类型 string,text,keyword
整数类型 integer,long,short,byte
浮点类型 double,float,half_float,scaled_float
逻辑类型 boolean
日期类型 date
范围类型 range
二进制类型 binary
数组类型 array
对象类型 object
嵌套类型 nested
地理坐标类型 geo_point
地理地图 geo_shape
IP类型 ip
令牌计数类型 token_count

注意事项关于字符串类型:

string类型: 在ElasticSearch 旧版本中使用较多,从ElasticSearch 5.x开始不再支持string,由text和keyword类型替代。

  • text类型的字段不用于排序,很少用于聚合,需要分词设置text类型
  • keyword类型适用于索引结构化的字段,keyword类型的字段只能通过精确值搜索到。不需要分词设置keyword类型

补充:

对text类型的字段,会先使用分词器分词,生成倒排索引,用于之后的搜索。

对keyword类型的字段,不会分词,搜索时只能精确查找

2.6、集群Cluster

ElasticSearch 是一个分布式的搜索引擎,所以一般由多台物理机组成。而在这些机器上通过配置一个相同的cluster name,让其互相发现从而把自己组织成一个集群。

2.7、Node 节点

即一个elasticsearch 实例。节点也有自己的名称,默认在启动时会以一个随机的UUID的前七个字符作为节点的名字,你可以为其指定任意的名字。通过集群名在网络中发现同伴组成集群。一个节点也可是集群。(每个物理机器上可以有多个节点,使用不同的端口和节点名)。

node节点可以分为三类:

2.7.1、master节点

集群中的一个节点会被选为master节点,它将负责管理集群范畴的变更:处理创建,删除索引等请求,维护集群状态信息。master节点无需参与文档层面的变更和搜索,这意味着仅有一个master节点并不会因流量增长而成为瓶颈。任意一个节点都可以成为 master 节点。

2.7.2、data节点:

   持有数据和倒排索引。默认情况下,每个节点都可以通过设定配置文件elasticsearch.yml中的node.data属性为true(默认)成为数据节点。如果需要一个专门的主节点,应将其node.data属性设置为false。

2.7.3、Client节点:

如果将node.master属性和node.data属性都设置为false,那么该节点就是一个客户端节点,扮演一个负载均衡的角色,将到来的请求路由到集群中的各个节点。

2.8、Shard 分片:

为了将数据添加到 Elasticsearch,我们需要索引(index)——一个存储关联数据的地方。实际上,索引只是一个用来指向一个或多个分片(shards)的 逻辑命名空间 (logical namespace)。

当你查询的索引分布在多个分片上时,ES会把查询发送给每个相关的分片,并将结果组合在一起,而应用程序并不知道分片的存在。即:这个过程对用户来说是透明的。

        分片分为:主分片(Primary shard)和副本分片(Replica shard)

主分片Primary shard:

用于解决数据水平扩展的问题,通过主分片,可以将数据分布到集群内的所有节点之上,将一份索引数据划分为多小份的能力,允许水平分割和扩展容量。多个分片可以响应请求,提高性能和吞吐量。一个节点(Node)一般会管理多个分片。

副本分片Replica shard:

副本分片只是一个主分片的拷贝。 副本分片作为硬件故障时保护数据不丢失的冗余备份,并为搜索和返回文档等读操作提供服务。

分片的特点:

  • 一个Index数据在物理上被分布在多个主分片中,每个主分片只存放部分数据,每个主分片可以有多个副本。
  • 主分片的作用:对索引的扩容,使一个索引的容量可以突破单机的限制。
  • 副本分片是对数据的保护,每个主分片对应一个或多个副本分片,当主分片所在节点宕机时,副本分片会被提升为对应的主分片使用。
  • 一个主分片和它的副本分片,不会分配到同一个节点上。
  • 一个分片就是一个Lucene实例,并且它本身就是一个完整的搜索引擎。应用程序不会和它直接通信。
  • 当索引创建完成的时候,主分片的数量就固定了,如果要修改,需要重建索引,代价很高,但是复制分片的数量可以随时调整。

分片的设定:

对于生产环境中分片的设定,需要提前做好容量规划,主分片数是在索引创建的时候预先设定,事后无法修改。

  • 分片数设置过小

    • 导致后续无法增加节点实现水平扩展;
    • 单个分片的数据量太大,导致数据重新分配耗时。
  • 分片数设置过大,7.0开始,默认主分片设置成1,解决了over-sharding的问题
    • 影响搜索结果的相关性打分,影响统计结果的准确性
    • 单个节点上过多的分片,会导致资源浪费,同时也会影响性能

用图形表示出来可能是这样子的:

  • Index 1:蓝色部分,有3个shard,分别是P1,P2,P3,位于3个不同的Node中,这里没有Replica。
  • Index 2:绿色部分,有2个shard,分别是P1,P2,位于2个不同的Node中。并且每个shard有一个replica,分别是R1和R2。

基于系统可用性的考虑,同一个shard的primary和replica不能位于同一个Node中。这里Shard1的P1和R1分别位于Node3和Node2中,如果某一刻Node2发生宕机,服务基本不会受影响,因为还有一个P1和R2都还是可用的。因为是主备架构,当主分片发生故障时,需要切换,这时候需要选举一个副本作为新主,这里除了会耗费一点点时间外,也会有丢失数据的风险。

2.8.1、路由

Elasticsearch 如何知道一个文档应该存放到哪个分片中呢?实际上,这个过程是根据下面这个公式决定的:

shard = hash(routing) % number_of_primary_shards

routing 是一个可变值,唯一不可重复,默认是文档的 _id ,也可以设置成一个自定义的值。 routing 通过 hash 函数生成一个数字,然后这个数字再除以 number_of_primary_shards (主分片的数量)后得到余数 。这个分布在 0 到 number_of_primary_shards-1 之间的余数,就是我们所寻求的文档所在分片的位置。

这就解释了为什么我们要在创建索引的时候就确定好主分片的数量 并且永远不会改变这个数量:因为如果数量变化了,那么所有之前路由的值都会无效,文档也再也找不到了。
        所有的文档 API( get 、 index 、 delete 、 bulk 、 update 以及 mget )都接受一个叫做 routing 的路由参数 ,通过这个参数我们可以自定义文档到分片的映射。一个自定义的路由参数可以用来确保所有相关的文档(例如所有属于同一个用户的文档)都被存储到同一个分片中。

3、ElasticSearch中索引原理

我们知道ES的搜索是非常快的,并且比MySQL快很多,所以来看下两者的索引原理:

  • MySQL的索引原理:B+Tree索引
  • ElasticSearch的索引原理:倒排索引

        倒排索引:也叫反向索引,首先对文档数据按照id进行索引存储,然后对文档中的数据分词,记录对词条进行索引,并记录词条在文档中出现的位置。这样查找时只要找到了词条,就找到了对应的文档。概括来讲是先找到词条,然后看看哪些文档包含这些词条。通俗地来讲,正向索引是通过key找value,倒排索引则是通过value找key。跟MySQL中的索引回表查询有点类似。

Elasticsearch学习(一):基础概念相关推荐

  1. 漫谈深度强化学习之基础概念

    漫谈深度强化学习之基础概念 原创:  张泽旺  深度学习每日摘要  2017-02-23 当下,深度强化学习(Deep Reinforcement Learning)的应用已经铺天盖地般出现了.为什么 ...

  2. 深度学习:基础概念陈述及P-R曲线绘制案例(Python)

    文章目录 @[toc] 一.概念陈述 1.1引例 1.2机器学习与深度学习 1.3基础概念 1.4机器学习与统计学的对比 二.数据集(dataset) 2.1数据集的数学表示 2.2训练集和测试集 2 ...

  3. Elasticsearch 学习(一).基础原理

    Elasticsearch 参考: 14.Elasticsearch上篇(原理) (passjava.cn) 文章目录 Elasticsearch 一.Elasticsearch简介 1.1 什么是E ...

  4. pmp学习1——基础概念

    1.什么是项目管理 项目管理就是将知识.技能.工具与技术应用于项目活动,以满足项目要求.项目管理室通过合理运用于整合42个项目管理过程来实现的.可以根据逻辑关系,把这42个过程分为5大过程组,即: * ...

  5. Elasticsearch学习(2) 基本概念

    目录 1.Es基本定义 1.1 文档(Document) 1.2 索引(Index) 1.3 类型(Type) 1.4 映射(Mapping) 1.5 集群(Cluster) 1.6 节点(Node) ...

  6. 自动化测试学习 - 自动化测试基础概念

    概述 在开发过程中总会经历下面类似的问题: 每次在版本发布上线之前,要花费好几个小时甚至是更长时间对你的应用进行测试,这个过程非常枯燥而痛苦. 当代码的复杂度达到了一定的级别,当维护者的数量不止你一个 ...

  7. 深度学习分类基础概念对ACC、PPV、TPR、TNR

    举个例子: ACC = 10+15 +20/(10+1+2+3+14+4+5+6+20) PPV(猫) = 10/(10+1+2) [解释]这里的1和2是因为狗.猪分类错误,分到了猫 PPV(狗) = ...

  8. 【强化学习】从强化学习基础概念开始

    在开始探索强化学习的诸多算法之前,我们先来了解一下它所涉及到的具体概念.这些概念将作为基石,一直陪伴着我们的学习之旅.为了能够将这些概念熟记在心,我们这一期做成强化学习概念小卡片,一张一张给大家展示和 ...

  9. 复杂网络基础概念总结

    前言:最近刚定下的课题,现在主要学习网络基础概念的知识,凡是学习总是得做下总结笔记才能比较清楚.也分享给大家一起学习吧,如有错误可以提出私信我或者评论. 社会网络通常显示出较强的社区效应,网络中的节点 ...

  10. 15分钟掌握Elasticsearch 8大核心概念与基础用法

    Elastic已经形成了一个较为庞大的生态,这个生态的核心就是Elasticsearch.初学者的重点就是如何快速地了解并使用Elasticsearch,本文总结了Elasticsearch的8大核心 ...

最新文章

  1. java条码大小_java – 自定义条形码输入中缺少条形码高度
  2. Activity与多个fragment的之间的相爱想杀
  3. 网络matlab程序_【Matlab】官网资源盘点
  4. 英语基础语法(八)-时态
  5. ubuntu安装python3、setuptools、ipython
  6. ionic应用程序文件保存和清除缓存
  7. 打印机提示手动进纸解决办法
  8. python 线程池的研究及实现
  9. golang orm对比
  10. overfitting怎么解决?
  11. JSzip 前端处理下载打包文件夹
  12. python汇率的转换程序_用Python制作汇率转换小程序
  13. 推荐电影电视剧下载最好去处
  14. 刷屏专用超长复制_求超长的刷屏文字
  15. HTML文本格式化标签详解
  16. echarts二次渲染时宽高为0图表不显示
  17. 25个问题让你了解谷歌钱包
  18. 大数据面试重点之hive(五)
  19. 推荐一个类似于国内知乎国外网站-Quora
  20. 云计算实验2 Spark分布式内存计算框架配置及编程案例

热门文章

  1. 完美修改证件照背景详细步骤,可以消除边界处的白边或者红边
  2. C库源码中的移位函数
  3. [摘录]第一部分 掌舵领航(2)
  4. Unirech:阿里云国际版怎么获得免费试用的机会以及注册流程
  5. 字节跳动裁员不发年终奖致员工与HR薅头发互殴?字节回应来了
  6. html 中二维数组创建,【百度】js基础任务2-二维数组,dom操作
  7. 数据分析笔记:广州市财政收入挖掘预测案例
  8. Data-driven methods for solving algebra word problems论文阅读
  9. iPad 如何使用妙控键盘
  10. 总结图扑软件可实现的可视化效果案例分享