Redis基础知识
五大数据类型
String、Set、List、Hash、Zset(有序集合)
-
String类型是二进制安全的。意味着String可以包含任何数据。String类型最多可以是512M
- 其中Redis里面的操作都是原子操作,因为Redis是单线程+多路IO复用机制。单线程都是原子操作。
- String的数据结构为简单动态字符串,内部结构实现上类似于Java的ArrayList,采用预分配冗余空间的方式来减少内存的频繁分配
-
List类型是单键多值,底层是个双向链表,两端操作效率高,通过索引下标的操作效率低
- List的数据结构为快速链表quicklist
- 在列表元素较少的情况下会使用一块连续的内存存储,结构为ziplist。数量较多时改为quicklist。Redis将链表和ziplist结合起来,满足了快速插入删除性能,又不会出现太大的空间冗余。
-
Set类型是String类型的无序集合。底层是一个value为null的hash表。
- 对外提供的功能与list类似,特殊之处在于可以自动重排。当需要存储一个列表数据,又不希望出现重复数据是,set是一个很好选择。添加,删除,查找的复杂度都是O(1)。
- Set数据结构是字典,字典是hash表实现的,所有的value都指向同一个内部值。
-
Hash是一个string类型的field和value的映射表,hash适合用于存储对象。
-
通过key+field操作对应属性数据,既不需要重复存储数据,也不会带来序列化和并发修改控制问题。
-
Hash对应的数据结构是两种:zipset(压缩列表)和hashtable(哈希表)。field-value长度较短且个数较小时,使用zpilist,否则使用hashtable。
-
-
有序集合Zset,是一个没有重复元素的字符串集合。
- 其中每个成员关联了一个评分(score),评分用于从最低分到最高分的方式排序集合中的成员。集合的成员是唯一的,但是评分是可重复的
- Zest底层使用了两个数据结构:hash和跳跃表。hash作用是关联元素value和score,保障元素value的唯一性,通过value找到相应的score值。跳跃表的作用在于给元素value排序,根据score的范围获取元素列表
- 跳跃表:以空间换时间。与红黑树(二叉查找树)比较,跳跃表的优点是维持结构平衡的成本比较低,完全依靠随机。而二叉查找树在多次插入删除后,需要rebalance来重新调整结构平衡。
发布订阅
- 发布Publish 订阅subscription 是一种消息通信模式
Redis新数据类型
-
Bitmaps
进行位操作 数组下标再bitmaps中叫做偏移量
节约空间,提升运行。但不适合与网站的独立访问量少的。
-
HyperLogLog
基数统计算法。
-
Geospatial
经纬度,地理位置操作。
Redis事务操作
-
事务定义
序列化,串联多任务命令,防止插队
-
Multi、Exec、discard
Multi组队执行,Exec执行阶段,discard停止执行
-
事务的错误处理
-
事务冲突的问题
悲观锁、乐观锁
乐观锁,操作过程:在执行multi之前,先执行watch key,可以监视一个或多个key,如果在事务执行之前监测到key被其他命令所改动,则事务将被打断
-
Redis事务三特性
单独的隔离操作、没有隔离级别的概念、不保证原子性
Redis持久化RDB
在指定时间间隔内将内存中的数据集快照写入磁盘,恢复时将快照文件直接读取到内存里。
RDB缺点是最后一次持久化后的数据可能丢失。
Redis持久化AOF
以日志的形式记录每个写操作,将Redis执行过的所有指令记录下来(读操作不记录),只许追加文件但不可以改写文件。
Redis主从复制
Redis集群
Redis应用问题解决
-
缓存穿透
问题出现:缓存和数据库中都没有数据,用户不断发起请求,从而导致大量请求访问直接数据库导致应用服务器压力过大
解决方案:
-
采用布隆缓冲器:用于检查一个元素是否在一个集合中。将所有可能存在的数据哈希到一个足够大的bitmaps中,一个一定不存在的数据会被这个bitmaps拦截掉,从而避免了对底层存储系统的查询压力。
缺点:有一定的识别率和删除困难
-
-
缓存击穿
问题出现:redis某个key过期,大量的访问这个key,导致数据库访问压力瞬时增加
解决方案:缓存预热、设置随机的过期时间,使用锁
-
缓存雪崩
问题出现:极少时间段,大量key集中过期。
解决方案:
- 锁或则队列
- 设置过期标志更新缓存
- 将缓存失效时间分散开
-
分布式锁
上锁同时设置过期时间,实现原子操作