Java基础到就业!项目加面试!之Redis面试大全!

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: 简单来说 redis 就是一个数据库,不过与传统数据库不同的是 redis 的数据是存在内存中的,所以存写速度非常快,因此 redis 被广泛应用于缓存方向。

1,什么是Redis


简单来说 redis 就是一个数据库,不过与传统数据库不同的是 redis 的数据是存在内存中的,所以存写速度非常快,因此 redis 被广泛应用于缓存方向。


另外,redis 也经常用来做分布式锁。redis 提供了多种数据类型来支持不同的业务场景。除此之外,redis 支持事务 、持久化、LUA脚本、LRU驱动事件、多种集群方案。


最主要的Redis就是缓存应用!


2,Redis和Memecache有什么区别?


对于 redis 和 Memecache的区别有下面四点。


a.redis支持更丰富的数据类型(支持更复杂的应用场景):Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,zset,hash等数据结构的存储。memcache支持简单的数据类型,String。


b.Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用,而Memecache把数据全部存在内存之中。


c.集群模式:memcached没有原生的集群模式,需要依靠客户端来实现往集群中分片写入数据;但是 redis 目前是原生支持 cluster 模式的。


d.Memcached是多线程,非阻塞IO复用的网络模型;Redis使用单线程的多路 IO 复用模型。


3,Redis和Mysql的区别:


redis: 内存型非关系数据库,数据保存在内存中,速度快


mysql:关系型数据库,数据保存在磁盘中,检索的话,会有一定的Io操作,访问速度相对慢


4,为什么要用reids,不用不行吗?


主要从“高性能”和“高并发”这两点来看待这个问题。在这两种情况下Redis非常的快。


首先看一下高性能:


假如用户第一次访问数据库中的某些数据。这个过程会比较慢,因为是从硬盘上读取的。将该用户访问的数据存在数缓存中,这样下一次再访问这些数据的时候就可以直接从缓存中获取了。操作缓存就是直接操作内存,所以速度相当快。如果数据库中的对应数据改变的之后,同步改变缓存中相应的数据即可!


最重要的就是在高并发的时候,Redis非常的快。


直接操作缓存能够承受的请求是远远大于直接访问数据库的,所以我们可以考虑把数据库中的部分数据转移到缓存中去,这样用户的一部分请求会直接到缓存这里而不用经过数据库。


那么Redis为啥这么快呢?听小孟道来。


如果简单的解释就是:


首先,采用了多路复用io阻塞机制然后,数据结构简单,操作节省时间。并且,Redis自身的事件处理模型将epoll中的连接、读写、关闭都转换为事件,不在网络I/O上浪费过多的时间。最后,运行在内存中,Redis直接自己构建了VM机制 ,不会像一般的系统会调用系统函数处理,自然速度快。


微信图片_20221009201116.png


5,Redis为什么是单线程的?单线程可以处理高并发吗?


Redis的瓶颈不是cpu的运行速度,而往往是网络带宽和机器的内存大小。再说了,单线程切换开销小,容易实现既然单线程容易实现,而且CPU不会成为瓶颈,那就顺理成章地采用单线程的方案了。


当然可以处理高并发,Redis不就实现了吗?


6,为什么Redis 6.0 之后改多线程呢?


上面说了Redis是单线程的,Redis6.0之前Redis都是单线程的,就是处理客户端的数据时,读写都由一个顺序串行的主线程处理。


redis使用多线程并非是完全摒弃单线程,redis还是使用单线程模型来处理客户端的请求,只是使用多线程来处理数据的读写和协议解析,执行命令还是使用单线程。


这样做的目的是因为redis的性能瓶颈在于网络IO而非CPU,使用多线程能提升IO读写的效率,从而整体提高redis的性能。


它的执行命令操作内存的仍然是个单线程。


微信图片_20221009201121.png



7,Redis的五种类型有那些?


String 整数,浮点数或者字符串,使⽤场景:缓存、计数器、共享 Session、限速。


Set 集合,通常用在兴趣标签之类的。


Zset 有序集合,通常用在排行榜之类的。


