栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【Python 八股文】- Redis基础

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【Python 八股文】- Redis基础

文章目录

1. Redis应用场景有哪些?2. Redis怎么实现消息队列?3. Memcached和Redis的区别?4. Redis 数据类型有哪些?5. Redis持久化机制6. 持久化机制的区别?7. 过期键的删除策略8. Redis的内存淘汰机制是什么样的?9. 缓存雪崩10. 缓存击穿11. 缓存穿透12. Redis的主从复制模式13. Redis哨兵模式14. 限流算法15. Redis分布式锁?16. Redis优点17. Redis缺点18. Redis为什么这么快?19. Redis为何选择单线程20. keys命令存在的问题?21. SortedSet和List异同点?


1. Redis应用场景有哪些?

缓存热点数据,缓解数据库的压力。利用 Redis 原子性的自增操作,可以实现计数器的功能,比如统计用户点赞数、用户访问数等。简单的消息队列,可以使用Redis自身的发布/订阅模式或者List来实现简单的消息队列,实现异步操作。限速器,可用于限制某个用户访问某个接口的频率,比如秒杀场景用于防止用户快速点击带来不必要的压力。好友关系,利用集合的一些命令,比如交集、并集、差集等,实现共同好友、共同爱好之类的功能。 2. Redis怎么实现消息队列?

使用列表,让生产者将任务使用LPUSH命令放进列表,消费者不断用RPOP从列表中取出任务。发布订阅模式。类似于MQ的主题模式,只能消费订阅之后发布的消息,一个消息可以被多个订阅者消费。延时队列,使用SortedSet拿时间戳作为score,消息内容作为key,调用来生产消息,消费者用zrangebyscore指令获取N秒之前的数据进行轮询进行处理。 3. Memcached和Redis的区别?

MemCached 数据结构单一,仅用来缓存数据,而 Redis 支持多种数据类型。MemCached 不支持数据持久化,重启后数据会消失。Redis 支持数据持久化。Redis 提供主从同步机制和集群部署能力,能够提供高可用服务。Memcached 没有提供原生的集群模式。Redis 使用单线程的多路 IO 复用模型,Memcached使用多线程的非阻塞 IO 模型。Redis 的速度比 Memcached 快很多。 4. Redis 数据类型有哪些?

基本数据类型:

String:最常用的一种数据类型,String类型的值可以是字符串、数字或者二进制,但值最大不能超过512MB。Hash:Hash 是一个键值对集合。List:有序可重复的集合,底层是依赖双向链表实现的。Set:无序去重的集合。Set 提供了交集、并集等方法,对于实现共同好友、共同关注等功能特别方便。SortedSet:有序Set。内部维护了一个score的参数来实现。适用于排行榜和带权重的消息队列等场景。

特殊的数据类型:

Bitmap:位图,可以认为是一个以位为单位数组,数组中的每个单元只能存0或者1,数组的下标在 Bitmap 中叫做偏移量。Bitmap的长度与集合中元素个数无关,而是与基数的上限有关。Hyperloglog。HyperLogLog 是用来做基数统计的算法,其优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定的、并且是很小的。典型的使用场景是统计独立访客。Geospatial :主要用于存储地理位置信息,并对存储的信息进行操作,适用场景如定位、附近的人等。 5. Redis持久化机制

持久化就是把内存的数据写到磁盘中,防止服务宕机导致内存数据丢失。

Redis支持两种方式的持久化:

RDB的方式:根据指定的规则定时将内存中的数据存储在硬盘上,生成快照文件,Redis重启会加载快照文件恢复数据,RDB是 Redis 默认的持久化方案。AOF的方式:以独立日志的方式记录每次写命令,Redis重启时会重新执行AOF文件中的命令达到恢复数据的目的。AOF的主要作用是解决了数据持久化的实时性,AOF 是Redis持久化的主流方式。 6. 持久化机制的区别?

RDB 恢复数据远远快于 AOF 的方式。RDB 使用单独子进程来进行持久化,主进程不会进行任何 IO 操作,保证了 Redis 的高性能。对于同一份文件AOF文件比RDB数据快照要大。RDB方式数据无法做到实时持久化。RDB 文件使用特定二进制格式保存,存在老版本 Redis 无法兼容新版 RDB 格式的问题。 7. 过期键的删除策略

常见的过期删除策略是惰性删除、定期删除、定时删除。

惰性删除:只有访问这个键时才会检查它是否过期,如果过期则清除。

优点:最大化地节约CPU资源。缺点:如果大量过期键没有被访问,会一直占用大量内存。 定时删除:为每个设置过期时间的key都创造一个定时器,到了过期时间就清除。

优点:该策略可以立即清除过期的键。缺点:会占用大量的CPU资源去处理过期的数据。 定期删除:每隔一段时间就对一些键进行检查,删除其中过期的键。

该策略是惰性删除和定时删除的一个折中,既避免了占用大量CPU资源又避免了出现大量过期键不被清除占用内存的情况。

Redis中同时使用了惰性删除和定期删除两种。

8. Redis的内存淘汰机制是什么样的?

Redis是基于内存的,所以容量肯定是有限的,有效的内存淘汰机制对Redis是非常重要的。

当存入的数据超过Redis最大允许内存后,会触发Redis的内存淘汰策略。

在Redis4.0前一共有6种淘汰策略:

在设置了过期时间的键的空间进行移除:

volatile-lru:当Redis内存不足时,会在设置了过期时间的键中使用LRU算法移除那些最少使用的键。volatile-ttl:从设置了过期时间的键中移除将要过期的volatile-random:从设置了过期时间的键中随机淘汰一些

在全局的空间进行移除

allkeys-lru:当内存空间不足时,根据LRU算法移除一些键allkeys-random:当内存空间不足时,随机移除某些键noeviction:当内存空间不足时,新的写入操作会报错

在Redis4.0后一共有2种淘汰策:

volatile-lfu:从设置过期时间的键中移除一些最不经常使用的键(LFU算法:Least Frequently Used))allkeys-lfu:当内存不足时,从所有的键中移除一些最不经常使用的键 9. 缓存雪崩

缓存雪崩是指缓存中数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至down机。和缓存击穿不同的是, 缓存击穿指并发查同一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到从而查数据库。

解决方案:

缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生。如果缓存数据库是分布式部署,将热点数据均匀分布在不同搞得缓存数据库中。设置热点数据永远不过期。 10. 缓存击穿

缓存击穿是指缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力。

解决方案:

1、设置热点数据永远不过期。2、接口限流与熔断,降级。重要的接口一定要做好限流策略,防止用户恶意刷接口,同时要降级准备,当接口中的某些 服务 不可用时候,进行熔断,失败快速返回机制。3、布隆过滤器。bloomfilter就类似于一个hash set,用于快速判某个元素是否存在于集合中,其典型的应用场景就是快速判断一个key是否存在于某容器,不存在就直接返回。布隆过滤器的关键就在于hash算法和容器大小,4、加互斥锁, 11. 缓存穿透

缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求。由于缓存是不命中时被动写的,并且出于容错考虑,如果从存储层查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到存储层去查询,失去了缓存的意义。

在流量大时,可能DB就挂掉了,要是有人利用不存在的key频繁攻击我们的应用,这就是漏洞。

如发起为id为“-1”的数据或id为特别大不存在的数据。这时的用户很可能是攻击者,攻击会导致数据库压力过大。

解决方案:

接口层增加校验,如用户鉴权校验,id做基础校验,id<=0的直接拦截;从缓存取不到的数据,在数据库中也没有取到,这时也可以将key-value对写为key-null,缓存有效时间可以设置短点,如30秒(设置太长会导致正常情况也没法使用)。这样可以防止攻击用户反复用同一个id暴力攻击 12. Redis的主从复制模式

在主从复制中,数据库分为两类,一类是主库(master),另一类是同步主库数据的从库(slave)。主库可以进行读写操作,当写操作导致数据变化时会自动同步到从库。而从库一般是只读的(特定情况也可以写,通过参数slave-read-only指定),并接受来自主库的数据,一个主库可拥有多个从库,而一个从库只能有一个主库。

从库会先同步主库持久化数据,再同步发生在主库的实时操作数据。

13. Redis哨兵模式

Redis的主从复制模式下, 一旦主节点由于故障不能提供服务, 需要人工将从节点晋升为主节点, 同时还要通知应用方更新主节点地址, 对于很多应用场景这种故障处理的方式是无法接受的。

哨兵模式下Sentinel(哨兵)进程是用于监控redis集群中Master主服务器工作的状态,在Master主服务器发生故障的时候,可以实现Master和Slave服务器的切换,保证系统的高可用(HA)

哨兵进程的作用:

监控(Monitoring): 哨兵(sentinel) 会不断地检查你的Master和Slave是否运作正常。提醒(Notification):当被监控的某个Redis节点出现问题时, 哨兵(sentinel) 可以通过 API 向管理员或者其他应用程序发送通知。

自动故障迁移(Automatic failover):

当一个Master不能正常工作时,哨兵(sentinel) 会开始一次自动故障迁移操作。它会将失效Master的其中一个Slave升级为新的Master, 并让失效Master的其他Slave改为复制新的Master;当客户端试图连接失效的Master时,集群也会向客户端返回新Master的地址,使得集群可以使用现在的Master替换失效Master。Master和Slave服务器切换后,Master的redis.conf、Slave的redis.conf和sentinel.conf的配置文件的内容都会发生相应的改变,即Master主服务器的redis.conf配置文件中会多一行slaveof的配置,sentinel.conf的监控目标会随之调换。 14. 限流算法

计数器(固定窗口)算法: 计数器算法是使用计数器在周期内累加访问次数,当达到设定的限流值时,触发限流策略。下一个周期开始时,进行清零,重新计数。滑动窗口算法:滑动窗口算法是将时间周期分为N个小周期,分别记录每个小周期内访问次数,并且根据时间滑动删除过期的小周期。漏桶算法:漏桶算法是访问请求到达时直接放入漏桶,如当前容量已达到上限(限流值),则进行丢弃(触发限流策略)。漏桶以固定的速率进行释放访问请求(即请求通过),直到漏桶为空。令牌桶算法:令牌桶算法是程序以r(r=时间周期/限流值)的速度向令牌桶中增加令牌,直到令牌桶满,请求到达时向令牌桶请求令牌,如获取到令牌则通过请求,否则触发限流策略 15. Redis分布式锁?

-加锁: 加锁实际上就是在redis中,给Key键设置一个值,为避免死锁,并给定一个过期时间。
-解锁: 解锁的过程就是将Key键删除。但也不能乱删,不能说客户端1的请求将客户端2的锁给删除掉。这时候 random_value 的作用就体现出来。

为了保证解锁操作的原子性,我们用LUA脚本完成这一操作。先判断当前锁的字符串是否与传入的值相等,是的话就删除Key,解锁成功。

比较简单,但是问题也比较大,最重要的一点是,锁不具有可重入性。

16. Redis优点

基于内存操作,内存读写速度快。Redis是单线程的,避免线程切换开销及多线程的竞争问题。单线程是指网络请求使用一个线程来处理,即一个线程处理所有网络请求,Redis 运行时不止有一个线程,比如数据持久化的过程会另起线程。支持多种数据类型,包括String、Hash、List、Set、ZSet等。支持持久化。Redis支持RDB和AOF两种持久化机制,持久化功能可以有效地避免数据丢失问题。支持事务。Redis的所有操作都是原子性的,同时Redis还支持对几个操作合并后的原子性执行。支持主从复制。主节点会自动将数据同步到从节点,可以进行读写分离。 17. Redis缺点

对结构化查询的支持比较差。数据库容量受到物理内存的限制,不适合用作海量数据的高性能读写,因此Redis适合的场景主要局限在较小数据量的操作。Redis 较难支持在线扩容,在集群容量达到上限时在线扩容会变得很复杂。 18. Redis为什么这么快?

基于内存:Redis是使用内存存储,没有磁盘IO上的开销。数据存在内存中,读写速度快。单线程实现( Redis 6.0以前):Redis使用单个线程处理请求,避免了多个线程之间线程切换和锁资源争用的开销。IO多路复用模型:Redis 采用 IO 多路复用技术。Redis 使用单线程来轮询描述符,将数据库的操作都转换成了事件,不在网络I/O上浪费过多的时间。高效的数据结构:Redis 每种数据类型底层都做了优化,目的就是为了追求更快的速度。 19. Redis为何选择单线程

避免过多的上下文切换开销。程序始终运行在进程中单个线程内,没有多线程切换的场景。避免同步机制的开销:如果 Redis选择多线程模型,需要考虑数据同步的问题,则必然会引入某些同步机制,会导致在操作数据过程中带来更多的开销,增加程序复杂度的同时还会降低性能。实现简单,方便维护:如果 Redis使用多线程模式,那么所有的底层数据结构的设计都必须考虑线程安全问题,那么 Redis 的实现将会变得更加复杂。 20. keys命令存在的问题?

Redis的单线程的,keys指令会导致线程阻塞一段时间,直到执行完毕,服务才能恢复。scan采用渐进式遍历的方式来解决keys命令可能带来的阻塞问题,每次scan命令的时间复杂度是O(1),但是要真正实现keys的功能,需要执行多次scan。

scan的缺点:在scan的过程中如果有键的变化(增加、删除、修改),遍历过程可能会有以下问题:新增的键可能没有遍历到,遍历出了重复的键等情况,也就是说scan并不能保证完整的遍历出来所有的键。

21. SortedSet和List异同点?

相同点:

都是有序的;都可以获得某个范围内的元素。

不同点:

列表基于链表实现,获取两端元素速度快,访问中间元素速度慢;有序集合基于散列表和跳跃表实现,访问中间元素时间复杂度是OlogN;列表不能简单的调整某个元素的位置,有序列表可以(更改元素的分数);有序集合更耗内存。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/768542.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号