Redis是什么?
redis是key-value的nosql数据库,可以用来做缓存、分布式锁等。
SQL(关系型数据库):SQLServer、Oracle、MySQL;性能会随着数据的增大而下降
NoSQL(非关系型数据库):MongoDB、Redis;解决大规模数据集合多重数据种类带来的挑战
NewSQL(对各种新的可扩展/高性能数据库的简称):GenieDB;保持传统数据库管理系统优点的同时,力求实现NoSQL数据库的可伸缩性和高性能
Redis有哪些应用场景
缓存、分布式锁、黑白名单
Redis有什么优势
性能高,强并发能力,单机可以支撑几w到10w的QPS(每秒请求数)
Redis为什么这么快
存内存操作
核心是基于IO的多路复用,只是监听事件,不处理事件,而是直接压到队列,处理事件交给对应的处理器
单线程反而避免了多线程的频繁的上下文切换
Redis主要消耗什么物理资源
内存和网络带宽
Redis到底是单线程还是多线程
redis是单线程,对整个redis是多线程
Redis和Memcached有什么区别
Memcached跟redis一样,都是来做缓存的,但redis更为强大。
memcached只支持String,redis支持更为丰富的数据类型
redis支持持久化,memcached不支持(纯内存的)
支持redis中间件多(redis的速度比memcached快)
Redis支持哪些数据类型及应用场景
一共8种数据类型:string、list、set、hash、sortedset、bitmap、geo、hypeloglog
redis存储key-value格式的数据,key为字符串,value可以为(常用的5种)string,hash,list,set,sortedset
value的数据结构:
字符串(string)
普通的单值存储key value;分布式锁 setnx ;计数器 incr key;分布式session;缓存;黑名单
set name tom
哈希类型(hash,HashMap格式)
购物车;hash实现抢购;限购发放优惠券;激活码
hset person name tom age 18
列表类型(list,LinkedList格式,支持重复元素)
朋友圈点赞;消息订阅;
lpush a1 0 1
,从键为’a1’的列表左侧加⼊数据a 、 b 、c
集合类型(set,HashSet格式,不允许重复元素)
随机推荐新闻热点;随机抽奖
sadd a1 tom jerry pubby
,向键’a3’的集合中添加元素’zhangsan’、‘lisi’、‘wangwu’
有序集合类型(sortedset,TreeSet不允许重复元素,且元素有序)
电影院排序;排行榜
zadd a1 4 tom 5 jerry 6 pubby 3 jack
,向键’a4’的集合中添加元素’lisi’、‘wangwu’、‘zhaoliu’、‘zhangsan’,权重分别为4、5、6、3
Redis默认支持多少个数据库,怎么修改
默认16个库,redis.conf中修改
Redis的key和value最大可以支持到多大?
key可以大到512M,value最大512M
Redis事务有什么作用
Redis事务是一组命令集合。就是把多个命令打包,顺序地添加到队列中,并按照顺序依次执行。Redis事务能力弱,很少使用。
Redis事务的主要作用就是串联多个命令防止别的命令插队。
基本命令:
MULTI开启一个事务块;EXEC执行事务块所有命令;
DISCARD取消事务;
WATCH监视一个或多个key,事务执行前,key被其他命令修改了,则事务中断;
UNWATCH取消对key的监视
Redis持久化有什么作用
为了快速的恢复redis中的数据
可以作为一个存储来使用
Redis有哪几种持久化方式
RDB
每隔一定的时间周期将内存中的全量数据写入到快照文件中。
优点:数据恢复快;缺点:容器丢失数据
AOF(Append-only file)
对内存中数据进行修改的指令记录下来
优点:最多丢失1秒数据;缺点:数据恢复慢
Redis持久化方案是综合使用RDB和AOF两种持久化机制,AOF作为数据恢复的第一选择;RDB来做冷备份,在AOF文件都不可用的时候,可以用RDB来快速恢复数据。
Redis内存满了怎么办
可以在redis.conf中通过maxMemory来设置内存大小,在64位的系统中默认无内存限制,一般设置为物理内存的3/4
redis中失效的数据采用:定时删除+定期删除+惰性删除的方式,删除不掉的数据用内存淘汰机制。
定时删除:在设置键过期的同时,创建一个定时器,让定时器在键的过期时间来临,立即对键进行删除。
定期删除:redis默认每隔100ms就随机抽取一些设置了过期时间的key,检查是否过期,过期了就删除。
惰性删除:过期key,靠定期删除没有删除掉,还在内存里。除非系统去查找那个key,才会被redis删除。
定期删除漏掉了很多过期key,且没使用惰性删除,就是用redis内存淘汰机制。allkeys-lru:对所有key使用LRU算法进行删除
Redis如何实现大量数据插入
redis中引入管道机制(cat data.txt | redis-cli-pipe)
使用Luke协议,通过redis-cli-pipe发送数据到服务器
采用Jedis的父类中的pipelined()方法获取管道
使用RedisTemplate批量保存数据
Redis有那些高可用的方案
主从:分担读的压力
哨兵:解决主节点的单点故障
redis-cluster:写的压力,但是从节点只是备份节点,不分担读,要扩读,就要增加主节点。
Redis中的哈希槽怎么理解
用来进行数据的更好路由
redis-cluster中将分为16384个哈希槽(hash slot),所有的数据都分布在这些slot中,即使宕机,也会将这些节点的slot分担到其他节点去。
Redis支持的Java客户端有哪些
Jedis
Redisson是什么框架
Redisson在redis的基础上,封装了一套用分布式系统的一系列工具。
Jedis和Redisson对比有什么优缺点?
Jdeis是Redis的java实现客户端,其API提供了比较全面的Redis命令的支持;
Redisson实现了分布式工具,但与Jedis相比,功能较为简单。Redisson的宗旨是让使用着对redis的关注分离,从而让使用着关注处理业务逻辑上。
Jedis的性能要高于Redisson
什么是缓存预热
程序启动或缓存失效之后,主动将热点数据加载到缓存中。从而减少穿透和击穿的问题,缓解DB压力
代码思路:
实现InitializingBean或者CommandLineRunner
查询所有数据
把数据放到redis缓存中
设置失效时间
什么是缓存雪崩,如何解决
①、redis宕机后,会导致请求都访问数据库,会导致mysql宕机,web容器中会拿出大量线程连接mysql,导致资源耗尽。从而引起一系列连锁反应。
解决办法:
事前:redis备份、高可用、读写分离
事中:熔断,限流,降级
事后:用备份快速恢复
②、在某个时间段,大量数据同时过期导致雪崩问题
解决办法:
设置失效时间
什么是缓存穿透,如何解决
恶意构建redis中不存在的key,大量请求到DB
解决方法:
恶意构建不存在的key,反推到redis中
布隆过滤器(redis中存在,是不一定存在;redis中没有,是真没有)
什么是缓存击穿,如何解决
热点key(热点数据)失效,导致大量请求在redis未命中,请求到DB,导致DB宕机
解决方法:
设置key不失效(不可行)
上锁减少请求到DB(分布式锁,本地锁)
热点key进行分散
Redis和数据库双写一致性问题如何解决
先操作数据库,再删除缓存,失败就隔2秒删除一次,没有删掉就使用过期兜底
先操作数据库,然后将消息丢到mq中,让mq去删除缓存或者更新
先操作数据库,MySQL要写binlog,把binlog中的数据提取出来,修改缓存
Redis有哪些危险命令,如何防范
flushall、flushdb、config、keys
配置redis.conf,找到security区域,禁用命令
Redis如何统计独立用户访问量
incr,通过自增方式判断用户的访问量
HyperLogLog用来做基数统计的算法,误差很小。不适合数据敏感场景。
Redis的协议
resp协议(redis serialization protocol)及redis序列化协议,是一种简单的文本协议。
*为参数个数,$为一个参数字节数
Redis单线程模型
①、redis基于Reactor模式开发了自己的网络事件处理器,称为文件事件处理器。
②、文件事件处理器由Socket,IO多路复用程序,文件事件分派器,事件处理器组成
事件处理器由:
|——连接应答处理器:处理客户端的连接请求
|——命令请求处理器:执行客户端传递过来的命令
|——命令回复处理器:返回客户端命令的执行结果
③、IO多路复用程序回同时监听多个socket,当socket执行accept,read,write,close操作时,产生相对应的文件事件。IO多路复用程序会把产生事件的所有socket压入一个队列,传送给文件事件分派器,分派器会根据socket产生的事件类型分给对应事件处理器处理。
④、事件种类:AE_READABLE、AE_WRITABLE
⑤、redis的客户端与服务端的交互
分布式锁
ZooKeeper实现(CP):
①、基于zk的临时节点和watch机制来实现。例如,该目录下的节点抢占了锁,其他锁的节点就监听该目录,该节点释放锁之后,其它节点就会抢占该锁,出现羊群效应。
②、避免羊群效应,可以采用临时的有序节点。
Redis实现分布式锁(AP):
①、采用Redisson来做分布式锁,也是使用setnx,但由Lua保证原子性,加入了WatchDog进行锁续期
②、Redisson如何工作:客户端加锁会发送一段Lua脚本给redis集群,完成加锁,并在客户端产生一个watchDog每隔10s就检查锁的时间是否快到期,并且客户端未释放锁。时间到了会续期30s。客户端宕机了,watchdog就没了,锁到了时间就会释放。
③、redis实现分布式锁在极端情况下会出现丢锁的情况,例如,redis采用主从架构,向当前主节点上锁,但未同步到从节点上,此时主节点宕机了,哨兵会选择一个节点作为主节点,现在的主节点就没有锁了,所以就丢锁了;(redis官方给出redLock方案,就是另外拿3台redis节点来作为redlock,向3台redis节点都要写锁,超过半数写锁成功才是成功。但redLock本身是有问题的,redis是基于AOF进行数据持久化的,当前有key,但AOF文件没来得及刷新,节点就宕机了,就丢锁了)
补充CAP理论:
C:一致性(Consistency)
A:可用性(Availability)
P:分区容错性(Partition Tolerance)
Redis主从复制和哨兵
主从复制:
主节点和从节点都可以进行服务,从节点复制主节点数据。主节点宕机了,从节点还可以提供服务
一个master可以用多个slave
一个slave只能有一个master
数据只能由master流向slave
高并发:通过设计保证系统能够同时并行处理很多请求。想提高redis的读写能力,可以用redis的主从架构。
高可用:是指通过设计减少系统不能提供服务的时间。使用redis的主从架构解决redis单点故障问题,需要哨兵机制。
主从复制原理:
全量复制:
从节点发起psync命令同步数据,发送命令之前会跟master建立socket长连接
主节点收到psync命令执行bgsave生成最新的rdb快照数据,会把这些可能修改数据集的请求缓存在内存中。
master发送rdb数据给slave
slave清空老数据并加载主节点rdb
master发送buffer
slave执行buffer里的写命令到内存
master通过socket长连接连续把写命令发给slave,保证数据一致性。
数据部分复制:
master和slave断开重连后,一般会对整份数据复制,但redis2.8之后,redis支持部分数据复制命令psync去master同步数据,slave与master在网络断开重连后进行部分数据复制(断电续传)
master会在其内存中创建一个复制数据用的缓存队列,缓存最近一段时间的数据,master和它所有的slave都维护了复制的数据下标offset和master的进程id,因此,当网络连接断开后,slave会请求master继续进行未完成的复制,从缓存所记录的数据下标开始。如果master进程id变化了,或者从节点数据下标offset太旧,已经不在master的缓存队列里了,那么将会进行一次全量数据的复制。
哨兵模式:
redis哨兵模式用于为redis实现高可用,在主从分离的模型中,如果主服务器宕机了,那么哨兵将选出一台服务器升级为主服务器提供服务。
选举过程。。。。
哨兵集群只有一个哨兵节点,redis的主从也能正常运行以及选举master,如果master宕机了,那唯一的那个哨兵节点就是哨兵leader,可以正常选举新的master
Redis集群脑裂
①、形成原因:因为网络问题,导致master节点跟slave节点和sentinel集群处于不同的网络分区,此时sentinel集群无法感知到master存在,会选择一个slave节点提升为master节点。所以就存在两个master节点。
②、导致问题:如果客户端还在基于原来的master节点继续写入数据,那么新的master节点就无法同步数据,当网络问题解决之后,sentinel集群将原先的master节点降级为slave节点,此时新的master节点同步数据会造成打量数据丢失。
③、redis配置文件
min-slaves-to-write 3
,代表连接到master的最少slave数量min-slaves-max-lag 10
,表示slave连接到master的最大延迟时间
按照这个配置,要求至少3个slave节点,且数据复制和同步的延迟不能超过10s,否则的话master就会拒绝写请求,配置了这两个参数后,发生了脑裂的话,原先的master节点收到客户端的写入请求会拒绝,可以减少数据同步之后的数据丢失。
redis中的异步复制情况下的数据丢失问题也能使用这两个参数。
评论区