Hash 散列表,哈希结构相对于字符串序列化缓存信息更加直观,并且在更新操作上更加便捷。哈希结构相对于字符串序列化缓存信息更加直观,并且在更新操作上更加便捷。


List 列表,在 Redis 中,可以队列表两端插⼊和弹出,还可以获取指定范围的元素列表、获取指定索引下的元素等,列表是⼀种⽐较灵活的数据结构,它可以充当栈和队列的⻆⾊。


微信图片_20221009201124.png


Set用的比较多,redis的端口号通常是6379:


127.0.0.1:6379> set key1 xiaomeng1
OK
127.0.0.1:6379> set key2 xiaomeng2
OK
127.0.0.1:6379> set key3 xiaomeng3
OK
127.0.0.1:6379> set key4 xiaomeng4
OK
127.0.0.1:6379> set key5 xiaomeng5
OK
127.0.0.1:6379> set key6 xiaomeng6
OK


除此之外,还有三种特殊的数据类型:


Geo:Redis3.2推出的,地理位置定位,用于存储地理位置信息,并对存储的信息进行操作。


HyperLogLog:用来做基数统计算法的数据结构。


Bitmaps :用一个比特位来映射某个元素的状态,在Redis中,它的底层是基于字符串类型实现的,可以把bitmaps成作一个以比特位为单位的数组。


8,Redis常见的功能有哪些?


1. 数据缓存功能


2. 分布式锁的功能


3. ⽀持数据持久化


4. ⽀持事务


5. ⽀持消息队列


微信图片_20221009201129.png


9,Redis的优缺点有哪些


优点:


上面已经了列举了Redis的很多优点:


1,读写非常的快,提高网站的访问速度,Redis能读的速度是110000次/s,写的速度是81000次/s。强悍的一比。


2,持AOF和RDB两种持久化方式。


3,支持较多的数据结构类型,有String、hash、set、zset等等。


4,支持主从复制,主机可以自动的将数据同步到从机,从而进行读写分离。


5,支持AOF和RDB的持久化方式。


缺点:


任何的事物有优点,必然有缺点。Redis也不例外。


Redis 不具备自动容错和恢复功能,主机从机的宕机都会导致前端部分读写请求失败,需要等待机器重启或者手动切换前端的IP才能恢复。


Redis 较难支持在线扩容,在集群容量达到上限时在线扩容会变得很复杂。为避免这一问题,运维人员在系统上线时必须确保有足够的空间,这对资源造成了很大的浪费。


10,说说缓存穿透,缓存雪崩以及缓存击穿?


A,缓存穿透:缓存穿透是指查询一条数据库和缓存都没有的一条数据,就会一直查询数据库,对数据 库的访问压力就会增大,缓存穿透的解决方案,再换个说法就是客户持续向服务器发起对不存在服务器中数据的请求。客户先在Redis中查询,查询不到后去数据库中查询。


缓存穿透的如何避免:


  1. 缓存空对象:如果⼀个查询返回的数据为空(不管是数据不存在,还是系统故障),我们仍然把这个空结果进⾏缓存,但它的过期时间会很短,最⻓不超过五分钟。
  2. 接口层增加校验,对传参进行个校验,比如说我们的id是从1开始的,那么id<=0的直接拦截;
  3. 缓存中取不到的数据,在数据库中也没有取到,这时可以将key-value对写为key-null,这样可以防止攻击用户反复用同一个id暴力攻击
  4. 缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生。
  5. 如果缓存数据库是分布式部署,将热点数据均匀分布在不同搞得缓存数据库中。


B,缓存击穿:就是一个很热门的数据,突然失效,而此时大量请求到服务器数据库中。


最好的办法就是设置热点数据永不过期。热点数据快要过期时,异步线程去更新和设置过期时间。


此外还可以采用互斥锁方案。


C,缓存雪崩:概念上是大量数据同一时间失效。此刻无数的请求直接绕开缓存,直 接请求数据库。


造成缓存雪崩的原因,有以下2种: reids宕机,可以通过构造redis集群解决! 大部分数据失效。可通过均匀设置过期时间解决,即让过期时间相对离散一点。


