3. 《剑指Java面试-Offer直通车》--Redis

String:sds 动态字符串【已使用的。还没有使用的】
List:双向链表   BLPOP LPOP LPUSH
Hash: HashMap
Set: 实现是一个 value永远为null的HashMap
Sorted Set: 跳跃表

1. redis如何清理数据?
————自身的失效策略,如:lru
2. redis为什么那么快?
————内存处理
————单线程【避免了多线程场景下上下文切换】
————io多路复用,非阻塞
3. redis和mem区别?
————mem是多核,redis是单核
————redis数据结构更丰富,所以mem内存利用率更高
4. redis可以执行lua吗?
————Redis内嵌了LUA解析器,可以执行lua 脚本,脚本可以通过eval等命令直接执行
5. redis其他特性?
————redis的所有操作都是原子性的
————内部实现采用epoll,采用了epoll+自己实现的简单的事件框架。epoll中的读、写、关闭、连接都转化成了事件
————redis实际上把任务封闭在一个线程,自然避免了线程安全问题,不过对于需要依赖多个redis操作的复合操作来说,依然需要锁,而且有可能是分布式锁。
————Master最好不要做任何持久化工作,如RDB内存快照和AOF日志文件;(Master写内存快照,save命令调度rdbSave函数,会阻塞主线程的工作,当快照比较大时对性能影响是非常大的,会间断性暂停服务,所以Master最好不要写内存快照;AOF文件过大会影响Master重启的恢复速度)
————如果数据比较重要,某个Slave开启AOF备份数据,策略设置为每秒同步一次
————keys数量大可能会导致卡顿,可以使用SCAN【无阻塞/少量】
6. redis单线程是什么意思?
————单线程指的是网络请求模块使用了一个线程(所以不需考虑并发安全性),即一个线程处理所有网络请求,其他模块仍用了多个线程。
7. redis的数据类型
————string动态字符串[redis里面append很常见]
————hash[初始为4,冲突链地址法,1:1rehash,rehashidx记录当前位置【渐进rehash】] [hmset hget]
————list是双向链表[lpush lrange]
————sorted set是跳跃表[zadd zrangebyscore]
————set [sadd smembers]
8. redis异步队列
————List(rpush,lpop消费,缺点是:没有等待队列里面有值就直接消费)
————BLPOP(阻塞直到有消息或者超时)
————pub/sub【无状态,无法保证可达】
9. redis持久化怎么回事?
————RDB(save阻塞、bgsave fork子进程)1. 执行bgsave(判断当前是否正在执行持久化)2. fork创建子进程(过程redis会阻塞)3. fork后,bgsave结束,不阻塞了 4. 子进程根据当前内存生成快照,替换旧版RDB 5. 子进程信号量同志结束      (save mn、从节点全量复制、debug reload、shutdown)开启
————AOF (命令追加,文件同步、文件重写、数据加载)
10. redis集群?
————全量同步(1. 从发送sync 2. 主接收sync 开始bgsave 缓冲区记录后续 3. bgsave结束,给从发送文件 4. 从收到载入文件 5. 主发送缓冲 6. 从同步缓冲)
————redis sentinel解决主从同步场景下,主突然挂了的情况
————redis 集群(hash 槽)
11. redis缓存雪崩
————穿透redis,将数据库给打挂了
————redis缓存挂了?key失效?——失效时间+随机数 ,其他原因?(redis集群+sentinel)
————sentinel限流
————本地缓存(guava)
————https安全拦截
12. redis和guava?
————guava是本地缓存,redis是分布式缓存,reids的数据类型更多样


IO 多路复用是5种I/O模型中的第3种,对各种模型讲个故事,描述下区别:
故事情节为:老李去买火车票,三天后买到一张退票。参演人员(老李,黄牛,售票员,快递员),往返车站耗费1小时。

1.阻塞I/O模型
老李去火车站买票,排队三天买到一张退票。
耗费:在车站吃喝拉撒睡 3天,其他事一件没干。

2.非阻塞I/O模型
老李去火车站买票,隔12小时去火车站问有没有退票,三天后买到一张票。
耗费:往返车站6次,路上6小时,其他时间做了好多事。


3.I/O复用模型
1.select/poll
老李去火车站买票,委托黄牛,然后每隔6小时电话黄牛询问,黄牛三天内买到票,然后老李去火车站交钱领票。 
耗费:往返车站2次,路上2小时,黄牛手续费100元,打电话17次

2.epoll
老李去火车站买票,委托黄牛,黄牛买到后即通知老李去领,然后老李去火车站交钱领票。 
耗费:往返车站2次,路上2小时,黄牛手续费100元,无需打电话

4.信号驱动I/O模型
老李去火车站买票,给售票员留下电话,有票后,售票员电话通知老李,然后老李去火车站交钱领票。 
耗费:往返车站2次,路上2小时,免黄牛费100元,无需打电话

