ES 原理和使用场景

news2024/11/20 0:34:21

为什么不能使用数据库做搜索?

  • 1、比方说,每条记录的指定字段的文本,可能会很长,比如说“商品描述”字段的长度,有长达数千个,甚至数万个字符,这个时候,每次都要对每条记录的所有文本进行扫描。
    你包不包含我指定的这个关键词(比如说“牙膏”)
  • 2、还不能将搜索词拆分开来,尽可能去搜索更多的符合你的期望的结果,比如输入“生化机”,就搜索不出来“生化危机”
    总的来说就是数据库来实现搜索,是不太靠谱的。通常来说,性能会很差的。

NoSQL 优点
(1)数据量较大,es的分布式本质,可以帮助你快速进行扩容,承载大量数据
(2)数据结构灵活多变,随时可能会变化,而且数据结构之间的关系,非常复杂,如果我们用传统数据库,那是不是很坑,因为要面临大量的表
(3)对数据的相关操作,较为简单,比如就是一些简单的增删改查,用我们之前讲解的那些document操作就可以搞定
(4)NoSQL数据库,适用的也是类似于上面的这种场景

Lucene

lucene,就是一个jar包,里面包含了封装好的各种建立倒排索引,以及进行搜索的代码,包括各种算法。我们就用java开发的时候,引入lucene jar,然后基于lucene的api进行去进行开发就可以了。
用lucene,我们就可以去将已有的数据建立索引,lucene会在本地磁盘上面,给我们组织索引的数据结构。另外的话,我们也可以用lucene提供的一些功能和api来针对磁盘上进行操作和查询。
在这里插入图片描述

Elasticsearch

Elasticsearch的功能,应用场景

在这里插入图片描述

1. 分布式的搜索引擎和数据分析引擎

搜索:百度,网站的站内搜索,IT系统的检索
数据分析:电商网站,最近7天牙膏这种商品销量排名前10的商家有哪些;新闻网站,最近1个月访问量排名前3的新闻版块是哪些
分布式,搜索,数据分析

2. 全文检索,结构化检索,数据分析

全文检索:我想搜索商品名称包含牙膏的商品,select * from products where product_name like “%牙膏%”
结构化检索:我想搜索商品分类为日化用品的商品都有哪些,select * from products where category_id=‘日化用品’
部分匹配、自动完成、搜索纠错、搜索推荐
数据分析:我们分析每一个商品分类下有多少个商品,select category_id,count(*) from products group by category_id

3. 对海量数据进行近实时的处理

分布式:ES自动可以将海量数据分散到多台服务器上去存储和检索
海联数据的处理:分布式以后,就可以采用大量的服务器去存储和检索数据,自然而然就可以实现海量数据的处理了
近实时:检索个数据要花费1小时(这就不要近实时,离线批处理,batch-processing);在秒级别对数据进行搜索和分析

跟分布式/海量数据相反的:lucene,单机应用,只能在单台服务器上使用,最多只能处理单台服务器可以处理的数据量

elasticsearch的核心概念

  1. Near Realtime(RT):近实时,数据被写入到es 到可以被搜索到这个时间 在一秒内可以完成。

  2. Cluster:集群,包含多个节点,每个节点属于哪个集群是通过一个配置(集群名称,默认是elasticsearch)来决定的,对于中小型应用来说,刚开始一个集群就一个节点很正常

  3. Node:节点,集群中的一个节点,节点也有一个名称(默认是随机分配的),节点名称很重要(在执行运维管理操作的时候),默认节点会去加入一个名称为“elasticsearch”的集群,如果直接启动一堆节点,那么它们会自动组成一个elasticsearch集群,当然一个节点也可以组成一个elasticsearch集群

  4. Document&field:文档,es中的最小数据单元,一个document可以是一条客户数据,一条商品分类数据,一条订单数据,通常用JSON数据结构表示,
    每个index下的type中,都可以去存储多个document。一个document里面有多个field,每个field就是一个数据字段。

