常用的数据类型
- String: 最基本的类型,单个Value最大上限1G
- List: 列表(队列,栈,堆),双向链表实现,用于序列集合,不要求元素唯一,通过push/pop操作 从链表头部/尾部 添加或删除元素
- Hash: 字典,用于存储多个属于一类k-v数据(比如个人信息),多用于结构比较复杂的数据
- Set: 无序存储多个不同的元素,要求元素唯一,容量为【2的32次方-1】;除了增加删除操作还可以进行求集合的并集 差集 交集
- SortedSet: 与Set非常相似,存储字符串的集合;不同于Set,它每个元素会去关联一个浮点数类型的权重值 ,通过权重值有序的获取集合中的元素,如果权重值一样再根据元素的字节排序获取;SortedSet最常应用与排行榜的场景,比如存储所有用户,把用户积分作为权重值,按照权重顺序排列,达到用户排行的效果
需要知道的特性
-
Redis所有操作都是原子的
-
Redis key过期删除策略:
定时删除: 根据key过期时间 启动定时器删除 [主动策略,占用cpu] 惰性删除: 访问key的时候才检查有没有过期,如果有则删除 [被动策略,占用内存] 定期删除: 定期删除所有过期的key [主动策略,间隔小则占用cpu 间隔大则占用内存]
Redis-Server 默认使用 惰性删除 + 定期删除,通过配合使用这2种删除策略达到 合理使用cpu时间 和 避免内存浪费 取得很好的平衡
- Redis支持2中持久化方式:
RDB(快照,默认) ,保存redis中的所有数据到磁盘中,如果redis中的数据量很大的话不推荐使用。生产环境中基本不适用此种模式
AOF,备份所有写指令到磁盘中
Redis速度快的原因
- 完全基于内存
- 数据结构简单
- 单线程,没有切换
Redis是单线程,主要是指Redis的网络IO和键值对读写是由一个线程来完成的,但Redis的其他功能,比如持久化、异步删除、集群数据同步等,其实是由额外的线程执行的
- io多路复用模型
缓存穿透,缓存击穿,缓存雪崩
-
缓存穿透: 查询一个不存在的数据,但是由于没有命中缓存(缓存中没有),然后又去DB中查询,查询了2次造成性能下降
解决方案:
1.给没有命中的key设定 “无意义的空值”,过期时间最长不超过五分钟
2.接口层增加校验
3布隆过滤器 -
缓存击穿: 对于缓存中一些设置了过期时间的热点数据,当某一个key过期了,恰好在这个时候有大量对这个key的并发请求,由于key已经过期了,这些请求直接打到DB,可能会瞬间压垮DB
解决方案:
1.互斥锁
2.设置热点数据永不过期 -
缓存雪崩:缓存设置了相同的过期时间,导致缓存同一时间失效,请求全部打到了DB,DB的瞬时压力过大,造成雪崩。和缓存击穿的区别在于:缓存击穿针对某一key缓存,缓存雪崩则是很多key。
解决方案:
1.key设定不同的( 随机)过期时间
2.设置热点数据永远不过期
Redis的IO模型
-
每个网络链接(请求)对应一个文件描述符(即图中的FD)
-
多路复用模块:
1.Redis线程不会阻塞在某个网络链接上 2.一个线程处理多个IO流(select,epoll,kqueue,evport等机制) 3.同时监控多个文件描述符,当其中一些文件描述符可读事件或者可写事件就绪时, 这些事件会被放进一个事件队列 4.Redis线程对该事件队列进行处理(基于事件的回调): a.向事件分发器传送事件 b.事件分发器在收到事件之后,会根据事件的类型将事件分发给对应的 事件处理器(handler)
Redis线程无需一直轮询是否有网络链接(请求)关心的事件发生,这就可以避免造成CPU资源浪费。因为Redis一直在对事件队列进行处理,所以能及时响应客户端请求,提升Redis的响应性能。
参考链接: