一、Mybatis部分
1、MyBatis中${}取值和#{}取值的区别?
#{}能够防止SQL注入,因为底层使用PreparedStatement对象,预编译,性能较高
${}不能防止SQL注入,因为底层使用Statement对象,不会预编译而是拼接字符串,性能较低
能使用#{}时尽量使用#{},如果需要动态传入表名或者字段名需要用 ${},比如,像 ORDER BY 时只能使用${}
2、MyBatis关联查询中,延迟加载和饥饿加载的区别?
延迟加载,是先从单表查询,需要使用关联数据的时候才发起关联查询,不用的时候不查询关联的数据,又叫懒加载,饥饿加载,是在查询时将关联的数据立即查询出来加载进内存,不管用不用。
3、MyBatis对象关联查询和集合关联查询怎么做?
单个关联对象用associate ,适用于多对一的关联查询,使用javaType来定义实体类型,集合用collection,适用于一对多的关联查询,使用ofType来定义集合的泛型类型。
4、MyBatis一级缓存和二级缓存的区别?
缓存,是指将从数据库查询出的数据存放在缓存中,下次使用相同查询时不必再从数据库查询,而是直接从缓存中读取,从而减轻数据库查询的压力,提高性能
mybaits中的一级缓存,是SqlSession级别,默认开启,使用同一个SqlSession发送相同的SQL时命中;它的生命周期和SqlSession一致,当调用SqlSession.close()方法时会释放缓存
mybatis中的二级缓存,是namespace级别,默认不开启,执行同一个namespace的相同statement,发送相同的SQL时命中;它的生命周期是程序结束
当SQL中执行了update()、delete()、insert()操作,则缓存中的数据都会清空
5、MyBaits的Mapper接口没有实现类为什么可以用@Autowired直接注入?
动态代理,赋值给mapper接口引用的对象其实是一个代理对象,这个代理对象是由 JDK 动态代理创建的。在解析mapper的时候,mybatis会通过java反射,获取到接口所有的方法。
当调用接口中方法时,将通过接口全限定名+方法名对应找到映射文件中namespace和id匹配的sql,然后将执行结果返回。
6、在MyBatis如何动态修改SQL?
使用Mybatis的拦截器可以做到,实现Interceptor接口
7、MyBatis的动态SQL标签有哪些?
if标签:条件判断
choose、when、otherwise标签:选择结构,类似java中的switch
trim标签:对包含的内容加上前缀,后缀
where标签:主要是用来简化SQL语句中where条件判断的,能智能的处理and or,不必担心多余导致语法错误
foreach标签:遍历元素。
include标签通过引用公共 SQL 片段实现代码重用,减少重复代码,提高可维护性。
8、Mybatis的mapper如何传递多个参数?
方式一,可以使用map进行传参,SQL中使用map的key来引用取值。
方式二,可以在SQL中使用#{param1},#{param2}...来引用取值,它是根据mapper接口对应方法中形参的顺序进行匹配的,不管接口方法的参数名字叫个啥,SQL都只能使用param1,param2,等来取值
方式三,可以使用@Param注解,给mapper接口方法的参数命名,在SQL中直接使用取的名字来引用
9、Mybatis,关联对象查询,使用嵌套子查询和JOIN连表有什么区别?
嵌套子查询,指的是在查询一个主对象的时候,使用单表查询,在resultmap中额外发送一个子sql查询关联对象,然后映射给主对象
连表join查询,指的是查询一个主对象的时候,使用join连表的方式把主对象和关联对象的数据一次性查出来,用resultmap映射结果
他们的区别,join连表查询只发一条sql就能把数据查询出来,嵌套子查询会有一个n+1的问题,就是说如果主查询出来n条数据,那么会额外发送n条子sql去查询对应的关联对象,加上主查询那1次,也就是n+1次,因此它的性能相对较低的,一般我们会使用join连表查询
10、为什么要使用连接池?
对数据库的操作都需要取得连接,使用完都需要关闭连接,如果每次操作需要打开关闭连接,这样系统性能很低下。连接池就可以动态的管理这些连接的申请,使用和释放,我们操作数据库只需要在连接池里获取连接,使用完放回连接池,这样大大节省了内存,提高效率。
数据库连接池的原理主要分为三部分:
-
第一,连接池的建立,在系统初始化时建立几个连接对象以便使用。
-
第二,连接池的管理,客户请求连接数据库时,首先查看连接池中是否有空闲连接,如果有直接分配,如果没有就等待,直到超出最大等待时间,抛出异常
-
第三,连接池的关闭,当系统关闭时,连接池中所有连接关闭
二、Redis部分
1、讲一下你理解的Redis,为什么Redis很快?
Redis是一种高性能的,开源的,C语言编写的非关系型数据库,可以对关系型数据库起到补充作用,同时支持持久化,可以将数据同步保存到磁盘
说Redis很快是相对于关系型数据库如mysql来说的,主要有以下因素
-
第一,数据结构简单,所以速度快
-
第二,直接在内存中读写数据,所以速度快
-
第三,采用多路IO复用模型,减少网络IO的时间消耗,避免大量的无用操作,所以速度快
-
第四,单线程避免了线程切换和上下文切换产生的消耗,所以速度快
2、你常用的Redis的数据存储结构有哪些,他们的使用场景分别是什么?
Redis存储形式是键值对,支持value形式包括String,List,Set,ZSet,Hash。
String可以用作简单数据的缓存、缓存json格式的字符串,还可以用作计数器,防攻击,验证码、登录过期等。
List可以用来做队列,秒杀等
Set可以用来去重
ZSet(Sorted Set):排行榜
Hash:键值对集合,适合存储对象
3、Redis每种存储结构说 4 个命令吧?
1)String
-
set key value 设置值
-
get key 取值
-
mset key value key value... 设置多个值
-
mget key key 获取多个值
-
incr key 将key中的值自增1
-
decre key 将key中的值自减1
2)List
-
lpush key value value... 从最左边设置值
-
rpush key value value... 从最右边设置值
-
lrange key start stop 查询key中指定区间的元素
-
lpop key 移出并返回key中最左边的元素
-
rpop key 移出并返回key中最右边的元素
3.Set
-
sadd key value1 value2 添加元素
-
smembers key 返回集合key中的所有元素
-
srem key member 删除集合key中member元素
-
scard key 查询集合key中的元素数量
4)ZSet
-
zadd key score value (score value)... 添加元素
-
zcard key 查询集合key中元素数量
-
zcount key min max 返回有序集合key中score 在min和max之间的元素
-
zrange key start stop 返回有序集合key中索引在start和stop之间的元素
5)Hash
-
hset key field value 添加元素
-
hget key field 获取key集合中field键对应的值
-
hmset key field value (field value)... 添加元素并批量添加子键值对
-
hmget key field field 获取key集合中所有的子键值对
4、你们项目是怎么用Redis的?
使用的是Springboot整合的redis,主要用来解决前后端分离后前后端会话问题(是否登录),以及验证码的问题。
5、怎么防止Redis宕机数据丢失问题?
通过对Redis持久化,把内存中的数据和命令,保存一份到磁盘中做备份,当Redis发生宕机,重启服务器的时候,会从磁盘重新加载备份的数据,从而解决数据丢失问题。
6、Redis持久化是什么?有几种方式?
将内存中的数据备份到磁盘的过程,就叫作持久化。
Redis持久化主要有两种方式,RDB和AOF,可以通过修改redis.conf进行配置。
RDB是记录数据快照,而AOF是记录写命令的
注:RDB配置---save 900 1 每 900 秒内如果至少有 1 个键被修改则保存快照
7、Redis有了AOF持久化为什么还要RDB?
AOF和RDB各有所长
-
RDB是记录数据快照,它的优点是只产生一个持久化文件,体积相对较小,启动恢复速度快,备份方便,它的缺点是没办法做到数据百分百不丢失,因为它是每隔一定时间保存一次,RDB不适用于大规模数据、不适用于实时持久化需求
-
AOF是记录写命令,它的优点是格式清晰,容易理解,数据更安全,采用append模式,即使持久化过程中宕机,也不影响已经保存的数据,它的缺点是文件体积较大,恢复速度慢。
结合使用RDB和AOF,可以提供双重保障。当Redis启动时,它首先会检查AOF文件是否存在,如果存在,则使用AOF文件来恢复数据。否则,它会检查RDB文件是否存在,如果存在,则使用RDB文件来恢复数据。这种双重保障可以确保系统的可靠性,即使一个持久化文件损坏或丢失,也可以从另一个文件中恢复数据。
8、Redis内存不够了怎么办?
方式一:增加物理内存
方式二:定期清理过期数据,使用淘汰策略,删掉一些老旧数据
方式三:集群
方式四:对数据进行压缩
9、你们Redis用在哪些业务上?用的什么存储结构?
主要用做缓存,比如:验证码,分类缓存,数据字典缓存,权限数据缓存,登录信息缓存等。
String类型的存储结构用的比较多,并且使用了Json格式进行序列化。
10、淘汰策略有哪些?你们用的哪种?
-
volatile-lru :从已设置过期时间的数据集中挑选最近最少使用的数据淘汰
-
volatile-ttl:从已设置过期时间的数据集中挑选将要过期的数据淘汰
-
volatile-random:从已设置过期时间的数据集中任意选择数据淘汰
-
allkeys-lru:从数据集中挑选最近最少使用的数据淘汰
-
allkeys-random:从数据集中任意选择数据淘汰
-
no-enviction:不使用淘汰
11、Redis事务和Mysql事务的区别?
Mysql的事务是基于日志,记录修改数据前后的状态来实现的;Mysql中的事务满足原子性:即一组操作要么同时成功,要么同时失败。适用于需要强一致性和持久性的场景,如金融系统、订单管理系统等。
而Redis的事务是基于队列实现的;Redis中的事务不满足原子性,即一组操作中某些命令执行失败了,其他操作不会回滚。适用于需要快速执行且数据一致性要求不高的场景,如缓存更新、计数器等。
因此对于比较重要的数据,应该存放在mysql中。
12、使用Redis如何实现消息广播?
Redis是使用发布订阅来实现广播的。
发布者通过 PUBLISH channel message向一个频道发布消息,该频道的所有订阅者都可以收到消息;订阅者通过 SUBSCRIBE channel命令订阅一个或多个频道,接收这些频道发布的消息。
13、为什么要使用Redis做缓存?
一个字,快。
缓存它指的是将数据库的数据同步到内存中,客户端获取数据直接从内存中获取。由于内存读写速度大于磁盘,而使用缓存能减少磁盘读取,大大提高查询性能。
Redis是一种高性能的,开源的,C语言编写的非关系型数据库。
我们一般会将经常查询的,不会经常改变的热点数据,保存到缓存中,提高响应速度。
14、缓存的执行流程?
1)客户端发起查询请求
2)判断缓存中是否有数据:如果有,直接返回;如果没有,就从数据库查询,再把数据同步到缓存
3)返回数据给客户端
15、你们怎么保证Redis和Mysql的一致性?
我们在代码中控制,如果mysql是写操作,直接把redis中的对应数据删除,下次查询数据会重新写入缓存。
我们的业务对一致性要求不是很高,因此采用了先操作mysql,后删除redis。在写数据库和删除缓存行代码之间如果有查询请求依然会查询到Redis中的老数据,但是这种情况非常极端,而且我们的业务也能容忍这种短暂的脏数据。
我还知道其他方案,比如延迟双删 , 监听Mysql事务日志自动同步Redis等。
16、SpringCache常用注解?
@EnableCaching:打在主启动类上,开启缓存功能
@Cacheable:打在方法上,表示该方法会开启缓存,打在类上,表示类中所有的方法都开启缓存,方法的返回值会自动写入缓存。如果缓存中已经有数据,方法将不会被调用,而是拿着缓存数据直接返回给客户端。
@CacheEvict:打在类或者方法上,会将缓存清除
@CachePut:更新缓存
@Caching:组合操作,包含了@Cacheable、@CachePut、@CacheEvict,适用于需要在一个方法上执行多个缓存操作的场景
@CacheConfig:打在类上,共享的一些常见缓存设置
17、了解缓存击穿,穿透,雪崩吗?怎么处理?
缓存击穿:缓存中没有,数据库中有的数据,由于某种原因比如缓存过期了,同时并发用户特别多,一时间都往数据库中读取数据。
-
解决方案:加互斥锁,只能允许一个线程访问数据库,然后其他线程就可以往内存中拿
缓存穿透:客户端频繁请求一个缓存和数据库中都没有数据,导致数据库压力大。
-
解决方案:布隆过滤器来判断数据库中有没有这个key
缓存雪崩:缓存重启,或者大量key失效,导致大量并发打到数据库
-
解决方案:为key设置不同的过期时间
18、Redis的主从有什么优点,和缺点?
优点是读写分离,主节点负责写操作,从节点负责读操作,分担了读的压力,同时能起到备份作用,防止数据丢失
缺点:是不能分担写的压力,主的单点故障没有解决,存储没有得到扩容;由于复制是异步进行的,主从之间可能会存在数据不一致的情况。在主节点发生故障后,最近的写操作可能尚未被复制到从节点。
19、解释一下Redis的哨兵模式。哨兵的不足?
当主服务器中断服务后,可以将一个从服务器升级为主服务器 ,以便继续提供服务。
哨兵就是用来监控主从服务器,实现故障恢复功能的。它会不断的检查主服务器和从服务器的健康状态,当某个服务器出现问题时,可以向管理员发起通知。如果主服务器不可用时,会自动选择一个从服务器作为新的主服务器,并让其他的从服务器从新的主服务器复制数据
哨兵也是主从模式,没有解决写的压力,只减轻了读的压力,而且存储也得不到扩容
20、Redis的cluster集群怎么存储数据的?
Redis Cluster集群采用哈希槽 (hash slot)的方式来分配的。它默认分配了16384个槽位,当我们set一个key 时,会用CRC16算法得到所属的槽位,然后将这个key 分到对应区间的节点上。
21、什么情况下Redis集群不可用?
Redis Cluster有一个容错机制,Redis 集群中的每个主节点会定期向其他主节点发送 PING 消息,其他节点会回复 PONG 消息, 如果半数以上的主节点与故障节点通信都超时了,就会认为该节点故障了。
自动触发故障转移操作,故障节点对应的健康的从节点升级为主节点。
但是如果某个主节点挂了,又没有从节点可以使用,那么整个Redis集群就不可用了。
22、Redis存储结构底层有没有了解?什么是SDS?
简单动态字符串,是Redis自己封装的字符串结构。它记录了字节数组buf,字节数组中用到的字节数len,以及未使用的字节数free。
-
为了解决二进制安全问题,定义了len来表示已有字符串长度
-
为了防止缓冲区溢出,在分配内存的时候做了预留空间free
-
内存惰性释放,多余的内存加入free做预留,优化了内存频繁分配
-
针对不同的String长度定制了不同的SDS结构
23、Redis如何模拟队列和栈,用什么命令?
list控制同一边进,同一边出就是栈;list控制一边进,另一边出就是队列
lpush、rpush、lpop、rpop
24、Redis存储单个对象怎么存,存储对象集合怎么存?
单个对象可以使用String,也可以使用hash
集合对象可以使用hash,以便可以快速的通过field来取值
25、你们Redis用来做什么?使用的什么结构?
登录信息login,使用的是String结构存储
手机验证码code,使用的是String结构
课程分类course_type ,使用的是String结构
购物车保存,使用的是Hash结构
26、统计全国高考前20名用什么?
ZREVRANGEBYSCORE high_scores +inf -inf LIMIT 0 20
27、从100个VIP用户中随机抽取5名怎么做?
Srandmember 集合的键名 要返回的元素数量
三、Rocket MQ
1、最新RocketMQ经典高频面试题大全(附答案)_rocketmq面试题,2024年最新2024最新Golang高频精选面试题讲解-CSDN博客
2、简述mq整体架构?
1)nameServer(邮局的管理机构)
管理Broker。NameServer是一个无状态节点,可集群部署,节点之间无任何信息同步。
2) Broker(邮局)
暂存和传输消息。Broker部署相对复杂,Broker分为Master(主 Broker)和Slave(从Broker),一个Master可以对应多个Slave,但是一个Slave只能对应 一个Master, Master 与Slave的对应关系通过指定相同的BrokerName,不同的Brokerld 来定义,Brokerld 为 0 表示为 Master ,非0表示Slave 。Master 也可以部署多个。 每个Broker 与NameServer集群中的所有节点建立长连接,定时注册Topic信息到所有NameServer。 注意:当前RocketMQ版本在部署架构上支持一Master多Slave,但只有Brokerld = 1的从服务器才会参与消息的读负载。
3)Topic(地区)
区分消息的种类。一个发送者可以发送消息给一个或多个Topic。一个消息的接受者可以订阅一个或者多个Topic消息。
4)Message Queue
相当于是Topic的分区。用于并行发送和接收消息。
5)Producer(寄件人)
消息发送者。如:发信者。Producer完全无状态,可集群部署
Producer与NameServer集群中的其中一个节点(随机选择)建立长连接,定期从NameServer获取Topic路由信息,并向提供Topic服务的Master建立长连接,且定时向Master发送心跳。
6) Consumer(收件人)
消息接收者。如:收信者。Consumer与NameServer集群中的其中一个节点(随机选择)建立长连接,定期从NameServer获取Topic 路由信息,并向提供Topic服务的Master、Slave建立长连接,且定时向Master、Slave 发送心跳。Consumer既可以从Master订阅消息,也可以从Slave订阅消息,消费者在向Master拉取消息时,Master 服务器会根据拉取偏移量与最大偏移量的距离(判断是否读老消息,产生读I/O) ,以及从服务器是否可读等因素建议下一次是从Master还是Slave拉取。
3、简述RocketMQ的执行流程?
1)启动NameServer, NameServer 启动后监听端口,等待Broker、 Producer、 Consumer 连上来,相当于一个路由控制中心。
2)Broker启动,跟所有的NameServer保持长连接,定时发送心跳包。心跳包中包含当前Broker 信息(IP+端口等)以及存储所有Topic信息。注册成功后,NameServer集群中就有Topic跟Broker的映射关系。
3)收发消息前,先创建Topic, 创建Topic时需要指定该Topic 要存储在哪些Broker 上,也可以在发送消息时自动创建Topic。
4)Producer发送消息,启动时先跟NameServer集群中的其中一台建立长连接,并从NameServer中获取当前发送的Topic存在哪些Broker上,轮询从队列列表中选择一个队列,然后与队列所在的Broker建立长连接从而向Broker发消息。
4、简述RocketMQ的特点?
1)具有灵活的可扩展性。 RocketMQ天然支持集群,其核心四大组件( NameServer、 Broker、Producer、Consumer)的每一个都可以在没有单点故障的情况下进行水平扩展。
2)具有海量消息堆积能力。RocketMQ 采用零拷贝原理实现了超大量消息的堆积能力。
3)支持顺序消息。RocketMQ可以保证消息消费者按照消息发送的顺序对消息进行消费。消息分为全局有序消息和局部有序消息,一般推荐使用局部有序消息,即生产者通过某一类消息顺序发送至同一队列中来实现。
4)支持多种消息过滤方式。消息过滤分为在服务器端过滤和在消费端过滤。在服务器端过滤时可以按照消息消费者的要求进行过滤,优点是减少了不必要的消息传输,缺点是增加了消息服务器的负担,实现相对复杂。消费端过滤则完全由具体应用自定义实现,这种方式更加灵活,缺点是很多无用的消息会被传输给消息消费者
5)支持事务消息。RocketMQ 除支持普通消息、顺序消息之外,还支持事务消息,这个特性对于分布式事务来说提供了另一种解决思路支持回溯消息。回溯消费是指对于消费者已经消费成功的消息,由于业务需求需要重新消费。RocketMQ支持按照实践回溯消费,时间维度精确到毫秒,可以向前回溯,可以向后回溯。
5、如何防止消息丢失和消息重复(难)?
四、ElasticSearch
1、Lucene创建索引原理?
Lucene是基于倒排索引原理来实现的
-
首先,将原文档进行分词处理,形成一个个单独的单词
-
然后取出标点符号以及停词,形成词元
-
再将词元做一些语言相关的处理,比如变成小写,转换时态,单复数形式等等
-
将得到的词创建一个字典,按照字母顺序排序,合并相同的词,最终生成一个倒排索引文档
2、ES的keyword和text区别?
keyword:不分词,直接建立索引,支持模糊查询,精确查询,聚合查询;通常用于存储年龄,性别,邮编,邮箱号码等等,直接将完整数据保存的场景
text:分词后建立索引,支持模糊查询,精确查询,不支持聚合查询;通常存储全文搜索的数据,例如地址,文章内容的保存
3、ES的优势?
ES是基于Lucene的开源搜索引擎,它解决了原生Lucene使用的不足,优化了Lucene的调用方式
-
分布式的实时文件存储,每个字段都被索引并可被搜索
-
支持实时分析搜索
-
可以扩展到上百台服务器,处理PB级结构化或非结构化数据
-
通过简单的 RESTful API、可以跟各种语言的客户端甚至命令行进行交互
-
上手非常容易,只需很少的学习就可以在生产环境中使用
4、Lucene/ES为什么那么快(ES用到什么数据结构)?
传统搜索比如mysql的like关键字查询,它的搜索方式就是全文扫表,查询性能很低
ES是基于Lucene的全文检索引擎,它采用的是倒排索引结构,在存储时先对文档进行分词,再做一些标点符号去除,大小写时态转换等优化处理,最后按照字母顺序去重排序,形成一个倒排索引文档,我们在检索时,就可以通过二分查找的方式找到目标值
5、ES的分层结构,index下面是什么?
Index:索引库,包含有一堆相似结构的文档数据,类比Mysql中的数据库
Type:类型,它是index中的一个逻辑数据分类,类比Mysql中的表
Document:文档:是ES中的最小数据单元,通常用json结构标识,类比Mysql中的一行数据
Field:字段:类比Mysql中的一个列
从ES7.0开始,Type被干掉了,从此库表合一即一个Index中只有一个默认的Type
6、讲几个ES中的查询对象:比如TermQuery?
TermQuery:匹配关键字查询(关键词不分词)
MatchQuery:匹配关键字查询(关键字分词后)
BooleanQuery:按条件查询
matchAllQuery:匹配所有文档查询
rangeQuery:查询指定范围内的数据
7、你简单描述一下DSL语法?
DSL是一种以json形式标识的,由ES提供的一种查询语言,它由两部分组成,DSL查询和DSL过滤。
DSL查询类似于模糊查询,DSL过滤类似于精确查询
Elasticsearch会自动缓存一些经常使用的过滤器(例如term
、range
查询)结果,以加快后续相同查询的响应速度。这个缓存机制是由Elasticsearch内部管理的,开发者不需要在DSL查询中显式配置。需要注意的是,Elasticsearch仅会缓存过滤器查询的结果,不会缓存全文搜索查询的结果。
8、你说一下 match和term的区别?
term:不会对搜索词进行分词处理,而是作为一个整体与目标字段进行匹配,若完全匹配,则可查询到
match:会将搜索词分词,再与目标查询字段进行匹配,若分词中的任意一个词与目标字段匹配上,则可查询到
9、你使用过ES的哪些聚合查询?
指标聚合,比如求和,求最大值,最小值,平均数
数量统计聚合,计算满足条件数据的总条数,相当于sql中的count
去重聚合,它会计算非重复的数据个数,相当于sql中的distinct
桶聚合,它会将某个field的每个唯一值当成一个桶,并计算每个桶内的文档个数,相当于sql中的group by
最高权值聚合,它会匹配每组前n条数据,相当于sql中的group by后取出前n条
10、ES高亮怎么做的?
使用HighlightBuilder对关键字作高亮处理,在字段的前后拼上html标签<em></em>
由于我们项目使用的是SpringBoot整合ES的jar包,结果没有进行高亮处理,我们使用ElasticsearchTemplate的queryForPage方法来获取结果,再手动进行分页封装返回前台
11、你们ES和数据库的数据一致性怎么做的?
代码控制的,数据库做了写操作后,直接更新ES中的数据,我知道可以通过同步工具 Logstash 从各种数据源(包括数据库)中收集数据中数据,进行处理后将其发送到ES进行数据自动同步。
其他方式: 如何保证es和数据库数据一致性?
12、ES分片机制了解吗?
在Elasticsearch中,索引的数据被划分为多个分片。每个分片都是一个Lucene索引。分片使得ES能够将数据分布在集群中的多个节点上,从而实现并行处理和高可用性。
ES的索引库由多个分片 shard组成,shard分为primary shard(主分片)和replica shard(副分片),主分片承担写请求,副分片的数据从主分片复制而来,同时分担读请求,主分片的数量设定了就不能修改,副分片数量可以修改。
13、描述一下ES添加文档的过程?
(1) 客户端请求一个协调节点coordinating node
当客户端发送请求添加文档时,请求会首先到达Elasticsearch集群中的一个协调节点。协调节点负责处理请求的路由和分发,但它本身不存储数据。
(2) 协调节点根据算法选择一个primary shard: 算法 hash(document_id) % (num_of_primary_shards)
(3) 对应的primary shard 所在节点保存完数据后,将数据同步到replica node。
主分片会负责索引文档,即将文档的数据更新到倒排索引中,以便后续的查询操作。
(4) 协调节点coordinating node 确认 primary node 和所有 replica node 都成功保存了数据并更新索引后返回结果给客户端
注:如果在任何步骤中发生错误,协调节点会负责处理错误,并可能会向客户端返回错误信息
14、数据节点存储数据详细流程?
(1) 当分片所在的节点接收到来自协调节点的请求后,会将请求写入到Memory Buffer(内存缓冲区),然后定时(默认是每隔1秒)写入到Filesystem Cache(文件系统缓存),这个从Momery Buffer到Filesystem Cache的过程就叫做refresh
(2) 当然在某些情况下,Momery Buffer和Filesystem Cache的数据可能会丢失,ES是通过translog的机制来保证数据的可靠性的。其实现机制是接收到请求后,同时也会写入到translog中,当Filesystem cache中的数据写入到磁盘中时,才会清除掉,这个过程叫做flush;
(3)在flush过程中:
内存中的缓冲将被清除,内容被写入一个新的Lucene段
段的fsync将创建一个新的提交点,并将内容刷新到磁盘
旧的translog将被删除并开始一个新的translog
flush触发的时机是定时触发(默认30分钟)或者translog变得太大(默认为512M)时;
15、详细描述一下Elasticsearch获取文档的过程?
(1) 客户端请求一个协调节点coordinating node
(2) coordinate node 根据算法hash(document_id) % (num_of_primary_shards),将请求转发到对应的 node,此时会使用 round-robin随机轮询算法,在 primary shard 以及其所有 replica 中随机选择一个,让读请求负载均衡
(3) 接收到请求的 node 返回 document 给协调节点 coordinate node。
(4) coordinate node 返回 document 给客户端。
搜索被执行成一个两阶段过程,我们称之为 Query Then Fetch;
16、详细描述一下Elasticsearch搜索过程?
1) 在初始查询阶段时,查询会广播到索引中每一个分片拷贝(主分片或者副本分片)。
2) 每个分片在本地执行搜索,并构建一个优先队列,该队列包含匹配文档的from + size
个文档。这里的 from
和 size
是查询请求中的参数,用于分页和限定返回结果的数量。PS:在搜索的时候是会查询Filesystem Cache的,但是有部分数据还在Memory Buffer,所以搜索是近实时的。
3) 每个分片返回各自优先队列中所有文档的 ID 和排序值给协调节点,协调节点它合并这些值到自己的优先队列中来产生一个全局排序后的结果列表。
4) 接下来就是取回阶段,协调节点辨别出哪些文档需要被取回并向相关的分片提交多个 GET 请求。每个分片加载并丰富文档(例如,添加高亮、聚合数据等),如果有需要的话,接着返回文档给协调节点。一旦所有的文档都被取回了,协调节点返回结果给客户端。
16、详细描述一下Elasticsearch更新和删除文档的过程?
删除和更新也都是写操作,但是Elasticsearch中的文档是不可变的,因此不能被删除或者改动以展示其变更; 磁盘上的每个段都有一个相应的.del文件。当删除请求发送后,文档并没有真的被删除,而是在.del文件中被标记为删除。该文档依然能匹配查询,但是会在结果中被过滤掉。当段合并时,在.del文件中被标记为删除的文档将不会被写入新段。
在新的文档被创建时,Elasticsearch会为该文档指定一个版本号,当执行更新时,旧版本的文档在.del文件中被标记为删除,新版本的文档被索引到一个新段。旧版本的文档依然能匹配查询,但是会在结果中被过滤掉。
17、ES有几种节点类型?他们的作用分别是什么?
分为主节点,node.master =true , 数据节点node.data =true , 负载均衡节点(node.data =false,node.master=false),
node.master=true,代表该节点有成为主节点 ,主节点的主要职责是和集群操作相关的内容,如创建或删除索引,跟踪哪些节点是群集的一部分,并决定哪些分片分配给相关的节点。一般会把主节点和数据节点分开
node.data=true,数据节点主要是存储索引数据的节点,主要对文档进行增删改查操作,聚合操作等,数据节点对CPU,IO,内存要求较高,优化节点的时候需要做状态监控,资源不够时要做节点扩充
当主节点和数据节点配置都设置为false的时候,该节点只能处理路由请求,处理搜索,分发索引操作等,从本质上来说该客户节点表现为智能负载平衡器。配置:mode.master=false,mode.data=false
18、ES集群的三种颜色代表什么?
绿色,黄色,红色,绿色代表集群健康,所有的主备分片都得到分配,如果有备分片没有node去分配,集群是黄色,黄色和绿色都是可用状态,如果有主分片的节点宕机,集群不可写数据,呈现红色,代表集群不健康。
19、你们项目怎么使用ES?
我们使用的是spring-boot-start-data-elasticsearch这个库来操作ES,用在大数据的搜索场景,比如商品的发布,搜索功能。
20、elasticsearch为什么要使用分片?
提高可处理的容量、易于进行水平扩展、提高集群的稳定性和提高并发量。