{
  "product_id": "1",
  "product_name": "高露洁牙膏",
  "product_desc": "高效美白",
  "category_id": "2",
  "category_name": "日化用品"
}
  1. Index:索引,包含一堆有相似结构的文档数据,比如可以有一个客户索引,商品分类索引,订单索引,索引有一个名称。一个index包含很多document,一个index就代表了一类类似的或者相同的document。比如说建立一个product index,商品索引,里面可能就存放了所有的商品数据,所有的商品document。
  2. Type:类型,每个索引里都可以有一个或多个type,type是index中的一个逻辑数据分类,一个type下的document,都有相同的field,比如博客系统,有一个索引,可以定义用户数据type,博客数据type,评论数据type。
    type,日化商品type,电器商品type,生鲜商品type

日化商品type:product_id,product_name,product_desc,category_id,category_name
电器商品type:product_id,product_name,product_desc,category_id,category_name,service_period
生鲜商品type:product_id,product_name,product_desc,category_id,category_name,eat_period

每一个type里面,都会包含一堆document,类型于数据库中,这里的每一行数据就是一个document,

{
  "product_id": "2",
  "product_name": "长虹电视机",
  "product_desc": "4k高清",
  "category_id": "3",
  "category_name": "电器",
  "service_period": "1年"
}
{
  "product_id": "3",
  "product_name": "基围虾",
  "product_desc": "纯天然,冰岛产",
  "category_id": "4",
  "category_name": "生鲜",
  "eat_period": "7天"
}
  1. shard:单台机器无法存储大量数据,es可以将一个索引中的数据切分为多个shard,分布在多台服务器上存储。有了shard就可以横向扩展,存储更多数据,让搜索和分析等操作分布到多台服务器上去执行,提升吞吐量和性能。每个shard都是一个lucene index因为ES是分布式架构,类似于HDFS的存储方式,所以数据被打散存储在集群的多个节点上,一个分片实际上就是底层Lucene的一个索引,这里说的分片指的是ES中的主分片(因为还有副本分片一说),分片的方式是ES自动完成,用户可以指定分片的数量,主分片一旦指定就不能修改,因为ES打散数据的方式是和索引创建时指定的主分片数量有关(路由算法公式:shard=hash(routing)%number_of_primary_shards,进行文档分配),后期改变会导致分片中的数据不可搜索。

  2. replica:任何一个服务器随时可能故障或宕机,此时shard可能就会丢失,因此可以为每个shard创建多个replica副本。replica可以在shard故障时提供备用服务,保证数据不丢失,多个replica还可以提升搜索操作的吞吐量和性能。**primary shard(建立索引时一次设置,不能修改,默认5个),replica shard(随时修改数量,默认1个),默认每个索引10个shard,5个primary shard,5个replica shard,最小的高可用配置,是2台服务器。 副本就是分片的一个拷贝,不仅能提高自身容灾,另外,请求量很大的情况下,副本可以分担主Shard压力,承担查询功能。副本个数还以在创建完索引后灵活调整

在这里插入图片描述

ES实现写入和读取的原理

在这里插入图片描述

(1)ES写数据过程

  1. 客户端随机选择一个node发送请求过去,这个node就是coordinating node(协调节点)
  2. coordinating node,对document进行路由,将请求转发给对应的node(有primary shard)
  3. 实际的node上的primary shard处理请求,然后将数据同步到replica node
  4. coordinating node,如果发现primary node和所有replica node都搞定之后,就返回响应结果给客户端
  5. 在写primary shard的过程中同时还要持久到本地 :

1)先写入buffer,在buffer里的时候数据是搜索不到的;同时将数据写入translog日志文件
2)如果buffer快满了,或者到一定时间,就会将buffer数据refresh到一个新的segment file中,但是此时数据不是直接进入segment file的磁盘文件的,而是先进入os cache的。这个过程就是refresh

每隔1秒钟,es将buffer中的数据写入一个新的segment file,每秒钟会产生一个新的磁盘文件,segment file,这个segment file中就存储最近1秒内buffer中写入的数据

但是如果buffer里面此时没有数据,那当然不会执行refresh操作咯,每秒创建换一个空的segment file,如果buffer里面有数据,默认1秒钟执行一次refresh操作,刷入一个新的segment file中

操作系统里面,磁盘文件其实都有一个东西,叫做os cache,操作系统缓存,就是说数据写入磁盘文件之前,会先进入os cache,先进入操作系统级别的一个内存缓存中去

只要buffer中的数据被refresh操作,刷入os cache中,就代表这个数据就可以被搜索到了

