1.为什么用缓存?
使用缓存主要原因:
1.高性能:查DB比较慢,读缓存更快,提高系统性能
2.高并发:
mysql 单机支撑到 2000QPS 也开始容易报警,缓存走内存,内存天然支持高并发,单机支撑的并发量轻松一秒几万十几万
2.单线程?
Redis优化成了多线程?实际只是对io操作的优化。
Redis 的多线程部分只是用来处理网络数据的读写和协议解析,执行命令仍然是单线程。
多线程的优化只涉及io,参考NIO模型,而内存还是基于单线程操作,官方的两个原因:
1.Redis基本上基于内存操作,并不需要什么io操作,并且cpu不是Redis的性能瓶颈
2.为简化操作,防止产生并发问题
3.Redis的数据结构
参考:
Redis 都有哪些数据类型?分别在哪些场景下使用比较合适?
基本的5种数据结构:String,Hash,Set,Zset,List
String:普通键值对
Hash:需要存储一些结构化数据的时候可以考虑用Hash
Set:去重,考虑并集、差集、交集等(共同好友之类的)
Zset:去重并排序(做排名)
List:有序列表,还能实现分页(分页评论、消息队列有序消息之类)
参考:
Redis 中的5种特殊的数据结构 bitmap,hyperLogLog,bloomFilter,GeoHash,Stream
扩展类型:
BloomFilter:布隆过滤器
通过多次hash初步判断所查数据是否存在
set时对key多次hash,将hash值所在的位置置为1;查询的时候对key进行多次hash若所有位置都为1则可能存在,若有为0的肯定不存在(有一定的误差,但是已经能解决大部分问题了,并且十分节省空间!使用传统set放不下大量数据)
场景:网站去重,垃圾邮件过滤,缓存穿透
HyperLogLog
也会存在误差,去重误差值在0.81%左右,但只占12KB内存
场景:计算某网页UV,数据量非常大,几百万几千万,若用set非常占空间,HyperLogLog可以去重并计数,虽然有点误差但完全可以接受
原理:基数计数、概率算法
参考:
HyperLogLog
HyperLogLog 算法详解
BitMap
场景:统计一年内多个用户同时在线的天数
Redis 中的 bitmap 还提供了多个 bitmap 进行与,或,异或运算的命令,当然还有单个 bitmap 的 非 运算。
GeoHash
场景:附近的人,附近的商店
原理:具体原理是将地球看成一个平面,并把二维坐标映射成一维(精度损失的原因)
Stream
消息队列
4.过期策略+淘汰机制
过期策略:定期删除+惰性删除
定期删除:默认是每隔 100ms 就随机抽取一些设置了过期时间的 key,检查其是否过期,如果过期就删除
惰性删除:获取某个 key 的时候,Redis 会检查一下 ,这个 key 如果设置了过期时间,如果过期了此时就会删除,不会返回任何东西。
内存淘汰机制:
noeviction
**allkeys-lru:**最近最少使用(实现:LinkedHashMap)
allkeys-random
volatile-lru
volatile-random
volatile-ttl