一天五道Java面试题----第十天(简述Redis事务实现--------->负载均衡算法、类型)

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
传统型负载均衡 CLB,每月750个小时 15LCU
简介: 这篇文章是关于Java面试中Redis相关问题的笔记,包括Redis事务实现、集群方案、主从复制原理、CAP和BASE理论以及负载均衡算法和类型。

这里是参考B站上的大佬做的面试题笔记。大家也可以去看视频讲解!!!

文章目录

  • 1、简述Redis事务实现
  • 2、redis集群方案
  • 3、redis主从复制的核心原理
  • 4、CAP理论,BASE理论
  • 5、负载均衡算法、类型

1、简述Redis事务实现

1、事务开始

MULTI命令的执行,标识着一个事务的开始。MULTI命令会将客户端状态的flag属性中打开REDIS_MULTI标识来完成的。

2、命令入队

当一个客户端切换到事务状态后,服务器会根据这个客户端发送来的命令来执行不同的操作。如果客户端发送的命令为MULTI、EXEC、WATCH、DISCARD中的一个,立即执行这个命令,否则将命令放入一个事务队列里面,然后向客户端返回QUEUED回复。

  • 如果客户端发送的命令为EXEC、DISCARD、WATCH、MULTI四个命令的其中一个,那么服务器立即执行这个命令。
  • 如果客户端发送的是四个命令以外的其他命令,那么服务器并不立即执行这个命令。
  • 首先检查命令的格式是否正确、如果不正确,服务器会在客户端状态(redisClient)的flags属性关闭REDIS_MULTI标识,并且返回错误信息给客户端。如果正确,将这个命令放入一个事务队列里面,然后向客户端返回QUEUED回复

事务队列是按照FIFO的方式保存入队的命令。

3、事务执行

客户端发送EXEC命令,服务器执行EXEC命令逻辑

  • 如果客户端状态的flags属性不包含REDIS_MULTI标识,或者包含REDIS_DIRTY_CAS或者REDIS_DIRTY_EXEC标识,那么就直接取消事务的执行。
  • 否则客户端处于事务状态(flags有REDIS_MULTI标识),服务器会遍历客户端的事务队列,然后执行事务队列中的所有的命令,最后将返回结果全部返回给客户端;

redis不支持事务回滚机制,但是它会检查每一个事务中的命令是否错误。

Redis事务不支持检查哪些程序员自己的逻辑错误。例如对String类型的数据库执行对HashMap类型的操作!!!

  • WATCH命令是一个乐观锁,可以为Redis事务提供check-and-set(CAS)行为,可以监控一个或多个键,一旦其中有一个键被修改(或删除),之后的事务就不会执行,监控一直持续到EXEC命令。
  • MULTI命令有用于开启一个事务,它总是返回OK,MULTI执行之后,客户端可以继续向服务器发送任意多条命令,这些命令不会立即被执行,而是被放到一个队列中,当EXEC命令被调用时,所有队列中的命令才会被执行。
  • EXEC:执行所有事务块内的命令。返回事务块内所有命令的返回值,按命令执行的先后顺序排列。当操作被打断时,返回空值NULL。
  • 通过调用DISCARD,客户端可以清空事务队列,并放弃执行事务,并且客户端会从事务状态中退出。
  • UNWATCH命令可以取消watch对所有key的监控。

2、redis集群方案

主从

哨兵模式:
sentinel,哨兵是redis集群中非常重要的一个组件,主要有一下功能:

  • 集群监控:负责监控redis master 和slave进程是否正常工作。
  • 信息通知:如果某个redis实例有故障,那么哨兵负责发送信息作为报警通知给管理员
  • 故障转移:如果master node挂掉了,会自动转移到slave node上。
  • 配置中心:如果故障转移发生了,通知client客户端新的master地址

哨兵用于实现redis集群的高可用,本身也是分布式的,作为一个哨兵集群去运行,互相协同工作。

  • 故障转移时,判断一个master node是否宕机了,需要大部分的哨兵都同意才行,涉及到了分布式选举
  • 即使部分哨兵节点挂掉了,哨兵集群还是能正常工作的
  • 哨兵通常需要3个实例,来保证自己的健壮性。
  • 哨兵+redis主从的部署架构,是不保证数据零丢失的,只能保证redis集群的高可用性。
  • 对于哨兵+redis主从这种复杂的部署架构,尽量在测试环境和生产环境,都进行充足的测试和演练。