为什么叫es是准实时的?NRT,near real-time,准实时。默认是每隔1秒refresh一次的,所以es是准实时的,因为写入的数据1秒之后才能被看到。

可以通过es的restful api或者java api,手动执行一次refresh操作,就是手动将buffer中的数据刷入os cache中,让数据立马就可以被搜索到。

只要数据被输入os cache中,buffer就会被清空了,因为不需要保留buffer了,数据在translog里面已经持久化到磁盘去一份了

3)只要数据进入os cache,此时就可以让这个segment file的数据对外提供搜索了

4)重复1~3步骤,新的数据不断进入buffer和translog,不断将buffer数据写入一个又一个新的segment file中去,每次refresh完buffer清空,translog保留。随着这个过程推进,translog会变得越来越大。当translog达到一定长度的时候,就会触发commit操作。

buffer中的数据,倒是好,每隔1秒就被刷到os cache中去,然后这个buffer就被清空了。所以说这个buffer的数据始终是可以保持住不会填满es进程的内存的。

每次一条数据写入buffer,同时会写入一条日志到translog日志文件中去,所以这个translog日志文件是不断变大的,当translog日志文件大到一定程度的时候,就会执行commit操作。

5)commit操作发生第一步,就是将buffer中现有数据refresh到os cache中去,清空buffer

6)将一个commit point写入磁盘文件,里面标识着这个commit point对应的所有segment file

7)强行将os cache中目前所有的数据都fsync到磁盘文件中去

translog日志文件的作用是什么?就是在你执行commit操作之前,数据要么是停留在buffer中,要么是停留在os cache中,无论是buffer还是os cache都是内存,一旦这台机器死了,内存中的数据就全丢了。

所以需要将数据对应的操作写入一个专门的日志文件,translog日志文件中,一旦此时机器宕机,再次重启的时候,es会自动读取translog日志文件中的数据,恢复到内存buffer和os cache中去。

commit操作

  • 1、写commit point;
  • 2、将os cache数据fsync强刷到磁盘上去;
  • 3、清空translog日志文件

8)将现有的translog清空,然后再次重启启用一个translog,此时commit操作完成。默认每隔30分钟会自动执行一次commit,但是如果translog过大,也会触发commit。整个commit的过程,叫做flush操作。我们可以手动执行flush操作,就是将所有os cache数据刷到磁盘文件中去。

不叫做commit操作,flush操作。es中的flush操作,就对应着commit的全过程。我们也可以通过es api,手动执行flush操作,手动将os cache中的数据fsync强刷到磁盘上去,记录一个commit point,清空translog日志文件。

9)translog其实也是先写入os cache的,默认每隔5秒刷一次到磁盘中去,所以默认情况下,可能有5秒的数据会仅仅停留在buffer或者translog文件的os cache中,如果此时机器挂了,会丢失5秒钟的数据。但是这样性能比较好,最多丢5秒的数据。也可以将translog设置成每次写操作必须是直接fsync到磁盘,但是性能会差很多。

其实es第一是准实时的,数据写入1秒后可以搜索到;可能会丢失数据的,你的数据有5秒的数据,停留在buffer、translog os cache、segment file os cache中,有5秒的数据不在磁盘上,此时如果宕机,会导致5秒的数据丢失。

如果你希望一定不能丢失数据的话,你可以设置个参数,官方文档,百度一下。每次写入一条数据,都是写入buffer,同时写入磁盘上的translog,但是这会导致写性能、写入吞吐量会下降一个数量级。本来一秒钟可以写2000条,现在你一秒钟只能写200条,都有可能。

10)如果是删除操作,commit的时候会生成一个.del文件,里面将某个doc标识为deleted状态,那么搜索的时候根据.del文件就知道这个doc被删除了

11)如果是更新操作,就是将原来的doc标识为deleted状态,然后新写入一条数据

12)buffer每次refresh一次,就会产生一个segment file,所以默认情况下是1秒钟一个segment file,segment file会越来越多,此时会定期执行merge

13)每次merge的时候,会将多个segment file合并成一个,同时这里会将标识为deleted的doc给物理删除掉,然后将新的segment file写入磁盘,这里会写一个commit point,标识所有新的segment file,然后打开segment file供搜索使用,同时删除旧的segment file。

