ELK基础

ELK基础

ELK是用于**数据抽取(Logstash)、搜索分析(Elasticsearch)、数据展现(Kibana)**的一整套解决方案,所以也称作ELK stack。

Elastic Stack简介

包含三大基础组件,分别是Elasticsearch、Logstash、Kibana。但实际上ELK不仅仅适用于日志分析,它还可以支持其它任何数据搜索、分析和收集的场景,日志分析和收集只是更具有代表性

组件介绍

Elasticsearch

Elasticsearch 是使用java开发,基于Lucene、分布式、通过Restful方式进行交互的近实时搜索平台框架。它的特点有:分布式,零配置,自动发现,索引自动分片,索引副本机制,restful风格接口,多数据源,自动搜索负载等。

Logstash

Logstash 基于java开发,是一个数据抽取转化工具。一般工作方式为c/s架构,client端安装在需要收集信息的主机上,server端负责将收到的各节点日志进行过滤、修改等操作在一并发往elasticsearch或其他组件上去。

Kibana

Kibana 基于nodejs,也是一个开源和免费的可视化工具。Kibana可以为 Logstash 和 ElasticSearch 提供的日志分析友好的 Web 界面,可以汇总、分析和搜索重要数据日志。

Beats

Beats 平台集合了多种单一用途数据采集器。它们从成百上千或成千上万台机器和系统向 Logstash 或 Elasticsearch 发送数据。

Beats由如下组成:

Packetbeat:轻量型网络数据采集器,用于深挖网线上传输的数据,了解应用程序动态。Packetbeat 是一款轻量型网络数据包分析器,能够将数据发送至 Logstash 或 Elasticsearch。其支 持ICMP (v4 and v6)、DNS、HTTP、Mysql、PostgreSQL、Redis、MongoDB、Memcache等协议。

Filebeat:轻量型日志采集器。当您要面对成百上千、甚至成千上万的服务器、虚拟机和容器生成的日志时,请告别 SSH 吧。Filebeat 将为您提供一种轻量型方法,用于转发和汇总日志与文件,让简单的事情不再繁杂。

Metricbeat :轻量型指标采集器。Metricbeat 能够以一种轻量型的方式,输送各种系统和服务统计数据,从 CPU 到内存,从 Redis 到 Nginx,不一而足。可定期获取外部系统的监控指标信息,其可以监控、收集 Apache http、HAProxy、MongoDB、MySQL、Nginx、PostgreSQL、Redis、System、Zookeeper等服务。

Winlogbeat:轻量型 Windows 事件日志采集器。用于密切监控基于 Windows 的基础设施上发生的事件。Winlogbeat 能够以一种轻量型的方式,将 Windows 事件日志实时地流式传输至 Elasticsearch 和 Logstash。

Auditbeat:轻量型审计日志采集器。收集您 Linux 审计框架的数据,监控文件完整性。Auditbeat 实时采集这些事件,然后发送到 Elastic Stack 其他部分做进一步分析。

Heartbeat:面向运行状态监测的轻量型采集器。通过主动探测来监测服务的可用性。通过给定 URL 列表,Heartbeat 仅仅询问:网站运行正常吗?Heartbeat 会将此信息和响应时间发送至 Elastic 的其他部分,以进行进一步分析。

Functionbeat:面向云端数据的无服务器采集器。在作为一项功能部署在云服务提供商的功能即服务 (FaaS) 平台上后,Functionbeat 即能收集、传送并监测来自您的云服务的相关数据。

Elastic cloud

基于 Elasticsearch 的软件即服务(SaaS)解决方案。通过 Elastic 的官方合作伙伴使用托管的 Elasticsearch 服务。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PfwsB98P-1681790775731)(null)]****

#一、搜索是什么

概念:用户输入想要的关键词,返回含有该关键词的所有信息。

场景:

1互联网搜索:谷歌、百度、各种新闻首页

2 站内搜索(垂直搜索):企业OA查询订单、人员、部门,电商网站内部搜索商品(淘宝、京东)场景。

#二、数据库做搜索弊端

#1、站内搜索(垂直搜索):数据量小,简单搜索,可以使用数据库。

问题出现:

l 存储问题。电商网站商品上亿条时,涉及到单表数据过大必须拆分表,数据库磁盘占用过大必须分库(mycat)。

l 性能问题:解决上面问题后,查询“笔记本电脑”等关键词时,上亿条数据的商品名字段逐行扫描,性能跟不上。

l 不能分词。如搜索“笔记本电脑”,只能搜索完全和关键词一样的数据,那么数据量小时,搜索“笔记电脑”,“电脑”数据要不要给用户。

#2、互联网搜索,肯定不会使用数据库搜索。数据量太大。PB级。

三、全文检索、倒排索引和Lucene

#1、全文检索
倒排索引表:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UoQftQSp-1681790773230)(C:\Users\陈刚\AppData\Roaming\Typora\typora-user-images\image-20221223210601630.png)]

如上:select * from product_term like ‘’%哪吒%‘’:

查含有哪吒的字的数据时会产生下面一个分词表(倒排索引表):

查哪吒会将有哪吒字段记入表中的分词term,含有哪吒的对应数据的id计入表中的id。如上上面四个都有,那么九江他们的content,id计入分词表对应的term和id:

