redis数据结构,持久化机制,过期策略详细解析

文章目录

    • 问题1:为啥Redis那么快撒?
    • 问题2:为啥要用redis?
    • 问题3:Redis有哪些数据结构呀?
    • 问题4:redis的pub/sub有什么缺点?
    • 问题5:Redis如何实现延时队列?
    • 问题5:redis的持久化?
      • 5.1 有两种持久化机制
      • 5.2 那这两种机制各自优缺点是啥?
      • 5.3 两种持久化机制如何选择?
    • 问题6: Redis还有其他保证集群高可用的方式么?
    • 问题7:redis cluster这种主从同步的原理是啥?
    • 问题8:redis 的内存淘汰机制是啥?
      • 8.1 redis的过期策略:过期删除+惰性删除
      • 8.1 redis的内存淘汰机制!
    • 问题9: 手写一下LRU代码?


问题1:为啥Redis那么快撒?

先总体概括一下:Redis是基于内存的单进程单线程模型的K-V数据库,官方提供的数据可以达到10万qps
1) 完全基于内存,绝大部分的操作都是基于内存的,非常快速
2)数据结构简单,对数据的操作也简单
3) 采用单线程,避免了不必要的上下文切换和竞争条件
4)使用多路IO复用模型,非阻塞IO.

问题2:为啥要用redis?

因为传统的关系型数据库已经不能满足业务需求,
比如说我们的一些汇率信息,词汇字段信息,这些都是
不会经常发生改变的,如果还是频繁的从数据库中获取
会给数据库造成压力,因此为了提高系统性能,引入了
缓存中间件,目前市面上比较常用的缓存中间件有Redis和Memcached
不过中和考虑了他们的优缺点,最后选择了Redis。

问题3:Redis有哪些数据结构呀?

常用的有五种String、Hash、List、Set、SortedSet
场景
string :缓存功能,计数器,共享用户session
list:分页展示,消息队列(左进右出 数据的生产者可以通过Lpush命令从左边插入数据,多个数据消费者,可以使用BRpop命令阻塞的“抢”列表尾部的数据
hash:一般都是存对象,简单对象格式
set:保障去重,
可以用来取交集,并集(比如共同好友)
sorted set 去重但可以排序,写进去的时候给一个分数,自动根据分数排序,可以用来做排行榜

还有HyperLogLog、Geo、Pub/Sub。
还玩过Redis Module,像BloomFilter,RedisSearch,Redis-ML

问题4:redis的pub/sub有什么缺点?

如果消费者下线的话,生产的消息会丢失,得用专业的消息队列,如rocketmq才能保障消息不丢失

问题5:Redis如何实现延时队列?

通过sortedset结构,以时间戳作为score,消息内容作为key,调用zdd来生产消息,消费者通过zrangbyscore获取N秒之前的数据轮询处理

问题5:redis的持久化?

5.1 有两种持久化机制

RDB持久化机制:是对redis中的数据执行周期性的持久化
AOF持久化机制:是对每条写入命令作为日志,以append-only的模式写入一个日志文件因为这个模式是只追加,没有任何寻址的开销,所以很快,类似于mysql中的binlog
这两种方式都可以实现redis的持久化,RDB适合做冷备,aof适合做热备
两种机制都开启的时候,redis再重启的时候默认会通过aof去重新构建数据,因为aof的数据相比于rdb更为完整。

5.2 那这两种机制各自优缺点是啥?

RDB
优点:因为RDB这种机制会生成多个文件,每个文件都代表着某一时刻redis里面的数据快照,所以说这种方式很适合做冷备份,完整的数据运维设置定时任务,然后定时同步到远端服务器,这样一来,一旦线上系统挂了,直接去远端拷贝一份之前的数据就可以了;同时他在同步数据的时候只是fork了一个子进程去做持久化,而且他在数据恢复的时候速度比aof来的更快
缺点:RDB都是快照文件,都是默认五分钟甚至更长时间才会生成一次,这就意味着可能会丢失5分钟的数据,而aof最多丢失1s的数据

AOF
优点:aof可以更好的保障数据不丢失,一般是每隔1s执行一次fsync操作,所以最多也就丢失1s的数据
缺点:做数据恢复的时候会比较慢;做冷备份和定期备份不太方便,可能需要通过手写脚本

5.3 两种持久化机制如何选择?

其实是可以综合使用RDB和AOF的,用aof来保障数据不丢失
做为数据恢复的第一选择,用RDB做不同程度的冷备份,在
aof文件都丢失或者是不可用的时候,在通过RDB进行快速的
数据恢复

问题6: Redis还有其他保证集群高可用的方式么?

哨兵集群sentinel:

哨兵集群模式必须要用3个实例才能保障自己的健壮性,哨兵+主从并不能保障数据不丢失但是可以保障集群的高可用性

为什么2个节点的哨兵集群架构不能正常工作?
由于两个参数, quorum和marority;
majority表示允许机器故障转移的个数,2的majority是2,表示要有两个节点才能进行故障转移,但是显然这不能满足。

所以正确的哨兵集群架构至少要有3节点

哨兵的作用:
集群监控,故障转移,
消息通知(如果某个redis实例有故障,哨兵负责发送消息作为报警通知给管理员)

问题7:redis cluster这种主从同步的原理是啥?

1)启动一台slave的时候,其实会发送psync命令给master,
2)如果这是slave第一次连接master,其实会触发一次全量复制
3)master就会启动一个线程,并生成rdb快照文件
4)同时master会把新的写请求都缓存在内存当中
5)rdb文件生成之后,master就会把这个rdb文件发给slave,slave拿到之后
第一件事就是先写到本地磁盘,然后加载进内存
6)之后master会把内存中缓存的写命令也发送给slave

问题8:redis 的内存淘汰机制是啥?

8.1 redis的过期策略:过期删除+惰性删除

定期删除:
默认100ms就随机抽一些设置了过期时间的key,去检查是否过期,过期了就删了

惰性删除:
定期删除存在一个问题,就是我有的key到了过期时间,但是没有被
检查到,而惰性删除就是针对于这种无效key,它是说我真正在查询
的时候就会去检查这个key过期了没有,如果它已经过期了就直接给
删除掉不给返回,没过期就爱咋咋地。

最后就是如果的如果,定期没删,我也没查询,那可咋整?–走内存淘汰机制

8.1 redis的内存淘汰机制!

常用的就是:
volatile-lru: 尝试回收最少使用的键
volatile-random: 回收随机的键使得新添加的数据有空间存放,但仅限于在过期集合的键。
volatile-ttl: 回收在过期集合的键,并且优先回收存活时间(TTL)较短的键,使得新添加的数据有空间存放

问题9: 手写一下LRU代码?

/**
 * LRU代码
 * @author hm
 */
public class LruCache<K,V> extends LinkedHashMap<K,V> {

    //定义缓存池数量
    private final   int cache_size;

    public LruCache(int size){
        //true表示最近访问的放在头部,最老访问的放在尾部
        super((int)Math.ceil(size/0.75)+1,0.75F,true);
        this.cache_size=size;
    }

    @Override
    protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
        //当map中的数据量大于指定缓存个数的时候
        return size()>cache_size;
    }
    
}

备注:这里给大家推荐一些redis学习入门的书籍和我参考的资料
《Redis中文官网》
《Redis实战》
《Redis深度探险—钱文品》
《Redis设计与实现—黄健宏》
公众号:三太子敖丙,中华石杉-石杉

你可能感兴趣的:(#,分布式缓存,redis,java,分布式,队列)