文章目录
Redis 是一个 K-V的存储器 就是一个 Map集合!
Redis的数据结构:
- String
Map<K,String>
set k v
get k - Hash
Map<K,Map<K,V>>
hset k field value …
hget k filed
hgetall k - List
Map<K,List>
list 底层的实现是双向链表 (管道k )
LPUSH k v
从管道(k)左边推一个值进入
RPUSH
从管道(k)右边推一个值进入
LPOP
从管道(k)左边弹一个值
RPOP
从管道(k)右边弹一个值 - Set
Map<K,Set>
SADD k v
SPOP k 从里面随机弹一个出来 - ZSet(有序的set 集合)
Map<K,ZSet>
ZADD k 分数1 v1 …
ZRange k 0 2 - BitMap(补充的)
Redis持久化:
AOF RDB
RDB 是redis 默认的持久化策略
RDB 速度快,但是安全性差
RDB 是把Redis 当前的数据快照保存一份
java 有个ObjectXXXStream rdb 就是类似把当前内存的数据直接通过对象流写到磁盘上面
AOF: 速度慢,但是安全性高(可以设置让它只丢失1s的数据)
AOF :就是把redis的写的操作命令记录在一个文本文件里面,aof 是以追加的形式写文件
redis的用途:
- 缓存 (缓存可有可无,RDB)
- 共享session(别人登陆的数据保存在里面,需要持久强一点AOF)
Redis的过期删除策略(重点):
redis的key 可以设置过期时间,若时间到了,该key 会自动从redis 里面删除
Redis 内部是怎么删除过期key的呢?-> 订单30min 后失效,12306 25min 票过期了
redis
1 定时删除 (每一个key 都需要一个线程->对cpu的要求高)
void set(String k,String v,long time){
redis.put(k,v)
long futureDeadTime = 当前时间 + time ;
new Thread(()->{
while(true){
if(当前时间>=futureDeadTime){
redis.remove(k) ;
break ;
}
}
}).start();
}
2 惰性删除(Redis 不会主动删除里面的key)
之前只有一个:Map<String,String> redis ;
新增一个数据结构:
String: K,
long: 未来它死的时间
Map<String,long> expires ;
void set(String k,String v,long time){
redis.put(k,v);
expires.put(k,当前时间+time);
}
触发删除的方法:
String get(String k){
if(expires.exist(k)){
long futureDeadTime = expires.get(k);
if(当前时间>=futureDeadTime){
redis.remove(k) ;
expires.remove(k);
return null ;
}
}
return redis.get(k);
}
思考:我们如果永久不访问这个过期的key ?
那该key 还会删除吗 ? 不会,占用内存的资源
3 定期删除(也是由服务器redis 触发的删除)
我们班35 个人,若每一个人都有一个助教(每个key,都有一个线程),问题不会可以直接找自己的助教
我们班只有1 个助教(1个助教帮很多人解决问题)
Map<String,String> redis ;
Map<String,Long> expires ;
{
new Thread(()->{
while(true){
Thread.sleep(5000) ;
List<String> deadKeys = new ArrayList<>();
expires.foreach((k,v)->{
if(当前时间>=v){
deadKeys.add(k) ; // 记录
}
})
deadKeys.foreach((k)->{
redis.remove(k);
expires.remove(k) ;
})
}).start();
}
}
void set(String k,String v ,long time){
redis.put(k,v);
expires.put(k,v)
}
String get(String k){
redis .get(k) ; // 有没有什么问题?
}
思考:这个过期删除的线程它是5s 执行一次
有个key,它的存活时间2s,在第3 s的时间,该key 有没有从redis 集合里面删除?
没有删除,定期删除有个实时性的问题:
解决思路,就是利用惰性删除:
代码的改进:
String get(String k){
if(expires.exist(k)){
long futrueDeadTime = expires.get(k);
if(当前时间>=futrueDeadTime){ // 该key 已经过期了,但是定期任务还没有发现他
redis.remove(k);
expires.remove(k) ;
return null ;
}
}
return redis.get(k) ;
}
Redis的集群:
Redis的官方集群的方案:6 台服务器,3 主3 从?