5.异步I/O模型
老李去火车站买票,给售票员留下电话,有票后,售票员电话通知老李并快递送票上门。 
耗费:往返车站1次,路上1小时,免黄牛费100元,无需打电话

1同2的区别是:自己轮询
2同3的区别是:委托黄牛
3同4的区别是:电话代替黄牛
4同5的区别是:电话通知是自取还是送票上门

​​​​​​​

 

redis采用的是单进程、单线程模型的 kv数据库,由c语言编写,将数据存储在内存里面,读写数据的时候,不会受限于硬盘io的速度限制

redis不使用表,它的数据库不会预定义,不会要求redis对存储的不同数据进行关联 ,所以:性能相对于关系型数据库要高出很多,其存储结构就是键值对,类似于hashmap

redis采用单线程,一般在面对并发场景用多个线程来处理,将io线程和业务线程分开,业务线程使用线程池,避免频繁创建和销毁线程,即便一次请求阻塞,也不会影响到其他请求

redis为什么会反其道而行之?redis单线程结构是说“其主线程是单线程的,主线程包括io事件的处理,以及io对应的相关请求业务的处理,还负责过期键的处理,复制协调,集群协调等等” 这些会被封装成周期性的任务,周期性的处理。避免了多线程里面频繁的上下文切换,锁竞争,使得redis执行起来 效率高

单线程可以处理高并发的请求吗?当然可以了,并发并不是并行。redis使用单线程+io多路复用。多核cpu流行的今天,使用单线程,只用一个核会不会对资源浪费?

不必担心,因为redis早已对相关问题进行验证,首先redis支持的qps相当高,并且qps峰值的时候cpu也并没有跑满,主要问题是网络原因,导致并非不能进一步上升,因此cpu并不是制约瓶颈【可以在多核场景下,启动多个redis实例】。这里提到的单线程是处理网络请求的时候只是单个线程的。。。

一个正式的redisserver肯定不止一个线程,如:持久化的时候,会根据实际情况,以子进程/子线程的方式运行

redis跑在单线程中,所有操作都是按照顺序线性执行的,但是读写操作【等待用户输入/输出】都是阻塞的。所以io操作一般不能直接返回。就会导致整个进程无法对其他用户提供服务,io多路复用就是为解决这个问题而出现的

 

 当使用read/write对某一个文件描述符fd进行读写时,如果当前fd不可读/写,整个redis就不会对其他的操作作出响应

redis采用那个呢?因为redis需要在多个平台运行 ,同时为了最大化的提供效率和性能,会根据编译平台不同选择不同的多路复用函数作为子模块。 

 简单动态字符串、

 

Hash

List

 Hset【支持交集、并集等】

 Sort set

假如redis里面有一亿个key,有10万个是固定前缀的key,如何将他们全部找不出来 

1. 使用keys 2. 查看总数据

3. 灌入数据

4. 查找

找出所有以k1打头的key。因为一次返回所有的key,key的数量过大,导致客户端被卡住了。也就是说当redis中key很多的时候,对于内存的消耗和redis服务器都是隐患

这个时候我们可以使用SCAN指令。可以无阻塞的提取出目标的列表,每次执行只会返回少量元素,可以用于生产环境,而不会出现向keys命令带来阻塞的问题

 

 

 

 

频道:topic

 

 为了解决这个问题,就需要专业的消息队列了。如:kafka等

rdb配置:

900s的时候有一次写入就进行备份 

当备份进程出错的时候,主进程停止写入,为了保证数据一致性的问题

保存的时候需要压缩,一般不建议开启,避免带来额外的开销

 

  

 

开关

写入方式:always[一旦缓存区的内容发生变化,就写入]

ererysec【每隔一秒,写入】推荐

no【交由操作系统决定,一般会等到操作系统满了才开始填充】

 

 

 

一个master是用于写操作,其他slave是用于读操作,master/slave代表了一个个独立的redis实例,另外定期的数据备份操作也是选取了其中一个slave完成的。可以最大程度发挥redis的性能,为了支持数据的弱一致性和最终 一致性。 

支持主从同步、从从同步

第一次同步主节点执行bgsave,并同时将后续修改记录到内存buffer,待完成后,将rdb文件全亮同步到从节点里面,从节点完成后就将rdb文件加载到内存中,完成后,再通知主节点,将其间修改及其内存里面的增量数据同步到从节点进行重放

 全量同步完成,后续所有写操作都是在master上完成的,所有读操作都是在slava上进行的。当然了master也可以去读,但是为了提升性能,一般会交由slave去读。

因此用户的写操作,需要及时的扩散到slave里面,保存数据最大程度上的同步

redis的master-slave进程在正常运行期间更新操作,包括写、删、更改等

redis的主从进程在正常运行期间。更新增量同步方式如下:

主从模式的弊端就是不具备高可用性。

当master挂掉后,redis将不能对外提供写入操作 

 

 

 

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值