redis Cluster 是一种服务端Sharding技术,3.0版本开始正式提供。采用==slot(槽)==的概念,一共分成16384个槽。将请求发送到任意节点,接收到请求的节点会将查询请求发送到正确的节点上执行

方案说明:

  • 通过哈希的方式,将数据分片,每个节点均分存储一定哈希槽(哈希值)区间的数据,默认分配 了16384个槽位
  • 每份数据分片会存储在多个互为主从的节点上
  • 数据写入先写主节点,再同步到从节点(支持配置为阻塞同步)
  • 同一分片多个节点间的数据不保持一致性
  • 读取数据时,当客户端操作的key没有分配在该节点上时,redis会返回转向指令,指向正确的节点
  • 扩容时需要把旧节点的数据迁移一部分到新节点

在redis cluster架构下,每个redis要开放两个端口号,比如一个是6379,另外一个就是加1w的端口号,比如16379.

16379端口号是用来进行节点间通信的,也就是cluster bus的通信,用来进行故障检测、配置更新、故障转移授权。cluster bus用了另外一种二进制的协议,gossip协议,用于节点间进行高效的数据交换,占用更少的网络带宽和处理时间。

优点:

  • 无中心架构,支持动态扩容,对业务透明
  • 具备Sentine的监控和自动Failover(故障转移)能力
  • 客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可
  • 高性能,客户端直连redis服务,免去了proxy代理的损耗

缺点:

  • 运维也很复杂、数据迁移需要人工干预
  • 只能使用0号数据库
  • 不支持批量操作(pipeline管道操作)
  • 分布式逻辑和存储模块耦合等

Redis Sharding是Redis Cluster出来之前,业界普遍使用的多Redis实例集群方法。其主要思想是采用哈希算法将Redis数据的Key进行散列,通过hash函数,特定的key会映射到特定的Redis节点上。java redis客户端驱动jedis,支持Redis Sharing功能,即ShardedJedis以及结合缓存池的ShardegjedisPool

优点:

优势在于非常简单,服务端的redis实例彼此独立,相互无关联,每个Redis实例像单服务器一样运行,非常容易线性扩展,系统的灵活性很强。

缺点:
由于sharding处理放到客户端,规模进一步扩大时给运维带来挑战。
客户端sharding不支持动态增删改节点。服务端redis实例群拓扑结构有变化时,每个客户端都需要更新调整。连接不能共享,当应用规模增大时,资源浪费制约优化

3、redis主从复制的核心原理

通过执行slaveof命令或设置slaveof选项,让一个服务器去复制另一个服务器的数据。主数据库可以进行读写操作,当写操作导致数据变化时会自动将数据同步给从数据库。而从数据库一般只是只读的,并接受主数据库同步过来的数据。一个主数据库可以拥有多个从数据库,而一个从数据库只能拥有一个主数据库。

全量复制:

  • 1、主节点通过bgsave命令fork子进程进行RDB持久化,该过程是非常消耗CPU、内存(页表复制)、硬盘IO的
  • 2、主节点通过网络将RDB文件发送给从节点,对主节点的带宽都会带来很大的消耗
  • 3、从节点清空老数据,载入新RDB文件的过程是阻塞的,无法响应客户端的命令;如果从节点执行bgrewriteaof,也会带来额外的消耗

部分复制:

  • 1、复制偏移量:执行复制的双方,主从节点,分别会维护一个复制偏移量offset
  • 2、复制积压缓冲区:主节点内部维护了一个固定长度的、先进先出(FIFO)队列作为复制积压缓冲区,当主从节点offset的差距过大超过缓冲区长度时,将无法执行部分复制,只能执行全量复制。
  • 3、服务器运行ID(runid):每个Redis节点,都有其运行ID,运行ID由节点在启动时自动生成,主节点会将自己的运行ID发送给从节点,从节点会将主节点的运行ID存起来。从节点Redis断开重连的时候,就是根据运行ID来判断同步的进度:

如果从节点保存的runid与主节点现在的runid相同,说明主从节点之前同步过,主节点会继续尝试使用部分复制(到底能不能部分复制还要看offset和复制积压缓冲区的情况)

