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机制 ,不会像一般的系统会调用系统函数处理,自然速度快。
5,Redis为什么是单线程的?单线程可以处理高并发吗?
Redis的瓶颈不是cpu的运行速度,而往往是网络带宽和机器的内存大小。再说了,单线程切换开销小,容易实现既然单线程容易实现,而且CPU不会成为瓶颈,那就顺理成章地采用单线程的方案了。
当然可以处理高并发,Redis不就实现了吗?
6,为什么Redis 6.0 之后改多线程呢?
上面说了Redis是单线程的,Redis6.0之前Redis都是单线程的,就是处理客户端的数据时,读写都由一个顺序串行的主线程处理。
redis使用多线程并非是完全摒弃单线程,redis还是使用单线程模型来处理客户端的请求,只是使用多线程来处理数据的读写和协议解析,执行命令还是使用单线程。
这样做的目的是因为redis的性能瓶颈在于网络IO而非CPU,使用多线程能提升IO读写的效率,从而整体提高redis的性能。
它的执行命令操作内存的仍然是个单线程。
7,Redis的五种类型有那些?
String 整数,浮点数或者字符串,使⽤场景:缓存、计数器、共享 Session、限速。
Set 集合,通常用在兴趣标签之类的。
Zset 有序集合,通常用在排行榜之类的。
Hash 散列表,哈希结构相对于字符串序列化缓存信息更加直观,并且在更新操作上更加便捷。哈希结构相对于字符串序列化缓存信息更加直观,并且在更新操作上更加便捷。
List 列表,在 Redis 中,可以队列表两端插⼊和弹出,还可以获取指定范围的元素列表、获取指定索引下的元素等,列表是⼀种⽐较灵活的数据结构,它可以充当栈和队列的⻆⾊。
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. ⽀持消息队列
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中查询,查询不到后去数据库中查询。
缓存穿透的如何避免:
- 缓存空对象:如果⼀个查询返回的数据为空(不管是数据不存在,还是系统故障),我们仍然把这个空结果进⾏缓存,但它的过期时间会很短,最⻓不超过五分钟。
- 接口层增加校验,对传参进行个校验,比如说我们的id是从1开始的,那么id<=0的直接拦截;
- 缓存中取不到的数据,在数据库中也没有取到,这时可以将key-value对写为key-null,这样可以防止攻击用户反复用同一个id暴力攻击
- 缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生。
- 如果缓存数据库是分布式部署,将热点数据均匀分布在不同搞得缓存数据库中。
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等持久化机制。通常运用在如下场景:
15,如何实现Redis的高可用?
一般有三种模式,分别为主从模式(Replication-Sentinel模式)、哨兵模式、集群模式。
主从模式:
主从模式是部署多台服务器,有主节点和从节点,主节点负责读写,从节点负责读。
首先是master和slave的连接,然后会将自身的数据复制给slave。
如果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
哨兵模式的架构图如下所示:
集群模式:
Redis 集群是一个提供在多个Redis节点间共享数据的程序集,对数据进行分片,也就是说每台Redis节点上存储不同的内容,来解决在线扩容的问题。哨兵模式基于主从模式,实现读写分离,它还可以自动切换,系统可用性更高。但是它每个节点存储的数据是一样的,浪费内存,并且不好在线扩容。
,
Redis Cluster有一个槽的概念,所有的键根据哈希函数映射到 0~16383 个整数槽内,每个节点负责维护一部分槽以及槽所映射的键值数据,可以直接自动跳转到这个对应的节点上进行存取操作。
槽位的信息存储于每个节点中。只有master节点会被分配槽位,slave节点不会分配槽位。