redis总结
一、Redis是什么?
基于内存亦可持久化的日志型、Key-Value数据库。
二、Redis的优点
1.速度快
原因:绝大部分请求是纯粹的内存操作;
使用了很多查找操作都特别快的数据结构进行数据存储;
采用单线程,避免上下文切花和竞争;
用到了非阻塞I/O多路复用机制
2.数据结构
String,list,hash,set,zset
3.原子性,支持事务
4.可以用作分布式锁;可以持久化数据;可以用作消息队列、排行榜、计数器;还支持publish/subscribe、通知、key过期等等
三、Redis和memcache对比
1.存储方式
Memcache把数据全部存在内存,断点后会挂掉,无法做到数据的持久化,且数据不能超过内存;
Redis有一部分数据存在硬盘上,可以做到数据的持久性。
2.数据支持类型
Memcache只支持string类型
Redis支持string,list,hash,set,zset
3.使用的底层模型
他们之间实现方式以及与客户端之间通信的应用协议不一样;
Redis直接构建了VM机制
4.存储值大小
Redis最大可以存储1GB,而memcache只有1MB
四、Redis存在的问题
1.缓存数据库的双写一致性问题
解决:
给缓存设置过期时间,缓存过期后自动查询数据库,保证数据库和缓存的一致性;
先更新数据在删除缓存,需要将要删除的缓存的key放到消息队列中去,不断重试,知道删除成功。
2.缓存雪崩
解决:设置缓存过期时间的时候加一个随机值;
设置双缓存,缓存1设置缓存时间,缓存2不设置,1过期后直接返回缓存2,并且启动一个进程去更新缓存1和2.
3.缓存穿透
利用互斥锁。缓存失效时,不能直接访问数据库,而是要先获取到锁,才能去请求数据库。没有得到锁,则休眠一段时间后重试。
采用异步更新策略。无论key是否取到值,都直接返回。Value值中维护一个缓存失效时间,缓存如果过期,异步起一个线程去读数据库,更新缓存。需要做缓存预热(项目启动前,先加载缓存)操作。
提供一个能迅速判断请求是否有效的拦截机制。比如利用布龙过滤器,内部维护一系列合法有效的key,迅速判断出请求所请求所携带的key是否合法有效。如果不合法,则直接返回。
4.缓存并发竞争
解决:如果多线程操作没有顺序要求的话,可以设置一个分布式锁,然后多个线程去争夺锁,谁先抢到锁就可以先执行。
可以利用redis的incr命令。
当多线程操作需要顺序时,可以设置一个消息队列,把需要的操作加到消息队列中去,严格按照队列的先后执行命令。
五、Redis的过期策略以及内存淘汰机制
定期删除和惰性删除的内存淘汰机制
在redis.conf中有一行配置
# maxmemory-policy volatile-lru该配置就是配内存淘汰策略的
- noeviction:当内存不足以容纳新写入数据时,新写入操作会报错。
- allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key。
- allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个key。
- volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的key。这种情况一般是把redis既当缓存,又做持久化存储的时候采用。
- volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个key。
- volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的key优先移除。
Ps:如果没有设置expire的key,不满足先决条件(prerequisites);那么volatile-lru,volatile-random和volatile-ttl策略的行为和noeviction(不删除)基本上一致。