1.redis的单线程模型:redis采用单线程处理网络请求,基于IO多路复用提升网络处理的速度(redis的性能瓶颈不在cpu,主要是受制于内存的大小)
2.redis基本数据结构:String,Hash,List,Set,Zset
String: 底层为int或者SDS(512M),能自动扩容缩容
优点:解决缓冲区溢出问题,预分配和惰性释放防止频繁操作内存,二进制安全
struct sdshdr{
//记录buf数组中已使用字节的长度
int len;
//记录buf数组中剩余空间的长度
int free;
//字节数组,用于存储字符串
char buf[]; };
List:底层为ziplist或者linkedlist
优点:可以模仿队列,栈数据结构
Hash: 底层为ziplist或者hashtable(渐进式rehash)
Set: 底层为intset或者hashtable
ZSet:ziplist或者skiplist
优点:跳跃链表的设计可以很好滴平衡时间和空间问题
3。redis的持久化方案:AOF和RDB
RDB:优点:体积小,对redis性能影响较小,恢复数据比较快,适合用于灾备,缺点:可能会丢失一部分数据
AOF:优点:秒级数据丢失(取决于appendfsync策略),易读,缺点:会影响一定性能,文件增长较快,需要重写AOF文件,需要重写缓冲区等保障数据安全
redis后面出了混合存储方式,混合使用的方式使得内存快照不必频繁的执行,并且AOF记录的也不是全部的操作命令,而是两次快照之间的操作命令,不会出现AOF日志文件过大的情况了,避免了AOF重写的开销了
4.内存过期策略和内存淘汰机制
内存过期:定期删除+惰性删除
内存淘汰: noeviction:当内存不足以容纳新写入数据时,新写入操作会报错。默认策略
allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key。
allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个key。
volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的key。
volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个key。
volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的key优先移除
5.redis缓存常见问题: 缓存穿透(布隆过滤器,缓存null的key),
缓存击穿(对热点key,加互斥锁,或者不设置过期时间,缓存预热),
缓存雪崩(过期时间设置随机,防止同一时间大量数据过期现象发生),
双写不一致(使用redis作为缓存时,可能会出现缓存是旧值,数据库是新值):(待完善,缓存数据库不一致问题讨论) 更新策略为 先删除缓存,再更新数据库 用一次缓存miss的代价来避免其他问题, 1.例如先更新缓存,再存数据库,更新失败导致缓存数据出现脏读 2.两个线程同时更新数据库,网络原因无法判断缓存哪个线程的数据,导致不一致问题 3.
6.redis架构:主从哨兵模式,codis模式,cluster模式
=======redis高级特性
7.HyperLogLog--统计用户访问量:(统计ip访问量去重)
pfadd key value1 //新增一个元素(key value) pfadd key value2 //新增一个元素(key value) pfadd key value3 //新增一个元素(key value) pfadd key value3 //新增一个元素(key value) pfadd key value4 value5 value6 value7 //新增多个元素(key value4 value5 value6 value7) pfcount key //统计该key去重后的元素个数(返回7)
pfmerge key1 key2 //将两个key合并,用于统计两个网站访问量的总大小