es里的写流程,有4个底层的核心概念,refresh、flush、translog、merge

当segment file多到一定程度的时候,es就会自动触发merge操作,将多个segment file给merge成一个segment file

(2)ES读数据过程

查询,GET某一条数据,写入了某个document,这个document会自动给你分配一个全局唯一的id,即doc id,同时也是根据doc id进行hash路由到对应的primary shard上面去。也可以手动指定doc id,比如用订单id,用户id。

你可以通过doc id来查询,会根据doc id进行hash,判断出来当时把doc id分配到了哪个shard上面去,从那个shard去查询

1)客户端发送请求到任意一个node,成为coordinate node
2)coordinate node对document进行路由,将请求转发到对应的node,此时会使用round-robin随机轮询算法,在primary shard以及其所有replica shard中随机选择一个,让读请求负载均衡
3)接收请求的node返回document给coordinate node
4)coordinate node返回document给客户端

(3)ES搜索数据过程

1)客户端发送请求到一个coordinate node
2)协调节点将搜索请求转发到所有的shard对应的primary shard或replica shard也可以
3)query phase:每个shard将自己的搜索结果(其实就是一些doc id),返回给协调节点,由协调节点进行数据的合并、排序、分页等操作,产出最终结果
4)fetch phase:接着由协调节点,根据doc id去各个节点上拉取实际的document数据,最终返回给客户端
(4)搜索的底层原理,倒排索引,用表格说明传统数据库和倒排索引的区别(自上而下)

关系型数据库(比如Mysql)非关系型数据库(Elasticsearch)
数据库 DB索引 Index
表 Table类型 Type
数据行 Row文档 Document
数据列 Column字段 Field
约束 Schema映射 Mapping

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1384395.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

第二百六十六回

文章目录 1. 概念介绍2. 分析与解决2.1 分析问题2.2 解决方案 3. 示例代码4. 内容总结 我们在上一章回中介绍了"如何修改CircleAvatar的大小"相关的内容,本章回中将介绍如何修改StatusBar中文字的颜色.闲话休提,让我们一起Talk Flutter吧。 1.…

三、ngxin虚拟主机

目录 什么是nginx虚拟主机修改端口 访问页面1、配置nginx.config 文件2、 添加配置给目录中写入内容检测nginx 是否有语法错误(nginx -t)重启 nginx查看配置结果 不同主机网卡 查看到不同的页面先添加一个临时ip修改ngixn配置文件创建目录文件检测nginx …

案例121:基于微信小程序的作品集展示系统设计与实现

文末获取源码 开发语言:Java 框架:SSM JDK版本:JDK1.8 数据库:mysql 5.7 开发软件:eclipse/myeclipse/idea Maven包:Maven3.5.4 小程序框架:uniapp 小程序开发软件:HBuilder X 小程序…

MySQL进阶篇(五) 锁

一、概述 锁是计算机协调多个进程或线程并发访问某一资源的机制。在数据库中,除传统的计算资源(CPU、RAM、I/O)的争用以外,数据也是一种供许多用户共享的资源。如何保证数据并发访问的一致性、有效性是所有数据库必须解决的一个问…

C#灵活的任务调度组件FluentScheduler

FluentScheduler是一个C#的灵活的任务调度组件,支持各类任务调度。网上有很多演示代码,此处记录下来,方便自己查找。 // See https://aka.ms/new-console-template for more information //Console.WriteLine("Hello, World!");us…

IP-Adapter:用于文本到图像扩散模型的文本兼容图像提示适配器