分词term:哪吒,ids:1

此时查到还有其他的数据也拥有哪吒字段:哪吒海报,哪吒公仔,哪吒玩偶,对应的id2,3,4,全部计入分词表中:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yMxRiBXs-1681790773231)(C:\Users\陈刚\AppData\Roaming\Typora\typora-user-images\image-20221223212213100.png)]

记入的id1,2,3,4对应的除了哪吒外,还有电影,海报,公仔,玩偶,于是将它们记入term:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bd5ngMJt-1681790773231)(C:\Users\陈刚\AppData\Roaming\Typora\typora-user-images\image-20221223210656825.png)]

最后形成的表为倒排索引表,里面的term,id是倒排索引,进行全文检索:

select * from product_term where term = ‘哪吒’

查询等于哪吒的数据时,从分词表中知道对应的id1,2,3,4都符合,查出来返回给母表。母表根据id拿到所有与哪吒相关的数据。

这样解决了数据磁盘占用过大(将一个数据特别大的表,通过倒排索引拆分成一个精简的表,通过匹配度高的词进行全文检索),性能损耗过大,效率低的问题以及不能分词:用户搜索如搜索“笔记电脑”,“电脑”的数据也会给用户。

2 . Lucene:

就是一个jar包,里面封装了全文检索的引擎、搜索的算法代码。开发时,引入lucene的jar包,通过api开发搜索相关业务。底层会在磁盘建立索引库。

第一章 Elasticsearch(Es)是什么

简介

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pG7rB9WO-1681790776508)(null)]

官网:https://www.elastic.co/cn/products/elasticsearch

1 . 为什么使用Es?没有Es存在的问题:

数据如何分布?

已知我们单个服务器(lucene实列)只能存1t数据,java客户端连接后拿到服务器lucene的jar包后执行相关业务。如果我们此时有2t数据,那么就需要两台服务器来存储,那么数据如何分布到两台服务器呢?平分取模?可如果后续一直增加数据,那么还是这么操作吗?况且lucene也不支持这种操作,这种操作只能让java客户端来操作。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-o21X9QP4-1681790773231)(C:\Users\陈刚\AppData\Roaming\Typora\typora-user-images\image-20221223213751440.png)]

数据如何交互?

就算成功平分数据,那么用户搜索数据在第一个服务器没找到,那么去第二个服务器找到数据了,怎么反馈呢?

数据如何备份?

数据量大时,数据如何备份?再起一个服务器(lucene实列)来进行数据保存,怎么进行数据的实时保存?

上述的三种问题,Es都可解决:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oTGq3TbT-1681790773232)(C:\Users\陈刚\AppData\Roaming\Typora\typora-user-images\image-20221223215249599.png)]

Es数据分布进行分片机制来解决。将所有的数据进行分片到很多个实列(shard)当中。

Es使用平行节点解决数据交互问题:客户端访问数据时,都可以平行交互到其他实列服务器的数据(访问一个服务器相当于同时访问了所有的服务器实列)。

Es使用副本机制来进行数据的保存,备份。

Es还拥有高级搜索功能(比如:分组,聚合)。

2 . Elasticsearch的功能

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

搜索:互联网搜索、电商网站站内搜索、OA系统查询

数据分析:电商网站查询近一周哪些品类的图书销售前十;新闻网站,最近3天阅读量最高的十个关键词,舆情分析。

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

全文检索:搜索商品名称包含java的图书select * from books where book_name like “%java%”。

结构化检索:搜索商品分类为spring的图书都有哪些,select * from books where category_id=‘spring’

数据分析:分析每一个分类下有多少种图书,select category_id,count(*) from books group by category_id

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

分布式:ES自动可以将海量数据分散到多台服务器上去存储和检索,经行并行查询,提高搜索效率。相对的,Lucene是单机应用。

近实时:数据库上亿条数据查询,搜索一次耗时几个小时,是批处理(batch-processing)。而es只需秒级即可查询海量数据,所以叫近实时。秒级

3 . Es核心概念:

(1)NRT(Near Realtime):近实时

两方面:

  • 写入数据时,过1秒才会被搜索到,因为内部在分词、录入索引。
  • es搜索时:搜索和分析数据需要秒级出结果。
#(2)Cluster:集群

包含一个或多个启动着es实例的机器群。通常一台机器起一个es实例。同一网络下,集群名一样的多个es实例自动组成集群,自动均衡分片等行为。默认集群名为“elasticsearch”。

#(3)Node:节点

每个es实例称为一个节点。节点名自动分配,也可以手动配置。一个节点有多个主分片和副本

#(4)Index:索引

包含一堆有相似结构的文档数据。

索引创建规则:

  • 仅限小写字母
  • 不能包含\、/、 *、?、"、<、>、|、#以及空格符等特殊符号
  • 从7.0版本开始不再包含冒号
  • 不能以-、_或+开头
  • 不能超过255个字节(注意它是字节,因此多字节字符将计入255个限制)
#(5)Document:文档

es中的最小数据单元。一个document就像数据库中的一条记录。通常以json格式显示。多个document存储于一个索引(Index)中。

book document

{
   
  "book_id": "1",
  "book_name": "java编程思想",
  "book_desc": "从Java的基础语法到最高级特性(深入的[面向对象](https://baike.baidu.com/item/面向对象)概念、多线程、自动项目构建、单元测试和调试等),本书都能逐步指导你轻松掌握。",
  "category_id": "2",
  "category_name": "java"
}
#(6)Field:字段

就像数据库中的列(Columns),定义每个document应该有的字段。

#(7)Type:类型

每个索引里都可以有一个或多个type,type是index中的一个逻辑数据分类,一个type下的document,都有相同的field。

注意:6.0之前的版本有type(类型)概念,type相当于关系数据库的表,ES官方将在ES9.0版本中彻底删除type。本教程typy都为_doc。

#(8)shard:分片

index数据过大时,将index里面的数据,分为多个shard,分布式的存储在各个服务器上面。可以支持海量数据和高并发,提升性能和吞吐量,充分利用多台机器的cpu。

#(9)replica:副本

在分布式环境下,任何一台机器都会随时宕机,如果宕机,index的一个分片没有,导致此index不能搜索。所以,为了保证数据的安全,我们会将每个index的分片经行备份,存储在另外的机器上。保证少数机器宕机es集群仍可以搜索。

能正常提供查询和插入的分片我们叫做主分片(primary shard),其余的我们就管他们叫做备份的分片(replica shard)。

es6默认新建索引时,5分片,2副本,也就是一主一备,共10个分片。所以,es集群最小规模为两台

4 .Es的优点:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OGnBxiVy-1681790773232)(C:\Users\陈刚\AppData\Roaming\Typora\typora-user-images\image-20221223224309040.png)]

假设我们有个叫book的索引,该索引有3t的数据量。每个主分片对应有一个副本R0,1,2。

(1)我们的es集群每个实列服务器只能存1t数据。所有会分片成p0,p1,p2三个shard来存储数据。这样减轻了单个node(节点:es实列)的压力.

(2)因为每个机器的的吞吐量为1000/s,那么有三个机器,当有客户端要往里面存数据时,同时往3个里存,那么总速度就达到了3000/s,充分利用机器的性能。

(3)当数据量越来越大,那么其中的索引就会越来越多,就会分片更多的服务器实列分担压力。新增的分片会将得到其他的机器存的数据和索引信息。这样分担存储数据减轻压力,而分担索引信息更是提高了集群扩展。

(4)大数据高并发的情况下,提供副本机制提供容错(副本和主分片的数据是完全一致的)。

(5)高可用:当其中一个node宕机后,它的副本会立刻接替该node,并和其他的node建立新的索引联系。

(6)能正常提供查询和插入的分片我们叫做主分片(primary shard),其余的我们就管他们叫做备份的分片(副本)。只进行查询数据不进行增删改的情况下,那么也可以去副本查拿到结果,那么三台机器三个副本,也就意味着查询的效率达到6000/s,更加提高了吞吐量。

5 . elasticsearch核心概念 vs. 数据库核心概念

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

6 . es相关配置:

安装es前,安装设置jdk1.8以上版本,随后在config下的elstaticsearch.yml进行配置:(es中默认端口为9200)

node.name: node-1  
cluster.initial_master_nodes: ["node-1"]  
xpack.ml.enabled: false 
http.cors.enabled: true
http.cors.allow-origin: /.*/

在jvm.options内设置:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-q5dBpH89-1681790773232)(C:\Users\陈刚\AppData\Roaming\Typora\typora-user-images\image-20221224130627627.png)]

随后bin下双击elstaticsearch.bat运行,运行成功后,es中默认端口为9200,浏览器输入localhost:9200

http://localhost:9200/?pretty 查看状态:

显示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VbexjtAi-1681790773232)(C:\Users\陈刚\AppData\Roaming\Typora\typora-user-images\image-20221224130752327.png)]

http://localhost:9200/_cluster/health 查询集群状态:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mJazEiXu-1681790773233)(C:\Users\陈刚\AppData\Roaming\Typora\typora-user-images\image-20221224133737195.png)]

Status:集群状态。Green 所有分片可用。Yellow所有主分片可用。Red主分片不可用,集群不可用。

7 . Kibana相关配置:

在Kibana.yml配置 修改为支持中文:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VYpTn8af-1681790773233)(C:\Users\陈刚\AppData\Roaming\Typora\typora-user-images\image-20221224135356368.png)]

随后在bin下启动Kibana.bat(Kibana的默认端口为5601)

浏览器访问http://localhost:5601 进入Dev Tools界面:

5、发送get请求,查看集群状态GET _cluster/health。相当于浏览器访问。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KpLEGx7J-1681790776931)(null)]

总览

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cyrQOL2n-1681790777109)(null)]

Dev Tools界面

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PHe30wRK-1681790777203)(null)]

监控集群界面

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-c4wo3wC8-1681790777378)(null)]

集群状态(搜索速率、索引速率等

8 .Elstaticsearch-head插件安装:

安装后,在该文件目录下打开黑窗口,运行npm run start 显示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-R0xBijh4-1681790773234)(C:\Users\陈刚\AppData\Roaming\Typora\typora-user-images\image-20221224174344211.png)]

在浏览器输入请求:http://localhost:9100显示出Elstaticsearch-head插件页面:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Kk8LB1gU-1681790773234)(C:\Users\陈刚\AppData\Roaming\Typora\typora-user-images\image-20221224175100296.png)]

已知我们启动了Es,Es-head插件它自动连接到Es默认iphttp://localhost:9200,我们点击连接http://localhost:9200后显示出了Es的内容:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CaELpz5j-1681790773234)(C:\Users\陈刚\AppData\Roaming\Typora\typora-user-images\image-20221224175113861.png)]

第二章 Es 快速入门

1 . 文档的数据格式:

(1)应用系统的数据结构都是面向对象的,具有复杂的数据结构

(2)对象存储到数据库,需要将关联的复杂对象属性插到另一张表,查询时再拼接起来。

(3)es面向文档,文档中存储的数据结构,与对象一致。所以一个对象可以直接存成一个文档。

(4)es的document用json数据格式来表达。

例如我们在java中一个使用类来对一个目标封装,比如班级类对应学生,姓名,年龄等属性,es通过json字符串形式来进行存储

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qsKXTGwo-1681790773235)(C:\Users\陈刚\AppData\Roaming\Typora\typora-user-images\image-20221224180207849.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CEfBq6uV-1681790773235)(C:\Users\陈刚\AppData\Roaming\Typora\typora-user-images\image-20221224180219819.png)]

2 . 简单的集群管理:

(1)快速检查集群的健康状况

打开kibana,开发工具:查看es健康状况

输入:GET /_cat/health?v (加个?v表示把每个数据对应属于哪个表的那哪个列的信息也显示打印出来)

随后在右侧显示出对应状况的数据

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Qck8QG2W-1681790773235)(C:\Users\陈刚\AppData\Roaming\Typora\typora-user-images\image-20221224181804246.png)]

如果只是::GET /_cat/health

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UN0nxjRS-1681790773235)(C:\Users\陈刚\AppData\Roaming\Typora\typora-user-images\image-20221224182604537.png)]

如何快速了解集群的健康状况?green、yellow、red?

green:每个索引的primary shard(主分片)和replica shard(副本)都是active状态的

yellow:每个索引的primary shard(主分片)都是active状态的,但是部分replica shard(副本)不是active状态,处于不可用的状态

red:不是所有索引的primary shard都是active状态的,部分索引有数据丢失

(2)快速查看集群中的索引:

GET /_cat/indices?v

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-S0dM9BsX-1681790773235)(C:\Users\陈刚\AppData\Roaming\Typora\typora-user-images\image-20221224182530888.png)]

(3)简单的索引操作:

注意:创建索引时,不同数据放到不同索引中:

如下图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-899WJfsc-1681790773236)(C:\Users\陈刚\AppData\Roaming\Typora\typora-user-images\image-20221224194239857.png)]

如果把user和order索引都全放到下面三个分片中,把数据混杂起来,业务人员要对订单order索引进行分析,有的分片内既存有order的索引,还存有user的索引,那么势必会对搜索分析过程造成干扰。

如果在某些时候突然order数据暴增,order的读写非常繁忙,而user和order的放在一块的话,势必会影响导致user的读写操作变慢,同时user本身速度也会因为user的读写变慢。

创建索引:

PUT /demo_index?pretty (pretty表示用json格式)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vT6GqCqg-1681790773236)(C:\Users\陈刚\AppData\Roaming\Typora\typora-user-images\image-20221224182846151.png)]

acknowledged为true:表示主分片接收到了创建索引的请求

shards_acknowledged为true:表示副本接收到了创建索引的请求

最后成功创建索引,名字叫demo_index的索引

删除索引:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FzsnLBND-1681790773236)(C:\Users\陈刚\AppData\Roaming\Typora\typora-user-images\image-20221224183127020.png)]

acknowledged为true:表示主分片接收到了删除索引的请求,成功删除了叫demo_index的索引

3 . 商品的CRUD操作

先创建一个图书的索引:

PUT /book

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FJ57kr4W-1681790773236)(C:\Users\陈刚\AppData\Roaming\Typora\typora-user-images\image-20221224183534907.png)]

(1)插入数据:语法:PUT /index/type/id

往book索引里插入一条数据:该数据id为1,文本类型

PUT /book/_doc/1

PUT /book/_doc/1
{
   
"name": "Bootstrap开发",
"description": "Bootstrap是由Twitter推出的一个前台页面开发css框架,是一个非常流行的开发框架,此框架集成了多种页面效果。此开发框架包含了大量的CSS、JS程序代码,可以帮助开发者(尤其是不擅长css页面开发的程序人员)轻松的实现一个css,不受浏览器限制的精美界面css效果。",
"studymodel": "201002",
"price":38.6,
"timestamp":"2019-08-25 19:11:35",
"pic":"group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg",
"tags": [ "bootstrap", "dev"]
}

运行显示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RSYRYWAN-1681790773236)(C:\Users\陈刚\AppData\Roaming\Typora\typora-user-images\image-20221224183852906.png)]

同理插入id为2,3的图书信息:

PUT /book/_doc/2
{
   
"name": "java编程思想",
"description": "java语言是世界第一编程语言,在软件开发领域使用人数最多。",
"studymodel": "201001",
"price":68.6,
"timestamp":"2019-08-25 19:11:35",
"pic":"group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg",
"tags": [ "java", "dev"]
}
PUT /book/_doc/3
{
   
"name": "spring开发基础",
"description": "spring 在java领域非常流行,java程序员都在用。",
"studymodel": "201001",
"price":88.6,
"timestamp":"2019-08-24 19:11:35",
"pic":"group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg",
"tags": [ "spring", "java"]
}
(2)查询数据:语法:GET /index/type/id

查询图书,检索文档:

查询book中id为1,类型为文本_doc的信息

GET /book_doc/1

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-coRqRiRH-1681790773236)(C:\Users\陈刚\AppData\Roaming\Typora\typora-user-images\image-20221224184245115.png)]

我们可以打开kibana的discovery,快速索引,将book输入,它就会自动检索到我们创建book索引,拿到book索引的所有数据显示出来:方便我们查看整个book的数据,如果只想查看到id,价格,书名等信息,点击左边的对应可用字段即可

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FChl1wcV-1681790773237)(C:\Users\陈刚\AppData\Roaming\Typora\typora-user-images\image-20221224184819683.png)]

如只看id和索引:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8j70pJj9-1681790773237)(C:\Users\陈刚\AppData\Roaming\Typora\typora-user-images\image-20221224185138580.png)]

(3)修改:全局替换操作
PUT /book/_doc/1
{
   
    "name": "Bootstrap开发教程1",
    "description": "Bootstrap是由Twitter推出的一个前台页面开发css框架,是一个非常流行的开发框架,此框架集成了多种页面效果。此开发框架包含了大量的CSS、JS程序代码,可以帮助开发者(尤其是不擅长css页面开发的程序人员)轻松的实现一个css,不受浏览器限制的精美界面css效果。",
    "studymodel": "201002",
    "price":38.6,
    "timestamp":"2019-08-25 19:11:35",
    "pic":"group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg",
    "tags": [ "bootstrap", "开发"]
}

可以看到,运行后对result显示了更新内容:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OF4ii6OY-1681790773237)(C:\Users\陈刚\AppData\Roaming\Typora\typora-user-images\image-20221224190612748.png)]

但是这个是全局替换,需要带上所有的信息才能替换

(4)修改:局部替换:
语法:POST /{index}/type /{id}/_update

我们要修改文档中,且只修改name这一个属性的内容:

POST /book/_doc/1/_update

因为_doc马上要被系统删除不用了,所以使用下面的格式:

POST /book/_doc/1/_update
{
   
  "doc": {
   
   "name": " Bootstrap开发教程高级666"
  }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ywGSgys4-1681790773237)(C:\Users\陈刚\AppData\Roaming\Typora\typora-user-images\image-20221224191308982.png)]

查询时发现确实修改成功:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A70a5clL-1681790773237)(C:\Users\陈刚\AppData\Roaming\Typora\typora-user-images\image-20221224191453783.png)]

(5)删除:

删除id为1的文档数据

DELETE /book/_doc/1

4 . 生成文档id:

(1)手动生成id

场景:数据从其他系统导入时,本身有唯一主键。如数据库中的图书、员工信息等。

用法:put /index/_doc/id

PUT /test_index/_doc/1
{
   
  "test_field": "test"
}
(2)自动生成id(id自动递增):

用法:POST /index/_doc

POST /test_index/_doc
{
   
  "test_field": "test1"
}

如下,es自动生成了id的串儿:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dFkULEfw-1681790773237)(C:\Users\陈刚\AppData\Roaming\Typora\typora-user-images\image-20221224194814838.png)]

5 . _source 字段:

含义:插入数据时的所有字段和值。在get获取数据时,在_source字段中原样返回。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BnEy4tRw-1681790773238)(C:\Users\陈刚\AppData\Roaming\Typora\typora-user-images\image-20221224200333053.png)]

(1)定制指定返回字段:

source_includes:表示要拿指定的字段的信息

只查看价格和名字:

GET /book/_doc/1?_source_includes=price,name

source只显示了介个和name的信息:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-h9PM8eML-1681790773238)(C:\Users\陈刚\AppData\Roaming\Typora\typora-user-images\image-20221224200805770.png)]

6 . 文档的替换和删除:

(1)全量替换:
PUT /test_index/_doc/1
{
   
  "test_field": "test"
}

执行语句新增数据后,会后一个version为1,再执行该语句,version为2,执行两次,返回结果中版本号(_version)在不断上升。此过程为全量替换。先前的数据为一个待删除的数据,实质:旧文档的内容不会立即删除,只是标记为deleted。适当的时机,集群会将这些文档删除。

(2)强制创建:

为防止覆盖原有数据,我们在新增时,设置为强制创建,不会覆盖原有文档。

语法:PUT /index/ _doc/id/__create

新增id为4的数据:

