- 是一个开源的key-value存储系统
- 支持持久化
- 一般作为缓存
- 支持多种数据类型
- 操作都是原子性的(单线程中,能够在单条指令完成的操作都是原子操作,因为中断只能发生在指令之间 多线程中,不能被其他线程或进程打断的操作为原子操作)
- 支持不同方式排序
- 可以实现主从同步
- 默认端口号6379(merz)
- 默认16个数据库,初始默认使用0号库
-
Redis 为什么快(有待完善)
单线程
-
数据结构(value)类型
String
最基本的类型,一个key对应一个value
- 二进制安全,可以包含任意数据,例如图片等
- 最多512M
- 数据结构
- 简单动态字符串,可以修改,内部结构实现类似ArrayList,采用预分配冗余空间的方式减少内存的频繁分配
- 实际分配的capacity一般都大于实际字符串长度len, 当字符串长度<1M时,都是加倍现有长度,超过1M则只会多扩1M
应用场景
单键多值,是简单的字符串链表
- 底层双向链表
- 数据结构
- quickList、ziplist
- 数据元素较少时是ziplist(它将所有的元素紧挨着一起存储,分配的是一块连续内存,数据较多时变成qiuckList(多个zipList前后相连的双向链表)
应用场景
类似于没有重复的列表
- 无序集合,底层是一个value为null的hash表
- 数据结构dict字典(hash表实现)
应用场景
键值对集合,适用于存储对象
- 数据结构
- ziplist(key-value较短且个数较少的时候)
- hashtable
应用场景
没有重复元素
- 每个成员都关联了一个评分,根据评分从最低分到最高排序
- 集合的成员唯一,评分可以重复
- 底层结构:
- hash,作用是关联元素value和score,保证value的唯一性,可以通过value找到相应的score
- 跳跃表:目的是给元素vaLue排序,根据score的范围获取元素列表
应用场景
- 根据商品销量进行排序显示
- 抖音热搜
bitmap
位图,是一个以位为单位的数组,数组中只能存储1或0,数组的下标在Bitmap中叫做偏移量。Bitmap实现统计功能,更省空间。面试中常问的布隆过滤器就有用到这种数据结构,布隆过滤器可以判断出哪些数据一定不在数据库中,所以常被用来解决Redis缓存穿透问题。Stream
Stream 实际上是一个具有消息发布/订阅功能的组件,也就常说的消息队列
Strean 除了拥有很高的性能和内存利用率外, 它最大的特点就是提供了消息的持久化存储,以及主从复制功能,从而解决了网络断开、Redis 宕机情况下,消息丢失的问题,即便是重启 Redis,存储的内容也会存在HyperLogLog
HyperLogLog是一种算法,并非redis独有
- 目的是做基数统计,故不是集合,不会保存元数据,只记录数量而不是数值。
- 耗空间极小,支持输入非常体积的数据量
- 核心是基数估算算法,主要表现为计算时内存的使用和数据合并的处理。最终数值存在一定误差
- redis中每个hyperloglog key占用了12K的内存用于标记基数(官方文档)
- pfadd命令并不会一次性分配12k内存,而是随着基数的增加而逐渐增加内存分配;而pfmerge操作则会将sourcekey合并后存储在12k大小的key中,这由hyperloglog合并操作的原理(两个hyperloglog合并时需要单独比较每个桶的值)可以很容易理解。
- 误差说明:基数估计的结果是一个带有 0.81% 标准错误(standard error)的近似值。是可接受的范围
Redis 对 HyperLogLog 的存储进行了优化,在计数比较小时,它的存储空间采用稀疏矩阵存储,空间占用很小,仅仅在计数慢慢变大,稀疏矩阵占用空间渐渐超过了阈值时才会一次性转变成稠密矩阵,才会占用 12k 的空间
GEO
Redis GEO 主要用于存储地理位置信息,并对存储的信息进行操作,
事务
redis事务是一个单独的隔离操作,事务中的所有命令都会序列化按顺序执行,执行过程中,不会被其他客户端发来的命令请求所打断
- 主要作用是串联多个命令,防止别的命令插队
- 输入multi开始组队,输入的命令会进入到队列中,不会执行,直到输入exec,redis会将命令队列里的命令依次执行,输入discard可以放弃组队
- 组队时出错,整个队列取消
-
锁
悲观锁
乐观锁
拿数据时不上锁,更新的时候去判断有没有更新
可以使用版本号等机制,适用于多读的应用场景持久化
RDB
在指定的时间间隔内,将内存中的数据集快照写入磁盘
- 当Redis重启时,RDB程序会通过重载RDB文件来还原数据库
- redis会单独创建一个子线程来持久化,会将数据写入到一个临时文件,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件。整个过程,主进程是不进行任何IO操作的,这就确保了性能,如果需要大规模的数据恢复,且对数据恢复的完整性不是非常敏感的,那RDB比aof高效
- 优势
- 适合大规模的数据恢复
- 对数据完整性和一致性要求不高更适合使用
- 节省磁盘空间
- 恢复速度快
劣势
以日志的形式来记录每个写操作,将redis所有写指令记录下来(读操作不记录),只许追加文件但不可以改写文件
- 优势
- 备份机制更稳健,丢失数据概率低
- 可读的日志文本,通过操作aof文件,可以处理误操作
- 劣势
- 比起rdb占用更多的磁盘空间
- 恢复备份速度要慢
- 每次读写都同步,有一定的性能压力
- 存在个别bug,造成恢复不能
- 默认不开启
- AOF和RDB同时开启,系统默认取aof的数据
- redis启动之初会重新读取该文件重新构建数据库,换言之,redis重启的话,就根据日志文件的内容,将写指令从头到尾执行一次完成数据恢复工作
可以都开启
对数据不敏感可以rdb
不建议单独aof,可能有bug
纯内存缓存,可以都不用
缓存穿透
访问缓存和数据库都不存在的数据
