先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7
深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新大数据全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
如果你需要这些资料,可以添加V获取:vip204888 (备注大数据)
正文
日期:9月12日 EureKaServer服务 Spring Cloud Ribbon负载均衡策略
SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈课程|黑马程序员Java微服务哔哩哔哩bilibili
1.今天所学内容摘要:
1.EureKaServer服务
Eureka 又称 服务注册中心,全部服务都需要进行注册才能使用,也是微服务架构中必不可少的组件。
1.1. Eureka 服务端
步骤一:使用IDEA快速创建Spring Boot项目,并且选择Eureka服务端(记得把Web的引用也勾选上,不然会出现项目启动不了的情况)
步骤二:在Spring Boot启动类上加Eureka服务端注解
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
步骤三:直接启动,默认端口是8080,http://localhost:8080
修改Eureka默认配置,修改配置如下:
################ 项目基本配置 ################
spring:
application:
# 对应注册Eureka中的服务名
name: eureka
1.2. Eureka 客户端
步骤一:采用IDEA快速创建Spring Boot项目,并且选择Eureka客户端依赖(Web也得勾选上,不然会出现项目启动不了)
步骤二:配置Eureka服务端地址,要是yml格式的
################ 项目基本配置 ################
server:
port: 8010
servlet:
# 项目访问路径前缀
context-path: /product
spring:
application:
# 注册到Eureka的服务名
name: product
################ Eureka配置 ################
eureka:
client:
service-url:
defaultZone: http://localhost:8080/eureka
步骤三:SpringBoot启动类上加上Eureka客户端注解,直接启动就可以了
步骤四:然后访问eureka后台管理页面,会发现有一个PRODUCT服务注册进来了,则表示没问题。
拓展了解:SpringCloud —— Eureka详细使用教程,以及实战案例演示-CSDN博客
2.Spring Cloud Ribbon负载均衡策略
负载均衡通器常有两种实现手段,一种是服务端负载均衡器,另一种是客户端负载均衡器,而 Ribbon 就属于后者——客户端负载均衡器。
客户端负载均衡器的实现原理是通过注册中心,如 Nacos,将可用的服务列表拉取到本地(客户端),再通过客户端负载均衡器(设置的负载均衡策略)获取到某个服务器的具体 ip 和端口,然后再通过 Http 框架请求服务并得到结果
2.1.负载均衡设置
//定义全局负载均衡:使用代码方式(配置在启动类中一般)
@Bean
public IRule randomRule(){
return new RandomRule();
}
//定义局部微服务的负载均衡:使用配置文件方式
userservice:
ribbon:
NFLoadBalancerRuleClassName: comnetflix,loadbalancer,RandomRule #负载均衡规则
Ribbon 内置了 7 种负载均衡策略:轮询策略、权重策略、随机策略、最小连接数策略、重试策略、可用性敏感策略、区域性敏感策略,并且用户可以通过继承 RoundRibbonRule 来实现自定义负载均衡策略
拓展了解:Spring Cloud Ribbon中的 7 种负载均衡策略! - 知乎
2.所遇到的问题描述:
3.扩展学习部分:
4.学习总结:
经过漫长岁月,感觉在去看视频学习有点苦恼了,今天主要是了解了一下微服务的部分内容,微服务说到底其实就是多模块开发的高级版本,多模块开发是指在一个服务端中,将各个功能拆分实现,说到底还是一起的;微服务开发就是将多模块开发延申开来,从一个服务端拆分,由多模块变为多服务端同步开发,从前的各模块之间还能通过依赖直接调用,现在的各服务端之间通过请求接口的方式来调用另一业务的数据,从而达到连接,对于微服务之间个业务服务端的连接同步的也有相应的管理方式如Nacos。
日期:9月13日 Ribbon饥饿加载 SpringCloud Nacos组件
SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈课程|黑马程序员Java微服务哔哩哔哩bilibili
Docker部署:Docker(黑马)_黑马 docker-CSDN博客
SpringAMQP(MQ):RabbitMQ(黑马spring cloud笔记)_rabbitmq 黑马 csdn-CSDN博客
1.今天所学内容摘要:
1.Ribbon饥饿加载
SpringCloud底层其实是利用了一个名为Ribbon的组件,来实现负载均衡功能的
Ribbon默认是采用懒加载的,及第一次访问时才会去创建LoadBalanceClient,因为创建的过程中要去做服务拉取,所以请求时间会很长;而饥饿加载则会在项目启动时就去创建,降低了第一次访问的耗时。
#基础配置:
ribbon:
eager-load:
enabled: true # 开启饥饿加载
clients: # 指定饥饿加载的服务名称
- userservice
概念:Nacos服务分级存储模型:服务-集群-实例
Nacos控制台中可设置权重比,用于设置访问实例的概率
拓展了解:SpringCloud学习笔记(黑马)(三)——nacos组件_nacos maven依赖-CSDN博客(三)——nacos组件_nacos maven依赖-CSDN博客")
2.SpringCloud Nacos组件
- Nacos与eureka的共同点 都支持服务注册和服务拉取 都支持服务提供者心跳方式做健康检测
- Nacos与Eureka的区别 Nacos支持服务端主动检测提供者状态:临时实例采用心跳模式,非临时实例采用主动检测模式临时实例心跳不正常会被剔除,非临时实例则不会被剔除 Nacos支持服务列表变更的消息推送模式,服务列表更新更及时 Nacos集群默认采用AP方式,当集群中存在非临时实例时,采用CP模式;Eureka采用AP方式
- 因为springcloud定义了规范,所以只需要修改组件和配置而不用修改代码,就可以实现原来的功能
//root的pom.xml导入依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.5.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
//service的pom.xml导入依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
//配置服务中心地址
server:
port: 8081
spring:
application:
name: server-order
cloud:
nacos:
server-addr: 127.0.0.1:8848 //nacos服务端地址
discovery:
cluster-name: HZ //集群属性配置
namespace: 4d6ce343-9e1b-44df-a90f-2cf2b6b3d177 //命名空间 (dev环境)
ephemeral: false //是否是时实例
service-user:
ribbon:
NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule //优先使用本地集群
注意:一般有了bootstrap配置文件后,只需要在application中配置一下当前的配置环境即可,例如(dev,pro等),在bootstrap中配置nocas作为服务中心和配置中心等
3.SpringAMQP(MQ)
#1.依赖------------------------------------
<!--AMQP依赖,包含RabbitMQ-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
#2.配置------------------------------------配置都是一样的
spring:
rabbitmq:
host: 190.92.246.107 # 主机名
port: 5672 # 端口
virtual-host: / # 虚拟主机
username: root
password: 123456
listener: #AMQP有一个消息预取机制,预取多少条消息是可以配置的。
simple:
prefetch: 1 #预取1条
#3.实现------------------------------------
#发布者
public class PublisherTest {
@Autowired
private RabbitTemplate rabbitTemplate;
@Test
public void testSimpleQueue() {
String queueName = "simple.queue";
String message = "hello, spring amqp";
rabbitTemplate.convertAndSend(queueName, message);
}
}
#消费者
@Component
public class SpringRabbitListener {
@RabbitListener(queues = {"simple.queue"})
public void listenSimpleQueue(String msg) {
System.out.println(msg);
}
}
注意:使用前需要去Linux服务器上部署启动RabbitMQ
拓展了解:SpringCloud学习笔记(黑马)(三)——nacos组件_nacos maven依赖-CSDN博客(三)——nacos组件_nacos maven依赖-CSDN博客")
2.所遇到的问题描述:
3.扩展学习部分:
4.学习总结:
今天学习状态还是不怎么样,迷迷糊糊的;今天主要学习了RabbitMQ的使用,以及SpringAMQP的应用;对于这部分的学习只能说是学的云里雾里;它讲的是消息队列的内容,主要就是模拟发送消息后由多人接收还是单人处理,我听起来感觉还好,但是就是有点不懂这方面的应用该用在哪里,微服务学到的东西感觉暂时都用不上,学习的使用操作起来也不是那么好操作,缺少了自己的想法;而且现在学习的好多东西都需要应用至Linux系统上感觉暂时都用不到现在的需求上。
日期:9月14日 Nacos配置管理 Http客户端 Feign 与 统一网关Gateway
SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈课程|黑马程序员Java微服务哔哩哔哩bilibili
【黑马】Feign学习笔记_feign 扫描包的-CSDN博客
1.今天所学内容摘要:
1.Nacos配置管理
Nacos一方面可以将配置集中管理,另一方可以在配置变更时,及时通知微服务,实现配置的热更新。
注意:项目的核心配置,需要热更新的配置才有放到nacos管理的必要。基本不会变更的一些配置还是保存在微服务本地比较好。
1.1. 从微服务拉取配置
微服务要拉取nacos中管理的配置,并且与本地的application.yml配置合并,才能完成项目启动
spring引入了一种新的配置文件:bootstrap.yaml文件,会在application.yml之前被读取,流程如下:
1)引入nacos-config依赖
首先,在user-service服务中,引入nacos-config的客户端依赖:
<!--nacos配置管理依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
2)添加bootstrap.yaml
然后,在user-service中添加一个bootstrap.yaml文件,内容如下:
spring:
application:
name: userservice # 服务名称
profiles:
active: dev #开发环境,这里是dev
cloud:
nacos:
server-addr: localhost:8848 # Nacos地址
config:
file-extension: yaml # 文件后缀名
**注意:这里会根据spring.cloud.nacos.server-addr获取nacos地址,再根据 s p r i n g . a p p l i c a t i o n . n a m e − {spring.application.name}- spring.application.name−{spring.profiles.active}.${spring.cloud.nacos.config.file-extension}**作为文件id,来读取配置。
3)读取nacos配置
在user-service中的UserController中添加业务逻辑,读取pattern.dateformat配置:
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@Value("s{pattern.dateformat}")
private String dateformat;
GetMapping("now")
public String now()[
return LocalDateTime.now().format(DateTimeFormatter.ofPattern(dateformat));
}
}
1. 2.配置热更新
我们最终的目的,是修改nacos中的配置后,微服务中无需重启即可让配置生效,也就是配置热更新。
要实现配置热更新,可以使用两种方式:
Nacos配置更改后,微服务可以实现热更新,方式:
1.通过@Value注解注入,结合@RefreshScope来刷新
2.通过@ConfigurationProperties注入,自动刷新
注意事项:
建议将一些关键参数,需要运行时调整的参数放到nacos配置中心,一般都是自定义配置
配置共享:
微服务启动时,会去nacos读取多个配置文件,如:
1.[spring.application.name]-[spring.profiles.active].yaml,例如:userservice-dev.yaml
2.[spring.application.name].yaml,例如:userservice.yaml
而[spring.application.name].yaml不包含环境,因此可以被多个环境共享。
1.3. 配置共享
微服务启动时,会去nacos读取多个配置文件,如: 1.[spring.application.name]-[spring.profiles.active].yaml,例如:userservice-dev.yaml 2.[spring.application.name].yaml,例如:userservice.yaml 而[spring.application.name].yaml不包含环境,因此可以被多个环境共享。
简单流程如下:
1)添加一个环境共享配置
我们在nacos中添加一个userservice.yaml文件
2)在user-service中读取共享配置
在user-service服务中,修改PatternProperties类,读取新添加的属性,修改UserController,添加一个方法
3)运行两个UserApplication,使用不同的profile
修改UserApplication2这个启动项,改变其profile值
4)配置共享的优先级
当nacos、服务本地同时出现相同属性时,优先级有高低之分
1. 4.搭建Nacos集群
Nacos生产环境下一定要部署为集群状态。
其中包含3个nacos节点,然后一个负载均衡器代理3个Nacos。这里负载均衡器可以使用nginx
1.4.1搭建集群
因为搭建集群内容比较广泛,所以只是表述流程,具体内容都可以百度到
搭建集群的基本步骤:
- 搭建数据库,初始化数据库表结构
- 下载nacos安装包
- 配置nacos
- 启动nacos集群
- nginx反向代理
2.Http客户端 Feign 与 统一网关Gateway
网关功能:
- 身份认证和权限校验 对工作人员或者是内部人员才能允许查看敏感信息 一切请求先到网关再到微服务,这样就能做到身份认证和权限校验
- 服务路由、负载均衡
倘若我们通过了身份认证和权限校验,那怎么知道访问哪个微服务呢?
服务路由: gateway网关不能处理对应的业务(比如用户查询功能),所以将请求转发到处理用户查询的服务(比如说userservice),因此网关必须根据请求判断把请求放到哪个服务里面
**负载均衡:**同样是userservice,但是可能有多个实例,此时就要根据负载均衡的规则来判断向哪个服务发送请求(从多个实例里面挑一个)
- 请求限流 对微服务的一种保护措施 限制人进入的流量,能够允许用户请求的量 比如我们限制500次用户请求,当超过500次之后就会限制进入,要不等着要不回去等人少的时候再来
2.1 搭建网关的步骤
2.1.1 创建新module并引入依赖
创建新的module,引入SpringCloudGateway的依赖和nacos的服务发现依赖:
<!--网关依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!--nacos服务发现依赖 新的module(Gateway)也是一个微服务,也需要服务注册或者从nacos拉取服务-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency>
2.1.2 编写路由配置及nacos地址
server:
port: 10010 # 网关端口,这个随便自己配置
spring:
application:
name: gateway # 服务名称
cloud:
nacos:
server-addr: localhost:8848 # nacos地址
# 上面的是nacos的服务注册与发现
# 下面的才是网络的路由配置
gateway:
routes: # 网关路由配置
- id: user-service # 路由id,自定义,只要唯一即可
# uri: http://127.0.0.1:8081 # 路由的目标地址 http就是固定地址
uri: lb://userservice # 路由的目标地址 lb就是负载均衡,后面跟服务名称
predicates: # 路由断言,也就是判断请求是否符合路由规则的条件
- Path=/user/** # 这个是按照路径匹配,只要以/user/开头就符合要求
解析: uri: http://127.0.0.1:8081 这是向一个具体的ip和端口进行路由,相当于把路由直接写死了,将来都往这个自己去发,我们一般不使用这种方式 uri: lb://userservice lb 就是负载均衡(loadBalance,代表路由的时候要做负载均衡),后面userservice是服务名 predicates 路由断言,判断请求是否符合路由规则的条件
2.1.3 访问Gateway
我们的gateway项目中只有一个pom.xml配置文件一个启动类,并没有做任何的处理逻辑,但是却能访问到userservice中的数据
2.2 总结
网关搭建步骤:
- 创建项目,引入nacos服务发现和gateway依赖
- 配置application.yml,包括服务基本信息、nacos地址、路由
路由配置包括:
- 路由id:路由的唯一标示
- 路由目标(uri):路由的目标地址,http代表固定地址,lb代表根据服务名负载均衡
- 路由断言(predicates):判断路由的规则
- 路由过滤器(filters):对请求或响应做处理
拓展了解:Nacos配置管理-CSDN博客
2.所遇到的问题描述:
3.扩展学习部分:
4.学习总结:
最近学习心无余力有足,感觉学习的东西一下子就高大上了,难以读懂,今天基于上一天学习内容,进行完善,主要是优化了微服务之间相互调用的方式,通过Feign优化调用;且对于微服务的安全方面学习了Gateway网关,主要作用就是在用户与微服务之间建立一道拦截措施,只有满足条件的人才能通过,类似于拦截器过滤器之类的东西;然后还接触了Docker部署,这玩意真的无语,要记的东西太多了笔记中索性不屑,直接同网址学习吧;总结的来讲今天学的一塌糊涂。,好的不能再好了!!!
日期:9月18日 部署单点ES Restclient操作索引库
SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈课程|黑马程序员Java微服务哔哩哔哩bilibili
安装教程:Elastic Search 安装部署最全教程(Docker)_docker安装es-CSDN博客
索引库:索引库操作-CSDN博客
文档操作:黑马学ElasticSearch(二)-CSDN博客
1.今天所学内容摘要:
1.1.部署单点ES
1.创建网络 #让ES与kibana容器互联
docker network create es-net
2.下载ES以及Kibana
docker pull elasticsearch:7.12.1
docker pull kibana:7.12.1
3.运行es
docker run -d \
--name es \
-e "ES_JAVA_OPTS=-Xms512m -Xmx512m" \
-e "discovery.type=single-node" \
-v es-data:/usr/share/elasticsearch/data \
-v es-plugins:/usr/share/elasticsearch/plugins \
--privileged \
--network es-net \
-p 9200:9200 \
-p 9300:9300 \
elasticsearch:7.12.1
4.部署kibana
docker run -d \
--name kibana \
-e ELASTICSEARCH_HOSTS=http://es:9200 \
--network=es-net \
-p 5601:5601 \
kibana:7.12.1
5.安装IK分词器
# 进入容器内部
docker exec -it es bash
# 进入bin目录
cd /usr/share/elasticsearch/bin
# 在线下载并安装
./elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.12.1/elasticsearch-analysis-ik-7.12.1.zip
#退出
exit
#重启容器
docker restart es
1.2.Restclient操作索引库
什么是RestClient
ES官方提供了各种不同语言的客户端,用来操作ES
这些客户端的本质就是组装DSL语句,通过http请求发送给ES
其中的Java Rest Client又包括两种:
- Java Low Level Rest Client
- Java High Level Rest Client
1)创建索引库,最关键的是mapping映射,而mapping映射要考虑的信息包括:
- 字段名、字段数据类型,可以参考数据表结构的名称和类型
- 是否参与搜索要分析业务来判断,例如图片地址,就无需参与搜索
- 是否分词呢要看内容,内容如果是一个整体就无需分词,反之则要分词
- 分词器,我们可以统一使用ik_max_word
2)初始化Restclient
步骤1:引入es的RestHighLevelClient依赖
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
</dependency>
步骤2:因为SpringBoot默认的ES版本是7.6.2,所以我们需要覆盖默认的ES版本
<properties>
<java.version>1.8</java.version>
<elasticsearch.version>7.12.1</elasticsearch.version>
</properties>
步骤3:初始化RestHighLevelClient
public class HotelIndexTest {
private RestHighLevelClient client;
@BeforeEach
void setUp() {
this.client = new RestHighLevelClient(RestClient.builder(
HttpHost.create("http://192.168.56.100:9200")
));
}
@AfterEach
void tearDown() throws IOException {
this.client.close();
}
}
3) 创建索引库
整体分为三步:
- (1)创建Request对象;因为是创建索引库的操作,因此Request是CreateIndexRequest
- (2)添加请求参数,其实就是DSL的JSON参数部分;因为json字符串很长,这里是定义了静态字符串常量MAPPING_TEMPLATE,让代码看起来更加优雅
- (3)发送请求,client.indices()方法的返回值是IndicesClient类型,封装了所有与索引库操作有关的方法
2.所遇到的问题描述:
3.扩展学习部分:
4.学习总结:
今天学习了一下对ES索引的使用,索引就好比数据库的另类版,主要不是用于存储数据的,但是在学习中,视频中暂时教的只是将数据库中数据按照索引库所需要的要求放入;然后简单的讲了如何增删改查等操作,没有讲到ES分词的使用,怎么样的应用到软件或者网页中,我无法理解ES的工作原理是什么,当ES分词后如何实现的搜索,又如何将我们所需要的数据呈现出来;自从学习了微服务就感觉有一种脱离实际的感觉,无法将微服务用到我现在所学的项目中去,没有代入感;
日期:9月19日
SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈课程|黑马程序员Java微服务哔哩哔哩bilibili
1.今天所学内容摘要:
1.1.DSL查询文档以及Restclient查询文档
ES的搜索引擎中主要包括{查询、分页、排序、高亮}等功能组成
Elasticsearch提供了基于JSON的DSL(Domain Specific Language)来定义查询。常见的查询类型包括:
- 查询所有:查询出所有数据,一般测试用。例如:match_all
- 全文检索(full text)查询:利用分词器对用户输入内容分词,然后去倒排索引库中匹配。例如: match_query multi_match_query
- 精确查询:根据精确词条值查找数据,一般是查找keyword、数值、日期、boolean等类型字段。例如:ids,range,term
- 地理(geo)查询:根据经纬度查询。例如 geo_distance geo_bounding_box
- **复合(compound)查询:**复合查询可以将上述各种查询条件组合起来,合并查询条件。例如:bool,function_score
查询的语法基本一致:
GET /indexName/_search
{
"query": {
"查询类型": {
"查询条件": "条件值"
}
}
}
1.2.全文检索查询
1.2.1.使用场景
全文检索查询的基本流程如下:
- 对用户搜索的内容做分词,得到词条
- 根据词条去倒排索引库中匹配,得到文档id
- 根据文档id找到文档,返回给用户
比较常用的场景包括:
- 商城的输入框搜索
- 百度输入框搜索
1.2.2.基本语法
常见的全文检索查询包括:
- match查询:单字段查询
- multi_match查询:多字段查询,任意一个字段符合条件就算符合查询条件
//match查询语法如下:
GET /indexName/_search
{
"query": {
"match": {
"FIELD": "TEXT"
}
}
}
//mulit_match语法如下:
GET /indexName/_search
{
"query": {
"multi_match": {
"query": "TEXT",
"fields": ["FIELD1", " FIELD12"]
}
}
}
1.2.4.总结
match和multi_match的区别是什么?
- match:根据一个字段查询
- multi_match:根据多个字段查询,参与查询字段越多,查询性能越差
注意:DSL查询语句还有很多大多都是重复的语法,不在演示
2.所遇到的问题描述:
3.扩展学习部分:
4.学习总结:
今天学习了DSL查询文档以及对应的Restclient查询文档,总体来讲两者的语法是差不多的,只要了解了一边的应用,另一边就能快速学会,因此总体来讲今天学习还算可以,但是ES搜索引擎的内容还是太多了,不是很好理解;单个查询文档的学习就有好多内容,一时半会无法完全学会,只有后期项目中多引用估计才能熟练掌握,现在只是对着视频学习实在是有点无力,ES搜索引擎的内容大都是配套的,我现在就像是学了就忘,以前学习的内容已经忘记的差不多了,无法完整的完善一个功能到现在学习的地步,现在学习的内容太依赖于之前所学的配置了,之前的不懂,现在学起来就更加费劲。
日期:9月20日
ElasticSearch基础——聚合、补全、集群。高亮+自定义分词器+自动补全+前后端消息同步
所学出处:SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈课程|黑马程序员Java微服务_哔哩哔哩_bilibili
1.今日内容摘要:
1.聚合
1.1.聚合的种类
聚合常见的有三类:
-
桶(Bucket)聚合:用来对文档做分组
- TermAggregation:按照文档字段值分组,例如按照品牌值分组、按照国家分组
- Date Histogram:按照日期阶梯分组,例如一周为一组,或者一月为一组
-
度量(Metric)聚合:用以计算一些值,比如:最大值、最小值、平均值等
- Avg:求平均值
- Max:求最大值
- Min:求最小值
- Stats:同时求max、min、avg、sum等
-
管道(pipeline)聚合:其它聚合的结果为基础做聚合
注意:参加聚合的字段必须是不能分词,例如是keyword、日期、数值、布尔类型
1.2.DSL实现聚合
1.2…1.Bucket聚合语法
GET /hotel/_search
{
"size": 0, // 设置size为0,结果中不包含文档,只包含聚合结果。如果设为20,就是既展示20个brand查询的"hits",又展示聚合"aggregations"
"aggs": { // 定义聚合
"聚合名": { //给聚合起个名字,例如brandAgg。查询结果里聚合名会嵌套在"aggregations"里
"terms": { // 聚合的类型,按照品牌值聚合,所以选择term
"field": "字段名", // 参与聚合的字段,例如brand
"size": 20 // 希望获取的聚合结果数量
"order": {
"_count": "asc" //按升序排序,默认是降序
}
}
}
}
}
1.2.2."query"标签限定聚合范围
“query” 标签和“aggs”标签是并列的,因此“query” 标签不为空就是限定了聚合范围。
默认情况下,Bucket聚合是对索引库的所有文档做聚合,但真实场景下,用户会输入搜索条件,因此聚合必须是对搜索结果聚合。那么聚合必须添加限定条件。
GET /hotel/_search
{
"query": { //添加query标签,限制查询文档内容
"range": { //range:根据值的范围查询
"price": { //查询价格字段
"lte": 200 // 只对200元以下的文档聚合
}
}
},
"size": 0,
"aggs": {
"brandAgg": {
"terms": {
"field": "brand",
"size": 20
}
}
}
}
1.2.3.度量(Metric)聚合语法
聚合与聚合之间是可以实现嵌套的,就像文档中的筛选后排序一样;聚合之间的语法配合也可以实现
GET /hotel/_search
{
"size": 0,
"aggs": {
"brandAgg": {
"terms": {
"field": "字段名",
"size": 20
},
"aggs": { // 是brands聚合的子聚合,也就是分组后对每组分别计算
"聚合名如score_stats": { // 聚合名称
"stats": { // 聚合类型,这里stats可以计算min、max、avg等。stats是statistics统计缩写
"field": "score" // 聚合字段,这里是score
}
}
}
}
}
}
1.3.RestAPI实现聚合
1.3.1.Restclient语法
聚合条件与query条件同级别,因此需要使用**request.source()**来指定聚合条件。
注意:request.source().aggregation(),聚合不是数组,虽然DSL是"aggs",但它不是数组,所以不是request.source().aggregations()
聚合结果:
聚合的解析与查询的解析是一样的都是通过JSON逐层解析的:
**注意:**response.getAggregations().get(“brandAgg”)的返回结果要是Terms,注意包别导错了,提示的第一个不是es的包。
2.自动补全
当用户在搜索框输入字符时,我们应该提示出与该字符有关的搜索项;
2.1.pinyin拼音分词器
下载地址:https://github.com/medcl/elasticsearch-analysis-pinyin
安装方式与IK分词器一样,分三步:
①解压
②上传到虚拟机中,elasticsearch的plugin目录
/var/lib/docker/volumes/es-plugins/_data
③重启elasticsearch
docker restart es
④测试
详细安装步骤可以参考IK分词器的安装过程。
POST /_analyze
{
"text": "如家酒店还不错",
"analyzer": "pinyin"
}
结果:
2.2.实现方法
默认的拼音分词器会将每个汉字单独分为拼音,而我们希望的是每个词条形成一组拼音,需要对拼音分词器做个性化定制,形成自定义分词器。
elasticsearch中分词器(analyzer)的组成包含三部分:
- **character filters:**在tokenizer之前对特殊字符进行处理。例如删除字符、替换字符
- **tokenizer:**将文本按照一定的规则切割成词条(term)。例如keyword,就是不分词;还有ik_smart
- **tokenizer filter:**将tokenizer输出的词条做进一步处理,tokenizer的词条结果依然在,只是处理后新加了一些。例如大小写转换、同义词处理、拼音处理等
拼音分词器处理文档流程:
自定义分词器,把ik分词结果过滤成拼音:
settings-analysis下定义分词器analyzer和filter
PUT /test
{
//设置分词器和过滤器
"settings": {
"analysis": {
"analyzer": { // 自定义分词器
"my_analyzer": { // 分词器名称,这里不需要指定character filters过滤器,因为没有特殊字符需要处理
"tokenizer": "ik_max_word",
"filter": "my_py_filter" //对ik分词结果做进一步处理
}
},
"filter": { // 自定义tokenizer filter
"my_py_filter": { // 过滤器名称
"type": "pinyin", // 过滤器类型,填写分词器名,这里是pinyin
"keep_full_pinyin": false,//eg: 刘德华> [liu,de,hua], default: true
"keep_joined_full_pinyin": true,//eg: 刘德华> [liudehua], default: false
"keep_original": true,//保留原始输入,默认false
"limit_first_letter_length": 16,//
"remove_duplicated_term": true,//
"none_chinese_pinyin_tokenize": false// 默认true。eg: liudehuaalibaba13zhuanghan -> liu,de,hua,a,li,ba,ba,13,zhuang,han
}
}
}
},
//创建索引
"mappings": {
"properties": {
"name": {
"type": "text",
"analyzer": "my_analyzer", //拼音分词器适合在创建索引时使用,不能在搜索时候用
"search_analyzer": "ik_smart" //如果搜索时用拼音分词器,搜索"狮子爱跳舞",会搜出"虱子"等同音字
}
}
}
}
注意:拼音分词器适合在创建索引时使用,不能在搜索时候用,如果搜索时用拼音分词器,搜索"狮子爱跳舞",会搜出"虱子"等同音字。
2.3.自动补全查询conmpetion suggester
Completion Suggester查询实现自动补全功能。匹配用户输入内容开头的词条并返回。为了提高补全查询的效率,对于文档中字段的类型有一些约束:
-
参与补全查询的字段必须是completion类型,数据是字符串数组。completion译为完成
-
字段的内容一般是用来补全的多个词条形成的数组。
创建索引库:
// 创建索引库
PUT test
{
"mappings": {
"properties": {
"title":{
"type": "completion"
}
}
}
}
插入数据:
// 示例数据
POST test/_doc
{
"title": ["天苍苍", "野茫茫"]
}
POST test/_doc
{
"title": ["天府", "天下"]
}
POST test/_doc
{
"title": ["世界", "黄天"]
}
自动补全查询:
// 自动补全查询
GET /test/_search
{
"suggest": {
"titleSuggest": { //例如自定义查询名称
"text": "天", // 关键字
"completion": {
"field": "title", // 补全查询的字段,例如title
"skip_duplicates": true, // 跳过重复的
"size": 10 // 获取前10条结果
}
}
}
}
2.4.创建新索引库,使用自定义分词器
//酒店数据索引库。先删除旧的,再新的
DELETE /hotel
PUT /hotel
{
"settings": {
"analysis": {
"analyzer": {
"text_anlyzer": { //ik+拼音过滤
"tokenizer": "ik_max_word",
"filter": "py"
},
"completion_analyzer": { //keyword+拼音过滤,相当于又保持关键词,又新加定制版拼音分词
"tokenizer": "keyword",
"filter": "py"
}
},
"filter": {
"py": {
"type": "pinyin",
"keep_full_pinyin": false,
"keep_joined_full_pinyin": true,
"keep_original": true,
"limit_first_letter_length": 16,
"remove_duplicated_term": true,
"none_chinese_pinyin_tokenize": false
}
}
}
},
"mappings": {
"properties": {
"id":{
"type": "keyword"
},
"name":{
"type": "text",
"analyzer": "text_anlyzer", //新建文档时分词器用ik+拼音过滤
"search_analyzer": "ik_smart", //搜索分词器用ik
"copy_to": "all"
},
"address":{
"type": "keyword",
"index": false
},
"location":{
"type": "geo_point"
},
"pic":{
"type": "keyword",
"index": false
},
"all":{
"type": "text",
"analyzer": "text_anlyzer",
"search_analyzer": "ik_smart"
},
"suggestion":{ //补全字段suggestion
"type": "completion", //补全字段类型必须completion
"analyzer": "completion_analyzer" //补全分词器,keyword+拼音过滤
}
}
}
}
2.5.自动补全查询的JavaAPI,SuggestBuilder()
suggest和query是平级的;
而自动补全的结果也比较特殊,解析的代码如下:
2.所遇问题描述:
3.扩展部分:
使用教程:
ElasticSearch基础3——聚合、补全、集群。黑马旅游检索高亮+自定义分词器+自动补全+前后端消息同步_java黑马酒店概述-CSDN博客
4.学习总结:
今天学习的速度相比之前慢了许多,有点心不在焉了;需要调整一下;今天主要学习了ES中的聚合语法,其中聚合的使用类似与数据库的聚集函数,同时ES中的聚合支持嵌套式,就比如文档的筛选后需要排序一样;聚合的使用场景通常会出现在数据的分类筛选中,如需要知道学校的学院有哪些,就可以通过聚合进行学院的分组;其次今天也学习了一些自动补全相关的内容,主要是扩展了之前的IK分词器,IK分词器支持的是中文分词,因此此次补上了拼音的分词器;自动补全的使用需要依赖于suggestion completion来定义需要自动补全的字段内容,同时通过于拼音分词器配合可以做到通过拼音首字母补全的功能,无论是聚合还是自动补全他们在java中的书写格式几乎和ES中编写是差不多的。
日期:9月21日
ElasticSearch基础——聚合、补全、集群。高亮+自定义分词器+自动补全+前后端消息同步
所学出处:SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈课程|黑马程序员Java微服务_哔哩哔哩_bilibili
1.今日内容摘要:
1.mysql与es数据同步
elasticsearch中的酒店数据来自于mysql数据库,因此mysql数据发生改变时,elasticsearch也必须跟着改变,这个就是elasticsearch与mysql之间的数据同步。
1.1.1.思路分析
常见的数据同步方案有三种:
- 同步调用
- 异步通知(学习)
- 监听binlog
1.1.2.异步通知
流程如下:
- hotel-admin对mysql数据库数据完成增、删、改后,发送MQ消息
- hotel-demo监听MQ,接收到消息后完成elasticsearch数据修改
2.MQ实现数据同步
2.1.1.思路
使用RabbitMQ的发布/订阅模型topic话题模式,支持不同的消息根据routingKey被不同的队列消费。先声明交换机、队列,增删两个routingKey。只需要增删两个队列,restapi里增改是一致的,id存在则修改,id不存在则新增。
忘了就回顾:SpringCloud基础4——RabbitMQ和SpringAMQP
步骤:
-
声明exchange、queue、RoutingKey
-
在hotel-admin中的增、删、改业务中完成消息发送
-
在hotel-demo中完成消息监听,并更新elasticsearch中数据
-
启动并测试数据同步功能
2.1.2前置操作
0)开启RabbitMQ
docker ps -a
docker start 容器名
管理端:
http://ip地址:15672/
1)引入依赖、yml
引入rabbitmq的依赖:
<!--amqp-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
yml:
server:
port: 8099
spring:
datasource:
druid:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/heima?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true
username: root
password: 1234
main:
banner-mode: off
rabbitmq: #MQ的相关配置
host: 192.168.200.131
port: 5672
username: itcast
password: 123321
virtual-host: / #虚拟主机
mybatis-plus:
configuration:
map-underscore-to-camel-case: true
global-config:
banner: false
2)常量类,声明队列交换机名称
在hotel-admin和hotel-demo中的cn.itcast.hotel.constatnts
包下新建一个类MqConstants
:
package cn.itcast.hotel.constants;
public class MqConstants {
/**
* 交换机
*/
public final static String HOTEL_EXCHANGE = "hotel.topic";
/**
* 监听新增和修改的队列
*/
public final static String HOTEL_INSERT_QUEUE = "hotel.insert.queue";
/**
* 监听删除的队列
*/
public final static String HOTEL_DELETE_QUEUE = "hotel.delete.queue";
/**
* 新增或修改的RoutingKey
*/
public final static String HOTEL_INSERT_KEY = "hotel.insert";
/**
* 删除的RoutingKey
*/
public final static String HOTEL_DELETE_KEY = "hotel.delete";
}
3)声明队列交换机
在config包下创建MqConfig,声明队列、交换机:
@Configuration
public class MqConfig {
@Bean
public TopicExchange topicExchange(){
//第二个参数为是否持久化,第三个参数为是否自动删除。两个参数默认值就是持久化、不自动删除
return new TopicExchange(MqConstants.HOTEL_EXCHANGE, true, false);
}
@Bean
public Queue insertQueue(){
return new Queue(MqConstants.HOTEL_INSERT_QUEUE, true);
}
@Bean
public Queue deleteQueue(){
return new Queue(MqConstants.HOTEL_DELETE_QUEUE, true);
}
@Bean
public Binding insertQueueBinding(){
return BindingBuilder.bind(insertQueue()).to(topicExchange()).with(MqConstants.HOTEL_INSERT_KEY);
}
@Bean
public Binding deleteQueueBinding(){
return BindingBuilder.bind(deleteQueue()).to(topicExchange()).with(MqConstants.HOTEL_DELETE_KEY);
}
}
**注意:**在RestClient的API中,全量修改与新增的API完全一致,判断依据是ID:
- 如果新增时,ID已经存在,则修改
- 如果新增时,ID不存在,则新增
3.集群
3.1概述
单机的elasticsearch做数据存储,必然面临两个问题:海量数据存储问题、单点故障问题。
- 海量数据存储问题:将索引库从逻辑上拆分为N个分片(shard),存储到多个节点
- 单点故障问题:将分片数据在不同节点备份(replica )
ES集群相关概念:
-
一个集群里有多个节点,每个节点都是一个es实例, 每个节点保存了自己的分片和一个其他节点备份的分片。
-
集群(cluster):一组拥有共同的 集群名 的 节点。
-
节点(node) :集群中的一个 Elasticearch 实例
-
分片(shard):索引可以被拆分为不同的部分进行存储,称为分片。在集群环境下,一个索引的不同分片可以拆分到不同的节点中
3.2.搭建ES集群
Docker Compose 使用的三个步骤:
- 使用 Dockerfile 定义应用程序的环境
- 使用 docker-compose.yml 定义构成应用程序的服务,这样它们可以在隔离环境中一起运行
- 执行 docker-compose up 命令(后面加-d是在后台运行)来启动并运行整个应用程序
3.2.1.创建es集群
创建同一个集群的三个节点,每个节点都是一个es实例:
①首先编写一个docker-compose.yml文件,上传到/root,内容如下:
#创建三个es容器,容器名和节点名都是es01、es02、es03。
version: '2.2'
services:
es01:
image: elasticsearch:7.12.1 #镜像名称
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注大数据)**
![img](https://img-blog.csdnimg.cn/img_convert/1df1b42e0af0186ec50a5a1c19b21cd5.png)
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
Binding deleteQueueBinding(){
return BindingBuilder.bind(deleteQueue()).to(topicExchange()).with(MqConstants.HOTEL_DELETE_KEY);
}
}
**注意:**在RestClient的API中,全量修改与新增的API完全一致,判断依据是ID:
- 如果新增时,ID已经存在,则修改
- 如果新增时,ID不存在,则新增
3.集群
3.1概述
单机的elasticsearch做数据存储,必然面临两个问题:海量数据存储问题、单点故障问题。
- 海量数据存储问题:将索引库从逻辑上拆分为N个分片(shard),存储到多个节点
- 单点故障问题:将分片数据在不同节点备份(replica )
ES集群相关概念:
-
一个集群里有多个节点,每个节点都是一个es实例, 每个节点保存了自己的分片和一个其他节点备份的分片。
-
集群(cluster):一组拥有共同的 集群名 的 节点。
-
节点(node) :集群中的一个 Elasticearch 实例
-
分片(shard):索引可以被拆分为不同的部分进行存储,称为分片。在集群环境下,一个索引的不同分片可以拆分到不同的节点中
3.2.搭建ES集群
Docker Compose 使用的三个步骤:
- 使用 Dockerfile 定义应用程序的环境
- 使用 docker-compose.yml 定义构成应用程序的服务,这样它们可以在隔离环境中一起运行
- 执行 docker-compose up 命令(后面加-d是在后台运行)来启动并运行整个应用程序
3.2.1.创建es集群
创建同一个集群的三个节点,每个节点都是一个es实例:
①首先编写一个docker-compose.yml文件,上传到/root,内容如下:
#创建三个es容器,容器名和节点名都是es01、es02、es03。
version: '2.2'
services:
es01:
image: elasticsearch:7.12.1 #镜像名称
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注大数据)**
[外链图片转存中...(img-Q4oTKGBN-1713326229717)]
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**