PUT /book/_doc/4/_create
{
   
    "name": "Bootstrap开发教程1",
    "description": "Bootstrap是由Twitter推出的一个前台页面开发css框架,是一个非常流行的开发框架,此框架集成了多种页面效果。此开发框架包含了大量的CSS、JS程序代码,可以帮助开发者(尤其是不擅长css页面开发的程序人员)轻松的实现一个css,不受浏览器限制的精美界面css效果。",
    "studymodel": "201002",
    "price":38.6,
    "timestamp":"2019-08-25 19:11:35",
    "pic":"group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg",
    "tags": [ "bootstrap", "开发"]
}

执行后,我们再执行该语句报错说该数据已经存在,不能覆盖,不能重复。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GpsPhZJj-1681790773238)(C:\Users\陈刚\AppData\Roaming\Typora\typora-user-images\image-20221224203430384.png)]

(3)删除:(延迟删除)

DELETE /book/id

DELETE /book/_doc/id

DELETE  /book/_doc/1/

实质:旧文档的内容不会立即删除,只是标记为deleted。适当的时机,集群会将这些文档删除。

7 . 局部更新(局部替换):

使用 PUT /index/type/id 为文档全量替换,需要将文档所有数据提交。

partial update局部替换则只修改变动字段。

用法:

post /index/type/id/_update 
{
   
   "doc": {
   
      "field""value"
   }
}

内部与全量替换是一样的,旧文档标记为删除,新建一个文档。

优点:

  • 大大减少网络传输次数和流量,提升性能
  • 减少并发冲突发生的概率。

7 . 批量增删改:

批量增语法:POST /_bulk

其他的以此类推。

POST /_bulk
{"action": {"metadata"}}
{"data"}

8 . 使用脚本更新:

es可以内置脚本执行复杂操作

(1)内置脚本:

修改文档6的num字段,+1。

插入数据

PUT /test_index/_doc/6
{
   
  "num": 0,
}

执行脚本操作(ctx:上下文,_source:文档6的source中的内容num+1)

POST /test_index/_doc/6/_update
{
   
   "script" : "ctx._source.num+=1"
}

搜索所有文档,将num字段乘以2输出

插入数据

PUT /test_index/_doc/7
{
  "num": 5
}

查询

GET /test_index/_search
{
   
  "script_fields": {
   
    "my_doubled_field": {
   
      "script": {
   
       "lang": "expression",
        "source": "doc['num'] * multiplier",
        "params": {
   
          "multiplier": 2
        }
      }
    }
  }
}

返回

{
        "_index" : "test_index",
        "_type" : "_doc",
        "_id" : "7",
        "_score" : 1.0,
        "fields" : {
          "my_doubled_field" : [
            10.0
          ]
        }
      }

9 . 图解es的并发问题

如同商品秒杀,多线程情况下,es同样会出现并发冲突问题

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i1lUNFI7-1681790773238)(C:\Users\陈刚\AppData\Roaming\Typora\typora-user-images\image-20221224213124651.png)]

10 . 图解悲观锁与乐观锁机制

解决es并发问题:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9tcyq1AC-1681790773238)(C:\Users\陈刚\AppData\Roaming\Typora\typora-user-images\image-20221224221026145.png)]

11 . java 客户端 获取es简单数据

我们启动es,kebana后

(1)高层api:

导入以来:

<dependency>
        <groupId>org.elasticsearch.client</groupId>
        <artifactId>elasticsearch-rest-high-level-client</artifactId>
        <version>7.3.0</version>
        <exclusions>
            <exclusion>
                <groupId>org.elasticsearch</groupId>
                <artifactId>elasticsearch</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.elasticsearch</groupId>
        <artifactId>elasticsearch</artifactId>
        <version>7.3.0</version>
    </dependency>

java代码:

public class TestDemo {
   
    public static void main(String[] args) throws IOException {
   
        //连接es的步骤:
        //1.获取连接的客户端
        RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost",9200,"http")));

        //2.构建请求,查询索引book的id为1的数据
        GetRequest getRequest = new GetRequest("book","1");

        //3.执行,这里请求参数使用默认
        GetResponse getResponse = client.get(getRequest, RequestOptions.DEFAULT);
        //4.拿到响应后解析,查询到数据后获取结果打印输出显示
        System.out.println(getResponse.getId());
        System.out.println(getResponse.getVersion());
        System.out.println(getResponse.getSource());
    }
}

输出显示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rlFqfFvw-1681790773238)(C:\Users\陈刚\AppData\Roaming\Typora\typora-user-images\image-20221225102214406.png)]

12 . 结合springboot获取es数据查询操作:

  • 当今趋势
  • 方便开发
  • 创建连接交由spring容器,避免每次请求的网络开销。

引入依赖:

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
            <version>2.0.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <version>2.0.6.RELEASE</version>
        </dependency>

配置springboot配置文件:

spring:
  application:
    name: service-search
heima:
  elasticsearch:
    hostlist: 127.0.0.1:9200 #多个结点中间用逗号分隔

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bpkjONyg-1681790773239)(C:\Users\陈刚\AppData\Roaming\Typora\typora-user-images\image-20221225102727072.png)]

设置主启动类:

@SpringBootApplication
public class SearchApplication {
    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(SearchApplication.class, args);
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bsiWRagO-1681790773239)(C:\Users\陈刚\AppData\Roaming\Typora\typora-user-images\image-20221225102949502.png)]