如果从节点保存的runid与主节点现在的runid不同,说明从节点在断线前同步的Redis节点并不是当前的主节点,只能进行全量复制。

在这里插入图片描述

4、CAP理论,BASE理论

CAP理论

Consistency(一致性)

  • 即更新操作成功并返回客户端后,所有节点在同一时间的数据完全一致。
  • 对于客户端来说,一致性指的是并发访问时更新过的数据如何获取的问题。
  • 从服务端来看,则是更新如何复制分布到整个系统,以保证数据最终一致。

Availability(可用性)

  • 即服务一直可用,而且是正常响应时间。系统能够很好的为用户服务,不出现用户操作失败或者访问超时等用户体验不好的情况

Partition Tolerance(分区容错性):

  • 即分布式系统在遇到某节点或网络分区故障的时候,仍然能够对外提供满足一致性和可用性的服务。分区容错性要求能够使应用虽然是一个分布式系统,而看上去却好像是在一个可以运转正常的整体。比如现在的分布式系统中由某一个或几个机器宕机了,其他剩下的机器还能够正常运转满足系统需求,对于用户而言并没有什么体验上的影响。

CP和AP:分区容错是必须保证的,当发生网络分区的时候,如果要继续服务,那么强一致性和可用性只能2选1.

BASE是Basically Available(基本可用)、soft state(软状态)和Eventually consisten(最终一致性)

BASE理论是对CPA中一致性和可用性权衡的结果,其来源于对大规模互联网系统分布式实践的总结,是基于CAP定理逐步演化而来的。BASE理论的核心思想是:即使无法做到强一致性,但每个应用都可以根据自身业务特定,采用适当的方式来使系统达到最终一致性

基本可用:

  • 响应时间上的损失:正常情况下,处理用户请求需要0.5s返回结果,但是由于系统出现故障,处理用户请求的时间变为3s
  • 系统功能上的损失:正常情况下,用户可以使用系统的全部功能,但是由于系统访问量突然剧增,系统的部分非核心功能无法使用。

软状态:数据同步允许一定的延迟

最终一致性:系统中所有的数据副本,在经过一段时间的同步后,最终能够达到一个一致的状态,不要求实时

5、负载均衡算法、类型

1、轮循法

  • 将请求按顺序轮流分配到后端服务器上,它均衡地对待后端的每一台服务器,而不关心服务器实际的连接数和当前的系统负载

2、随机法

  • 通过系统的随机算法、根据后端服务器的列表大小值来随机选取其中的一台服务器访问。由概率统计理论可以得知,随着客户端调用服务端的次数增多,其实际效果越来越接近于平均分配调用量到后端的每一台服务器,也就是轮循的结果

3、源地址哈希法

  • 源地址哈希的思想是根据获取客户端的IP地址,通过哈希函数计算得到的一个数值,用该数值对服务器列表的大小进行取模运算,得到的结果便是客户端要访问服务器的序号。采用源地址哈希法进行负载均衡,同一IP地址的客户端,当 后端服务器列表不变时,它每次都会映射到同一台后端服务器进行访问。

4、加权轮询法

  • 不同的后端服务器可能机器的配置和当前系统的负载并不相同,因此它们的抗压能力也不相同。给配置高、负载低的机器配置更高的权重,让其处理更多的请求;而配置低、负载高的机器,给其分配较低的权重,降低其系统负载,加权轮循能很好地处理这一问题,并将请求顺序且按照权重分配到后端。

5、加权随机法

  • 与加权轮询法一样,加权随机法也可根据后端机器的配置,系统的负载分配不同的权重。不同的是,它是按照权重随机请求后端服务器,而非顺序

6、随机连接数法

  • 最小连接数算法比较灵活和智能,由于后端服务器的配置不尽相同,对于请求的处理有快有慢,它是根据后端服务器当前的连接情况,动态地选取其中当前积压连接数最少的一台服务器来处理当前的请求,尽可能地提高后端服务的利用效率,将负责合理地分流到每一台服务器。

类型:
DNS方式实现负载均衡

硬件负载均衡:F5和A10