11,说一下Redis的持久化机制。


Redis的持久化机制有RDB和AOF。


RDB把内存数据以快照的形式保存到磁盘上。其核心的配置:


save <seconds> <changes>
# save ""
save 900 1
save 300 10
save 60 10000

可以进行备份和全量复制,但是无法做到实时的持久化。适合大规模的数据恢复。


RDB做不到实时的持久化,但AOF可以。采用日志的形式来记录每个写操作,追加到文件中,通过重启执行AOF来恢复数据。


Redis默认是把AOF关闭的,我们可以把它打开。no改为yes


appendonly yes


AOF数据的完整性和一致性更高,


但是,因为AOF记录的内容多,文件会越来越大,数据恢复也会越来越慢。


基于以上分析,若只打算用Redis 做缓存,可以关闭持久化。


若打算使用Redis 的持久化。建议RDB和AOF都开启。其实RDB更适合做数据的备份,留一后手。AOF出问题了,还有RDB。所以还是要根据不同的需求,去做不同的操作。


12,MySQL 里有 1000w 数据,redis 中只存 10w 的数据,如何保证 redis 中的数据都 是热点数据?


redis 内存数据集大小上升到一定大小的时候,就会施行数据淘汰策略。其实面试除了考察 Redis,大厂对于底层、分布式、微服务考察很多!


13,说下Redis的淘汰策略?


Redis的淘汰策略有8种,分别为:noeviction,volatile-lru,volatile-lfu,volatile-ttl,volatile-random,allkeylru,allkeys-lfu,allkeys-random


14,请讲一下Redis的应用场景?


我们都知道Redis最主要的就是缓存,在网站中应用最广泛,可以很明显的提高访问的速度,减少数据库的压力!和memcached相比,redis更加的强悍,因为提供了丰富的数据结构,还提供了RDB和AOF等持久化机制。通常运用在如下场景:


微信图片_20221009201140.png


15,如何实现Redis的高可用?


一般有三种模式,分别为主从模式(Replication-Sentinel模式)、哨兵模式、集群模式。


微信图片_20221009201145.png


主从模式:


主从模式是部署多台服务器,有主节点和从节点,主节点负责读写,从节点负责读。


首先是master和slave的连接,然后会将自身的数据复制给slave。


微信图片_20221009201149.png

如果maser和slave断开连接后重新连接,只获取在断开连接期间内丢失的命令流。


如果无法同步,slave 会请求进行全量重同步。


Redis Sentinel(哨兵):


哨兵是社区版本推出的原生高可用解决方案,为什么要提供哨兵?


在主从模式中,主节点发什么问题时,需要人工的将从节点搞成主节点,非常的费事,而且通知应用方更新主节点的地址,更加的费事。哨兵就可以解决这个问题。


哨兵模式的搭建:


#配置端口
port 26379
#以守护进程模式启动
daemonize yes
#日志文件名
logfile "sentinel_26379.log"
#存放备份文件以及日志等文件的目录
dir "/opt/redis/data"
#监控的IP 端口号 名称 sentinel通过投票后认为mater宕机的数量,此处为至少2个
sentinel monitor mymaster 192.168.14.101 6379 2
#30秒ping不通主节点的信息,主观认为master宕机
sentinel down-after-milliseconds mymaster 30000
#故障转移后重新主从复制,1表示串行,>1并行
sentinel parallel-syncs mymaster 1
#故障转移开始,三分钟内没有完成,则认为转移失败
sentinel failover-timeout mymaster 180000

哨兵模式的架构图如下所示:


微信图片_20221009201154.png


集群模式:


Redis 集群是一个提供在多个Redis节点间共享数据的程序集,对数据进行分片,也就是说每台Redis节点上存储不同的内容,来解决在线扩容的问题。哨兵模式基于主从模式,实现读写分离,它还可以自动切换,系统可用性更高。但是它每个节点存储的数据是一样的,浪费内存,并且不好在线扩容。


微信图片_20221009201159.png,