springboot搭建完成后,我们只需要将我们前面的高级es获取数据的类注入springboot容器内,我们的springboot就可以拿来使用了:

已知我们在kibana插入了这个数据:

PUT /test_post/_doc/1
{
  "user":"tom",
  "postDate":"2019-07-18",
  "message":"trying out es"
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JyOTcqgy-1681790773239)(C:\Users\陈刚\AppData\Roaming\Typora\typora-user-images\image-20221225111035398.png)]

我们先配置springboot配置类:

@Configuration
public class ElestaticSearchConfig {
   

    @Value("${heima.elasticsearch.hostlist}")
    private String hostlist;
    @Bean(destroyMethod = "close")// RestClient用完后需要关闭,close是RestClient自带的关闭方法
    public RestHighLevelClient getRestHighLevelClient(){
   
        //按照逗号分割,因为可能会写有多个ip,拿出每个ip
        String[] split = hostlist.split(",");
        //定义一个数组将split存入该数组操作
        HttpHost[] httpHostArray = new HttpHost[split.length];
        for (int i = 0; i < split.length; i++) {
   
            String item = split[i];
            //将拿到的ip,端口分隔开存入httpArray数组
            httpHostArray[i] = new HttpHost(item.split(":")[0],
                    Integer.parseInt(item.split(":")[1]),"http");
        }
        //将数组传入实现对es的连接
        return new RestHighLevelClient(RestClient.builder(httpHostArray));
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZMdJG3EZ-1681790773239)(C:\Users\陈刚\AppData\Roaming\Typora\typora-user-images\image-20221225112911258.png)]

随后测试类测试查询test_post中的id为1的几个数据:

@SpringBootTest(classes =SearchApplication.class)
@RunWith(SpringRunner.class)
public class TestDocument {
    @Autowired
    RestHighLevelClient client;
    @Test
    public void test1() throws IOException {
        //1.连接请求
        GetRequest getRequest = new GetRequest("test_post","1");
        //执行
        GetResponse getResponse = client.get(getRequest, RequestOptions.DEFAULT);
        System.out.println(getResponse.getId());
        System.out.println(getResponse.getVersion());
        System.out.println(getResponse.getSource());
    }
}

运行后:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6rHtH1TV-1681790773239)(C:\Users\陈刚\AppData\Roaming\Typora\typora-user-images\image-20221225113047952.png)]

(1)输出可选参数:

在构建请求时,设置请求我们想要的参数

@SpringBootTest(classes =SearchApplication.class)
@RunWith(SpringRunner.class)
public class TestDocument {
   
    @Autowired
    RestHighLevelClient client;
    @Test
    public void test1() throws IOException {
   
        //1.连接请求
        GetRequest getRequest = new GetRequest("test_post","1");
        //设置不想要的字段为user,message字段的,
        String[] includes =Strings.EMPTY_ARRAY;
        String[] excludes =  new String[]{
   "user","message"};
        FetchSourceContext fetchSourceContext = new FetchSourceContext(true, includes, excludes);
        GetRequest getRequest1 = getRequest.fetchSourceContext(fetchSourceContext);

        //执行
        GetResponse getResponse = client.get(getRequest, RequestOptions.DEFAULT);
        System.out.println(getResponse.getId());
        System.out.println(getResponse.getVersion());
        System.out.println(getResponse.getSource());
    }
}

运行后,source中只打印输出了postDate字段的数据:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CVjMWbCl-1681790773239)(C:\Users\陈刚\AppData\Roaming\Typora\typora-user-images\image-20221225120911370.png)]

上述的操作都是同步查询:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ahgoDkW8-1681790773240)(C:\Users\陈刚\AppData\Roaming\Typora\typora-user-images\image-20221225121750622.png)]

(2)异步查询:
@SpringBootTest(classes =SearchApplication.class)
@RunWith(SpringRunner.class)
public class TestDocument {
   
    @Autowired
    RestHighLevelClient client;
    @Test
    public void test1() throws IOException {
   
        //1.连接请求
        GetRequest getRequest = new GetRequest("test_post","1");
        String[] includes =Strings.EMPTY_ARRAY;
        String[] excludes =  new String[]{
   "user","message"};
        FetchSourceContext fetchSourceContext = new FetchSourceContext(true, includes, excludes);
        GetRequest getRequest1 = getRequest.fetchSourceContext(fetchSourceContext);

        //执行
        //同步查询
//        GetResponse getResponse = client.get(getRequest, RequestOptions.DEFAULT);
        //异步查询:
        //创建一个监听器:监听发送异步请求查询是否能成功
        ActionListener<GetResponse> listener = new ActionListener<GetResponse>() {
   
           //请求成功时执行
            @Override
            public void onResponse(GetResponse getResponse) {
   
                System.out.println(getResponse.getId());
                System.out.println(getResponse.getVersion());
                System.out.println(getResponse.getSource());
            }

            //失败时执行:
            @Override
            public void onFailure(Exception e) {
   
                e.printStackTrace();
            }
        };
        client.getAsync(getRequest,RequestOptions.DEFAULT,listener);
        //由于我们在注解上设置客户端在发送请求后会立刻关闭client:@Bean(destroyMethod = "close")/
        //所以我们需要让主线程睡一会儿,防止测试时无法访问
        try {
   
            Thread.sleep(5000);
        } catch (InterruptedException e) {
   
            throw new RuntimeException(e);
        }
    }
}