软件负载均衡:
Nginx、HAproxy、Lvs。其中的区别:

  • Nginx:七层负载均衡,支持HTTP、E-mail协议,同时也支持4层负载均衡;
  • HAproxy:支持七层规则的,性能也很不粗。OpenStack默认使用的负载均衡软件就是HPproxy
  • LVS:运行在内核态,性能是软件负载均衡中最高的,严格来说工作在三次(传输层),所以更通用一些,适用各种应用服务。
相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
3天前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
14 2
|
6天前
|
缓存 NoSQL 关系型数据库
大厂面试高频:如何解决Redis缓存雪崩、缓存穿透、缓存并发等5大难题
本文详解缓存雪崩、缓存穿透、缓存并发及缓存预热等问题,提供高可用解决方案,帮助你在大厂面试和实际工作中应对这些常见并发场景。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:如何解决Redis缓存雪崩、缓存穿透、缓存并发等5大难题
|
7天前
|
存储 算法 Java
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
本文详解自旋锁的概念、优缺点、使用场景及Java实现。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
|
13天前
|
存储 缓存 Oracle
Java I/O流面试之道
NIO的出现在于提高IO的速度,它相比传统的输入/输出流速度更快。NIO通过管道Channel和缓冲器Buffer来处理数据,可以把管道当成一个矿藏,缓冲器就是矿藏里的卡车。程序通过管道里的缓冲器进行数据交互,而不直接处理数据。程序要么从缓冲器获取数据,要么输入数据到缓冲器。
Java I/O流面试之道
|
9天前
|
存储 缓存 Java
大厂面试必看!Java基本数据类型和包装类的那些坑
本文介绍了Java中的基本数据类型和包装类,包括整数类型、浮点数类型、字符类型和布尔类型。详细讲解了每种类型的特性和应用场景,并探讨了包装类的引入原因、装箱与拆箱机制以及缓存机制。最后总结了面试中常见的相关考点,帮助读者更好地理解和应对面试中的问题。
33 4
|
7天前
|
存储 消息中间件 NoSQL
使用Java操作Redis数据类型的详解指南
通过使用Jedis库,可以在Java中方便地操作Redis的各种数据类型。本文详细介绍了字符串、哈希、列表、集合和有序集合的基本操作及其对应的Java实现。这些示例展示了如何使用Java与Redis进行交互,为开发高效的Redis客户端应用程序提供了基础。希望本文的指南能帮助您更好地理解和使用Redis,提升应用程序的性能和可靠性。
21 1
|
10天前
|
存储 Java 程序员
Java基础的灵魂——Object类方法详解(社招面试不踩坑)
本文介绍了Java中`Object`类的几个重要方法,包括`toString`、`equals`、`hashCode`、`finalize`、`clone`、`getClass`、`notify`和`wait`。这些方法是面试中的常考点,掌握它们有助于理解Java对象的行为和实现多线程编程。作者通过具体示例和应用场景,详细解析了每个方法的作用和重写技巧,帮助读者更好地应对面试和技术开发。
49 4
|
18天前
|
存储 消息中间件 NoSQL
Redis数据结构:List类型全面解析
Redis数据结构——List类型全面解析:存储多个有序的字符串,列表中每个字符串成为元素 Eelement,最多可以存储 2^32-1 个元素。可对列表两端插入(push)和弹出(pop)、获取指定范围的元素列表等,常见命令。 底层数据结构:3.2版本之前,底层采用**压缩链表ZipList**和**双向链表LinkedList**;3.2版本之后,底层数据结构为**快速链表QuickList** 列表是一种比较灵活的数据结构,可以充当栈、队列、阻塞队列,在实际开发中有很多应用场景。
|
21天前
|
存储 Java
[Java]面试官:你对异常处理了解多少,例如,finally中可以有return吗?
本文介绍了Java中`try...catch...finally`语句的使用细节及返回值问题,并探讨了JDK1.7引入的`try...with...resources`新特性,强调了异常处理机制及资源自动关闭的优势。
18 1
|
18天前
|
存储 NoSQL 关系型数据库
Redis的ZSet底层数据结构,ZSet类型全面解析
Redis的ZSet底层数据结构,ZSet类型全面解析;应用场景、底层结构、常用命令;压缩列表ZipList、跳表SkipList;B+树与跳表对比,MySQL为什么使用B+树;ZSet为什么用跳表,而不是B+树、红黑树、二叉树