文章目录 一、IP-Adapter简介二、IP-Adapter与img2img的区分(一)结构上的区别(二)流程上的区别(三)输出上的区别(四)原理上的区别 三、IP-Adapter的网络架构(一&#xff…

Python教程16:使用海龟画图turtle画会动的时钟

---------------turtle源码集合--------------- Python教程36:海龟画图turtle写春联 Python源码35:海龟画图turtle画中国结 Python源码31:海龟画图turtle画七道彩虹 Python源码30:海龟画图turtle画紫色的小熊 Python源码29&a…

单例模式---JAVA

目录 “饿汉”模式 完整代码 “懒汉”模式 完整代码 单例模式:保证某个类在程序中只存在唯一一份实例, 而不会创建出多个实例。 单例模式可以通过实例创建的时间来分为两种:“饿汉”和“懒汉”模式。 “饿汉”模式 所谓的“饿汉”模式实则就是在类…

异常处理注解 @ExceptionHandler

今天记录下 SpringBoot 中 ExceptionHandler 的使用。 场景 有一个员工表(employee),且给表中的 username 属性设置了唯一性。 -- auto-generated definition create table employee (id bigint auto_increment comment 主键primary key,name va…

STM32F103_ESP8266基于RTOS移植MQTT

STM32F103_ESP8266基于RTOS移植MQTT 目录 STM32F103_ESP8266基于RTOS移植MQTT一、准备工作二、移植mqttclient代码三、编译包含mqttclient的工程四、编写ESP8266驱动程序1、ESP8266 AT命令代码框架2、UART硬件和抽象层相关代码3、AT命令发送和解析代码4、plat_sock网络层相关代…

【redis基础1】基础数据类型详解和应用案例

博客计划 ,我们从redis开始,主要是因为这一块内容的重要性不亚于数据库,但是很多人往往对redis的问题感到陌生,所以我们先来研究一下。 本篇,我们先看一下redis的基础数据类型详解和应用案例。 1.redis概述 以mysql为…

软件测试|Python requests库的安装和使用指南

简介 requests库是Python中一款流行的HTTP请求库,用于简化HTTP请求的发送和处理,也是我们在使用Python做接口自动化测试时,最常用的第三方库。本文将介绍如何安装和使用requests库,以及一些常见的用例示例。 安装requests库 首…

认知觉醒(九)

认知觉醒(九) 专注力——情绪和智慧的交叉地带 第一节 情绪专注:一招提振你的注意力 用元认知来观察自己的注意力是一件很有意思的事情,相信你可以轻易观察到这种现象:身体做着A,脑子却想着B。 跑步的时候,手脚在…

AI与编程学习

在C语言中,指针通常与字符数组或字符串打交道时会涉及到ASCII码的转换,而不是用于表现多位数的第一位。48这个值对应的是ASCII码表中数字字符0的编码。 如果你有一个表示多位数的字符数组,例如: c char number[] "1234&qu…

ssm基于web办事大厅政务预约系统+vue论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储,归纳,集中处理数据信息的管理方式。本办事大厅政务预约系统就是在这样的大环境下诞生,其可以帮助管理者在短时间内处理完毕庞大的数据…

代码随想录day30 回溯算法最终章

51. N皇后 题目 n 皇后问题 研究的是如何将 n 个皇后放置在 nn 的棋盘上,并且使皇后彼此之间不能相互攻击。 给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。 每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 Q 和…

xtu oj 1340 wave

题目描述 一个n列的网格,从(0,0)网格点出发,波形存在平波(从(x,y)到(x1,y)),上升波(从(x,y)到(x1,y1)),下降波(从(x,y)到(x1,y−1))三种波形,请问从(0,0)出发,最终到达(n,0)的不同波形有多少种&#xff1f…

第 13 章图

文章目录 13.1 图基本介绍13.1.1 为什么要有图13.1.2 图的举例说明 13.2 图的表示方式13.2.1 邻接矩阵13.2.2 邻接表 13.3 图的快速入门案例13.4 图的深度优先遍历介绍13.4.1 图遍历介绍13.4.2 深度优先遍历基本思想13.4.3 深度优先遍历算法步骤13.4.4 深度优先算法的代码实现 …

TikTok系列算法定位还原x-ss-stub

TikTok的x系列的算法比较有名,很多粉丝也问过,之前没有深入研究,本人工作量也比较大。 我们上次说到TikTok的x-ss-stub的算法就是ccmd5标准库算的,今天要讲细致点,表面这个结论本不是直接将数据md5那么来的,是经过一系列分析来的 上图是上次截图的,这次我们分析整个定位…

【算法】七夕祭

题目 七夕节因牛郎织女的传说而被扣上了「情人节」的帽子。 于是 TYVJ 今年举办了一次线下七夕祭。 Vani 同学今年成功邀请到了 cl 同学陪他来共度七夕,于是他们决定去 TYVJ 七夕祭游玩。 TYVJ 七夕祭和 11 区的夏祭的形式很像。 矩形的祭典会场由 N 排 M 列共…