Redis Cluster有一个槽的概念,所有的键根据哈希函数映射到 0~16383 个整数槽内,每个节点负责维护一部分槽以及槽所映射的键值数据,可以直接自动跳转到这个对应的节点上进行存取操作。


槽位的信息存储于每个节点中。只有master节点会被分配槽位,slave节点不会分配槽位。

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
4天前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
16 2
|
7天前
|
缓存 NoSQL 关系型数据库
大厂面试高频:如何解决Redis缓存雪崩、缓存穿透、缓存并发等5大难题
本文详解缓存雪崩、缓存穿透、缓存并发及缓存预热等问题,提供高可用解决方案,帮助你在大厂面试和实际工作中应对这些常见并发场景。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:如何解决Redis缓存雪崩、缓存穿透、缓存并发等5大难题
|
9天前
|
存储 算法 Java
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
本文详解自旋锁的概念、优缺点、使用场景及Java实现。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
|
15天前
|
存储 缓存 Oracle
Java I/O流面试之道
NIO的出现在于提高IO的速度,它相比传统的输入/输出流速度更快。NIO通过管道Channel和缓冲器Buffer来处理数据,可以把管道当成一个矿藏,缓冲器就是矿藏里的卡车。程序通过管道里的缓冲器进行数据交互,而不直接处理数据。程序要么从缓冲器获取数据,要么输入数据到缓冲器。
Java I/O流面试之道
|
11天前
|
存储 缓存 Java
大厂面试必看!Java基本数据类型和包装类的那些坑
本文介绍了Java中的基本数据类型和包装类,包括整数类型、浮点数类型、字符类型和布尔类型。详细讲解了每种类型的特性和应用场景,并探讨了包装类的引入原因、装箱与拆箱机制以及缓存机制。最后总结了面试中常见的相关考点,帮助读者更好地理解和应对面试中的问题。
35 4
|
9天前
|
存储 消息中间件 NoSQL
使用Java操作Redis数据类型的详解指南
通过使用Jedis库,可以在Java中方便地操作Redis的各种数据类型。本文详细介绍了字符串、哈希、列表、集合和有序集合的基本操作及其对应的Java实现。这些示例展示了如何使用Java与Redis进行交互,为开发高效的Redis客户端应用程序提供了基础。希望本文的指南能帮助您更好地理解和使用Redis,提升应用程序的性能和可靠性。
23 1
|
12天前
|
存储 Java 程序员
Java基础的灵魂——Object类方法详解(社招面试不踩坑)
本文介绍了Java中`Object`类的几个重要方法,包括`toString`、`equals`、`hashCode`、`finalize`、`clone`、`getClass`、`notify`和`wait`。这些方法是面试中的常考点,掌握它们有助于理解Java对象的行为和实现多线程编程。作者通过具体示例和应用场景,详细解析了每个方法的作用和重写技巧,帮助读者更好地应对面试和技术开发。
51 4
|
24天前
|
存储 Java 程序员
Java面试加分点!一文读懂HashMap底层实现与扩容机制
本文详细解析了Java中经典的HashMap数据结构,包括其底层实现、扩容机制、put和查找过程、哈希函数以及JDK 1.7与1.8的差异。通过数组、链表和红黑树的组合,HashMap实现了高效的键值对存储与检索。文章还介绍了HashMap在不同版本中的优化,帮助读者更好地理解和应用这一重要工具。
51 5
|
23天前
|
存储 Java
[Java]面试官:你对异常处理了解多少,例如,finally中可以有return吗?
本文介绍了Java中`try...catch...finally`语句的使用细节及返回值问题,并探讨了JDK1.7引入的`try...with...resources`新特性,强调了异常处理机制及资源自动关闭的优势。
18 1
|
1月前
|
Java 程序员
Java 面试高频考点:static 和 final 深度剖析
本文介绍了 Java 中的 `static` 和 `final` 关键字。`static` 修饰的属性和方法属于类而非对象,所有实例共享;`final` 用于变量、方法和类,确保其不可修改或继承。两者结合可用于定义常量。文章通过具体示例详细解析了它们的用法和应用场景。
28 3