Redis 主从复制、哨兵和集群这三个有什么区别
主从模式:读写分离,备份,一个Master可以有多个Slaves。
哨兵sentinel:监控,自动转移,哨兵发现主服务器挂了后,就会从slave中重新选举一个主服务器。
集群:为了解决单机Redis容量有限的问题,将数据按一定的规则分配到多台机器,内存/QPS不受限于单机,可受益于分布式集群高扩展性。
Redis内部是如何存储数据的
这个问题我觉得简单说说表示自己了解过就行。redis内部使用一个redisObject对象来表示所有的key和value,redisObject最主要的信息如上图所示:type表示一个value对象具体是何种数据类型,encoding是不同数据类型在redis内部的存储方式。比如:type=string表示value存储的是一个普通字符串,那么encoding可以是raw或者int。
Redis如何删除过期数据
-
定期删除。redis会将设置过期时间的key放到独立字典中,定期遍历,它不会遍历所有数据,而是随机挑选出20条,如果有四分之一以上数据过期,则再次遍历
-
惰性删除。你获取某个key的时候,redis会检查一下 ,这个key如果设置了过期时间那么是否过期了?如果过期了此时就会删除,不会给你返回任何东西。
Redis与Memecache区别
-
Menecache只能存储字符串
-
redis可以进行持久化,Menecache只能存在内存
-
底层实现及通信协议不同,redis有自己的VM机制
缓存穿透
缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求,如发起为id为“-1”的数据或id为特别大不存在的数据。这时的用户很可能是攻击者,攻击会导致数据库压力过大。
解决:
- 接口层增加校验,如用户鉴权校验,id做基础校验,id<=0的直接拦截;
- 从缓存取不到的数据,在数据库中也没有取到,这时也可以将key-value对写为key-null,缓存有效时间可以设置短点,如30秒(设置太长会导致正常情况也没法使用)。这样可以防止攻击用户反复用同一个id暴力攻击
- 有个高级的用法是布隆过滤器。利用高效的数据结构和算法快速判断出你这个Key是否在数据库中存在,不存在你return就好了,存在就去查DB刷新KV再return
缓存击穿
缓存击穿是指缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力
解决:
- 加锁
- 失效时间(例如热门数据永不过期)
缓存雪崩
数据大批量到过期时间,而查询数据量巨大,在缓存失效的一瞬间,有多高并发请求直接透过缓存请求数据库,使得数据库挂掉。
例如淘宝网首页商品缓存突然全部失效,那么所有的刷新请求都会直接怼到数据库,会造成数据库挂掉,重启数据库还是会继续挂掉。
解决:
- 给缓存失效时间加“盐”,不让所有的缓存的失效时间一样。甚至某些更新少的页面可以设置永久缓存
- 分布式部署,使用分布式锁。
- 保险一些,可以加一些服务熔断降级的逻辑,以及本地缓存
和缓存击穿不同的是,缓存击穿指并发查同一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到从而查数据库。
如何保证缓存数据一致性(如果面试问redis在项目中的难点也可以说下一致性问题)
- 数据实时同步。 强一致性,更新数据库数据之后立即删除缓存,读数据的时候,再更新缓存,并且设置缓存失效时间,为了避免缓存雪崩,在更新缓存的时候,同一时间需要用锁,只允许一个请求访问数据库。
- 数据异步更新。准一致性。更新数据库之后,异步更新缓存,可以使用多线程技术或者用消息中间件通知更新缓存。
- 任务调度更新。最终一致性,采用任务调度框架,按照一定时间更新缓存。
redis回收策略
-
volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰,没设置的不会淘汰
-
volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰
-
volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰
-
allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰
-
allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
-
no-enviction(驱逐):禁止驱逐数据。不会继续写,但可以读,是默认策略
Redis的同步机制
第一次同步的时候,主节点做一次bgsave,并将后续的操作记录到内存buffer,待完成后将RDB文件全量同步到复制节点,复制节点接受完成后将RDB镜像加载到内存。加载完成后,再通知主节点将期间修改的操作记录同步到复制节点进行重放就完成了同步过程。后续的增量数据通过AOF日志同步即可。