目录
目录
目录
15、一个 Redis 实例最多能存放多少的 keys?List、Set、Sorted Set 他们最多能存放多少元素?
16、MySQL 里有 2000w 数据,redis 中只存 20w 的数据,如何保证 redis 中的数据都是热点数据?
17、如果有大量的 key 需要设置同一时间过期,一般需要注意什么?
1、介绍一下redis?
1、redis是一个免费开源、遵循bsd协议的高性能的key-value数据库
2、redis运行在内存中,但支持持久化到磁盘,重启的时候可以再次加载使用
3、具有丰富的数据类型。支持String、list、set、zset、hash5种常用类型及hyperloglog、geo、pub/sub等复杂类型
4、性能极高,支持11万/秒的读取速度及8万/秒的写速度。查找和操作的时间复杂度都是 O(1)
5、redis的所有操作都是原子的
6、支持事务
2、memcache和redis的区别?
1、memcacahe将数据全部存储在内存中,不能持久化,redis可以将数据持久化到磁盘。
2、memcache只支持简单的字符串类型,redis具有丰富的数据类型
3、redis的速度比memory更快
4、使用的底层模型及客户端使用的通信协议不同。
3、redis是单进程单线程的吗?
是,redis利用队列技术将并发访问变为串行访问,消除了传统数据库串行访问的开销。
4、一个字符串类型能够存储的最大容量是多少?
512M
5、redis的持久化机制?各自的优缺点?
redis的持久化机制有两种:rdb和aof,默认为rdb
rdb: 单独创建 fork一个子进程,将当前的父进程的数据库数据复制到子进程的内存中,然后由子进程写入临时文件中,持久化结束后,再让这个临时文件替换上次的快照文件,然后子进程退出,内存释放。
优点:
1、只有一个文件dump.rdb,方便持久化。
2、容灾性好,一个文件可以保存到安全的磁盘
3、性能好。fork()一个子进程来完成写操作,主进程继续处理命令,io最大化。
4、数据集大时,启动速度高于aof
缺点:
1、数据安全低。rdb是间隔一段时间进行持久化。如果在持久化过程中redis发生故障,会发生数据丢失。适合对数据完整性要求不高的情况
2、fork子进程的时候也会使主进程有短暂的阻塞,当数据集大或fork频率高时,也会使redis发生
阻塞。
aof: redis会将每一个收到的写命令通过write函数写入到文件中,类似于mysql的binlog.当重启的时候,redis会重新执行这些命令在内存中重建整个数据库的内容。
优点:
1、数据安全。aof持久化可以配置appendfsync属性为always,每执行一次命令就记录一次
2、这种记录执行命令的方式,及时宕机,也可以redis-check-aof解决数据一致性问题
3、aof的rewrite机制。
缺点:
1、aof比rdb文件大,且恢复速度慢。
2、数据集大的时候,比rdb启动效率低。
当两种方式同时开启,redis会优先选择aof
6、缓存穿透、缓存击穿、缓存雪崩、缓存抖动的定义及解决办法
1、缓存雪崩
缓存中的大量key集中失效,致使高并发情况下,大量请求同时访问数据库。
解决办法:1、加锁 2、分散key的失效时间 3、缓存预热
2、缓存击穿
热点key突然失效,致使高并发情况下对该key的访问同时访问数据库,
解决办法:1、加锁 2、热点数据不过期
3、缓存穿透
大量请求访问一个数据库和缓存中都没有的数据,致使每次都去查询数据库
解决办法:1、布隆过滤器 2、存null 3、接口层做用户鉴权:这种大量请求数据库及缓存中没有的数据的行为不常见,可能是恶意的攻击行为,因此可以通过鉴权的方式在接口层过滤掉非法请求。
4、缓存抖动
指Redis服务在响应时间上出现不稳定的波动现象
什么原因导致抖动?
1)高并发访问:Redis服务器同时处理大量并发请求时,如果请求超过了Redis服务器的处理能力,可能出现响应时间抖动。
2)不均衡的负载:打到Redis的请求不均匀地分布在不同的资源上,可能导致响应时间的抖动。
3)网络问题:网络延迟、丢包或拥塞等问题也可能导致Redis抖动。当Redis服务器与客户端之间的网络连接不稳定或面临网络故障时,响应时间可能出现抖动。
4)内存管理:Redis是基于内存的数据存储,当Redis面临内存压力,例如内存不足或者频繁的内存回收操作,可能会导致响应时间的抖动。
Redis抖动应对策略?
1)优化Redis配置:合理配置Redis服务器的资源参数,如最大连接数、最大内存限制等,已满足实际需求、减少抖动的可能性。
2)确保系统资源充足:为Redis服务器分配足够的内存、CPU等资源。
3)水平扩展Redis实例:分散负载到多个Redis实例上,以提高系统的整体处理能力。
4)监控和调优:监控Redis的性能指标,如响应时间、连接数、内存使用等,及时发现抖动现象,并针对性地进行调优。
5)网络优化:检查网络连接和带宽,确保Redis服务器和客户端之间稳定连接;优化网络设置以降低延迟和拥塞。
7、redis为什么这么快?
1、纯内存操作
2、单线程操作。避免了频繁的上下文切换
3、采用了非阻塞的io多路复用机制
8、redis的过期策略及内存淘汰机制
redis的过期策略: 定期删除+惰性删除
什么是定期删除+惰性删除?
定期删除,redis默认每隔100ms对key进行随机抽取检查,发现过期key则删除。
因为是随机抽样,所以必定有部分过期key没有及时删除,redis在用户每次获取key的时候会进行检查,如果key设置了过期时间并且已过期了,才会删除。这就是惰性删除
为什么不使用定时删除策略?
定时删除就是设置一个定时器,过期则将key进行删除,这样的确具有能够及时释放内存的好处。但是这会严重的消耗cpu性能,在高并发的情况下,redis要将时间应用在处理请求而不是删除操作上。而且在今天,内存的成本越来越低的情况下,以空间换时间的做法尤为普遍。
这种定期删除+惰性删除的过期策略有什么坏处?
这种随机抽取+用户请求key删除的方法必然导致 一些已经过期但未被抽取到也没被用户请求的数据在内存中激增,造成内存占用越来越高。
针对上述情况,redis的内存淘汰策略是什么呢?
redis提供了6种内存不足时的 内存淘汰策略,在redis.conf中通过以下形式设置
maxmemory-policy + 策略名称
1、 volatile-lru 在设置了过期时间的key中,挑选最近最少使用的数据进行删除
2、 volatile-ttl 在设置了过期时间的key中,挑选将要过期或已经过期的数据进行删除
3、 volatile-random 在设置了过期时间的key中,随机挑选数据进行删除
4、 allkeys-lru 在所有key中,挑选最近最少使用的数据进行删除、
5、 allkeys-random 在所有key中,随机挑选数据进行删除
6、 no-enviction 禁止驱逐数据,新写入操作将会直接报错
备注:倘若所有key都没有设置过期时间,则设置了1、2、3、策略等同于设置了 no-enviction
一般情况下使用策略的规则?
如果数据呈现幂率分布,也就是一部分数据访问高,一部分数据访问低,则采用allkeys-lru
如果数据呈现平等分布,所有数据的访问频率相同,则采用allkeys-random
9、redis的同步机制了解吗?
1、redis可以主从同步,从从同步。
第一次同步时,主节点做一次bgsave,并同时将后续修改操作记录到内存buffer,待完成后,将rdb文件全量同步到复制节点,复制节点接收后将rdb镜像加载到内存。加载完成后,在通知主节点将期间修改的记录同步到复制节点进行重放就完成了同步过程。
10、redis如何以指令形式设置密码和验证密码?
1、设置密码:config set requirepass 123456
2、验证密码:auth 123456
11、怎么理解redis的事务?
12、redis事务相关的命令有哪几个?
multi、exec、discard、watch
13、如何测试redis的连通性
ping
14、redis如何做内存优化?
(问内存优化而不是内存不足时的处理策略)
内存优化方法:主要是在存储层面,如对于一些对象类型,尽量使用hash类型存储。而不是为对象的每一个属性都设置一个单独的key.
15、一个 Redis 实例最多能存放多少的 keys?List、Set、Sorted Set 他们最多能存放多少元素?
理论上可以存储2^32,因此实际上是取决内存的大小
16、MySQL 里有 2000w 数据,redis 中只存 20w 的数据,如何保证 redis 中的数据都是热点数据?
(共2000w,只能存20w, 这个问题是想问redis的内存淘汰策略怎么选)
选择 allkeys-lru 作为内存淘汰策略。
17、如果有大量的 key 需要设置同一时间过期,一般需要注意什么?
redis中大量key集中过期,在那个情况下,可能会出现卡顿现象.,高并发情况下,有可能出现缓存雪崩,可以设置时间的时候加一下随机值,使得过期时间分散一些。
18、redis的常用场景?
1、会话缓存
2、全页缓存
3、队列
4、排行榜/计分器
5、发布订阅
19、使用过 Redis 做异步队列么,你是怎么用的?
20、redis分布式锁使用原理?
21、redis大Key问题
1、多大叫大key?
实际上,没有标准,每个公司和业务对大key的界定都不一样。凡是key大到对系统有影响了,就可以叫大Key.
给一个很多人的定义作为例子,高并发低延迟场景下, 针对string类型大小超过10KB, 针对List、set、zset、Hash类型,元素个数超过5000个,就是大key.
( 但实际上,就算达成上述程度,不一定会对系统产生影响,也有可能,没到那个程度,看你所在公司实际情况了)
2、大key有什么危害?
2.1 读取成本高: 读取时间长,消耗的网络带宽多,从而影响相关服务
2.2 写操作容易阻塞,导致无法正常响应
2.3 占用更多存储空间,导致内存溢出
2.4 集群情况下,内存使用不均。
3、大key产生的原因?
3.1 研发人员业务设计不合理,没有考虑数据变化,做好拆分
3.2 程序bug
4、如何找到大key?
4.1 使用redis-cli --bigkeys命令,可以打印出每种类型最大的key
4.2 redis rdb tools工具
5、大key清理
5.1 低峰期删除:选择业务流量低的时候清理缓存
5.2 分批定时定量删除
1.hash : hscan扫描
2.set : srandmember 随机取数据删除
3. zset : zremrangebyrank 移除指定排名区间内的所有元素
4.list pop 删
5.3 异步非阻塞删除: 使用unlink指令删除
22、zset类型使用专题(很多面试爱问)
常用命令:
应用场景:
1、排行榜
2、延时队列
实现方式描述:
生产者:放元素的时候,score等于system.currentTimeMills+delayTime 当前时间+延迟时间
消费者: 用redis的zRangebyScore, 取值范围是0到当前时间。
底层实现原理:压缩表+跳表
默认情况下,zset中元素个数小于128,且元素大小小于64字节时,采用压缩表,否则采用跳表。
采用压缩表主要是存储连续,减少了内存碎片以及额外的指针开销。
变成跳表主要是提高性能,压缩表的时间复杂度是O(n), 跳表时O(lngN).
为什么用跳表,不用红黑树等其他结构?
因为实现简单,像红黑树等还需要做复杂的平衡等操作,而跳表直接通过随机生成层级索引来维护数据有序性就可以了,插入和删除只需要操作相邻的指针就可以了。
zset的score相同的时候是怎么进行排序的?
官网文档解释是,如果score相同会按照字典顺序来排序,a到z的顺序。