运行后:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-65Sw5U2k-1681790773240)(C:\Users\陈刚\AppData\Roaming\Typora\typora-user-images\image-20221225132245022.png)]

我们可以获取结果时以 好几种方式来拿到结果,按照需求来给定结果:

 // 获取结果
        if (getResponse.isExists()) {
   
            long version = getResponse.getVersion();

            String sourceAsString = getResponse.getSourceAsString();//检索文档(String形式)
            System.out.println(sourceAsString);
            byte[] sourceAsBytes = getResponse.getSourceAsBytes();//以字节接受
            Map<String, Object> sourceAsMap = getResponse.getSourceAsMap();
            System.out.println(sourceAsMap);

        }else {
   

        }

13 . springboot进行文档新增数据操作

	@Autowired
    RestHighLevelClient client;
@Test
    public void testAdd() throws IOException {
   
        //1.构建请求
//        PUT /test_post/_doc/2
        //构建请求头:
        IndexRequest request = new IndexRequest("test_post");
        request.id("3");
        //构建请求体:四种方法
        //方法一:
        String  jsonString = "{\n" +
                "  \"user\":\"tom\",\n" +
                "  \"postDate\":\"2019-07-18\",\n" +
                "  \"message\":\"trying out es\"\n" +
                "}\n";
        request.source(jsonString, XContentType.JSON);//插入的字符串是json
//        //方法二:
//        Map<String, Object> jsonMap = new HashMap<>();
//        jsonMap.put("user","tom");
//        jsonMap.put("postDate","2019-07-18");
//        jsonMap.put("message","trying out es");
//        request.source(jsonMap);
//        //方法三:
//        XContentBuilder builder = XContentFactory.jsonBuilder();
//        builder.startObject();
//        {
   
//            builder.field("user","tom");
//            builder.field("postDate","2019-07-18");
//            builder.field("message","trying out es");
//        }
//        builder.endObject();
//        request.source(builder);
//        //方法四:
//        request.source("user","tom",
//                "postDate","2019-07-18",
//                "message","trying out es");

        //可选参数:
        //设置超时时间1s,下面两种都一样:
        request.timeout("1s");
        request.timeout(TimeValue.timeValueSeconds(1));
        //手动维护版本号:
        request.version(2);
        request.versionType(VersionType.EXTERNAL);

        //2.执行
        IndexResponse indexResponse = client.index(request, RequestOptions.DEFAULT);

        //3.获取结果
        System.out.println(indexResponse.getIndex());
        System.out.println(indexResponse.getId());
        System.out.println(indexResponse.getResult());
        //test_post
        //3
        //CREATED
    }

我们查询时可以同步,异步操作,同理新增数据也会有这些操作,同步操作:上述操作

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pCpxNxQL-1681790773240)(C:\Users\陈刚\AppData\Roaming\Typora\typora-user-images\image-20221225141326642.png)]

异步操作:

//创建一个监听器:监听发送异步请求查询是否能成功
ActionListener<IndexResponse> listener = new ActionListener<IndexResponse>() {
   

    @Override
    public void onResponse(IndexResponse indexResponse) {
   
        System.out.println(indexResponse.getIndex());
        System.out.println(indexResponse.getId());
        System.out.println(indexResponse.getResult());
    }

    @Override
    public void onFailure(Exception e) {
   
        e.printStackTrace();
    }
};

//3.获取结果
client.indexAsync(request,RequestOptions.DEFAULT,listener);
//test_post
//3
//CREATED

我们这里使用同步操作,获取结果后进行一些判断:

System.out.println(indexResponse.getIndex());
System.out.println(indexResponse.getId());
System.out.println(indexResponse.getResult());
//如果这个操作是插入新增操作,就打印出来
if(indexResponse.getResult() == DocWriteResponse.Result.CREATED){
   
    DocWriteResponse.Result result = indexResponse.getResult();
    System.out.println("CREATE---"+result.toString());
    //同理
}else if(indexResponse.getResult() == DocWriteResponse.Result.UPDATED){
   
    DocWriteResponse.Result result = indexResponse.getResult();
    System.out.println("update---" + result.toString());
}else{
   

}

运行后报错版本问题:

因为我们对数据进行了修改,数据的版本应该变化,我们设置的手动维护版本号:所以修改版本号+1:

//手动维护版本号:
request.version(3);
request.versionType(VersionType.EXTERNAL);

我们对该索引下id为3的数据的name进行修改:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LS2Q9b34-1681790773240)(C:\Users\陈刚\AppData\Roaming\Typora\typora-user-images\image-20221225150217398.png)]

显示出修改成功。

我们在java上拿到分片的信息,进行对分片的判断:

//对分片的操作:
ReplicationResponse.ShardInfo shardInfo = indexResponse.getShardInfo();
//判断成功的分片如果不等于总的主分片数
if(shardInfo.getTotal() != shardInfo.getSuccessful()){
   
    System.out.println("处理成功的分片数少于总分片");
}
//失败的分片
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值