Redis
2023-08-30 16:57:41 0 举报
Redis学习
作者其他创作
大纲/内容
NoSQL
关系型数据库
列+行,同一个表下数据的结构是一样的
非关系型数据库
数据存储没有固定的格式,并且可以进行横向扩展
NoSQL泛指非关系型数据库
Redis概念
Redis = Remote Dictionary Server,即远程字典服务
开源的使用ANSI C语言编写
支持网络、可基于内存亦可持久化的日志型
Key-Value数据库,并提供多种语言的API
与memcached一样,为了保证效率,数据都是缓存在内存中
区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件
并且在此基础上实现了master-slave(主从)同步
基本数据类型
String 字符串 key-value
String类型是redis的最基础的数据结构
String 类型的值最大能存储 512MB
可以支持各种子字符串
使用场景
缓存功能
利用redis作为缓存,配合其它数据库作为存储层
利用redis支持高并发的特点,可以大大加快系统的读写速度
降低后端数据库的压力
计数器
许多系统都会使用redis作为系统的实时计数器,可以快速实现计数和查询的功能
最终的数据结果可以按照特定的时间落地到数据库或者其它存储介质当中进行永久保存
统计多单位的数量
eg,uid:gongming count:0 根据不同的uid更新count数量
共享用户session
List 有序双端列表
list类型是用来存储多个有序的字符串的
一个列表当中可以存储有一个或者多个元素,redis的list支持存储2^32次方-1个元素
redis可以从列表的两端进行插入(pubsh)和弹出(pop)元素
或者读取指定下标的元素等操作
redis列表是一种比较灵活的链表数据结构,它可以充当队列或者栈的角色
redis列表是链表型的数据结构,所以它的元素是有序的,而且列表内的元素是可以重复的
使用场景
消息队列:reids的链表结构,可以轻松实现阻塞队列
文章列表或者数据分页展示的应用
Hash 字典 value json
键值对形式
用户信息、关系数据库的数据,value存储数据库记录
Set 无序不重复
redis集合(set)类型和list列表类型类似,都可以用来存储多个字符串元素的集合。
set集合当中不允许重复的元素,无序,set类型是使用哈希表构造的,持多个集合间的交集、并集、差集操作
去重、赞、踩、共同好友等
Zset 有序不重复含分数
有序无重复集合,增加分数,重复分数+1,用于统计重复量
访问量排行榜、点击量排行榜等
HyperLogLog 基数统计
不存储元素的值,它使用的是概率算法,通过存储元素的hash值的第一个1的位置,来计算元素数量
HyperLogLog 可用极小空间完成独立数统计
算法的核心思想是基于哈希函数和位运算,通过将哈希值转换成比特流并统计前导0的个数,从而快速估算大型数据集中唯一值的数量
应用场景
不同IP访问量
GEO 地理空间
要用于存储地理位置信息,并对存储的信息进行操作
Redis支持将Geo信息存储到有序集合(zset)中,再通过Geohash算法进行填充
应用场景
附件的人
附件元素距离排序
Bitmap 位图
其实也就是字节数组(byte array)
用一串连续的2进制数字(0或1)表示,每一位所在的位置为偏移(offset)
位图就是用每一个二进制位来存放或者标记某个元素对应的值
通常是用来判断某个数据存不存在的
因为是用bit为单位来存储所以Bitmap本身会极大的节省储存空间
应用场景
用户在线状态
用户签到状态
统计独立用户
BloomFilter(布隆过滤)
当一个元素被加入集合时,通过K个散列函数将这个元素映射成一个位数组中的K个点
使用多个哈希函数对元素key (bloom中不存value) 进行哈希,算出一个整数索引值,然后对位数组长度进行取模运算得到一个位置
每个无偏哈希函数都会得到一个不同的位置
把它们置为1,存在可能不存在,不存在一定不存在
应用场景
解决缓存穿透
黑名单校验
web拦截器
底层数据结构
SDS结构体(简单动态字符)
结构图
低复杂度获取字符串长度:由于len存在,可以直接查出字符串长度
避免缓冲区溢出,len检查内存空间是否满足需求
减少修改字符串的内存重新分配次数
空间预分配
SDS 被修改后,程序不仅会为 SDS 分配所需要的必须空间,还会分配额外的未使用空间
惰性空间释放
当对 SDS 进行缩短操作时,程序并不会回收多余的内存空间
而是使用 free 字段将这些字节数量记录下来不释放
后面如果需要 append 操作
则直接使用 free 中未使用的空间,减少了内存的分配
hash表(字典)
结构图
Redis 整体就是一个 哈希表来保存所有的键值对
哈希表,本质就是一个数组,每个元素被叫做哈希桶
不管什么数据类型,每个桶里面的 entry 保存着实际具体值的指针
整个数据库就是一个全局哈希表,而哈希表的时间复杂度是 O(1)
只需要计算每个键的哈希值,便知道对应的哈希桶位置
定位桶里面的 entry 找到对应数据,这个也是 Redis 快的原因之一
Redis 通过链式哈希解决冲突,链表过长,rehash,新建hash减少冲突
linkedList(双端列表)
结构
后续版本对linkedList数据结构,进行了改造,使用 quicklist 代替了 ziplist 和 linkedlist
zipList(压缩列表)
结构
压缩列表是 List 、hash、 sorted Set 三种数据类型底层实现之一
当一个列表只有少量数据的时候,并且每个列表项要么就是小整数值
要么就是长度比较短的字符串
那么 Redis 就会使用压缩列表来做列表键的底层实现
一系列特殊编码的连续内存块组成的顺序型的数据结构
ziplist 中可以包含多个 entry 节点,每个节点可以存放整数或者字符串
表头有三个字段 zlbytes(占用字节数)、zltail(列表尾的偏移量) ,zllen(列表格数),zlend(列表尾部)
skipList(跳跃表)
结构图
sorted set 类型的排序功能便是通过「跳跃列表」数据结构来实现
跳跃表(skiplist)是一种有序数据结构
它通过在每个节点中维持多个指向其他节点的指针,从而达到快速访问节点的目的
intset(整数数组)
当一个集合只包含整数值元素,并且这个集合的元素数量不多时,Redis 就会使用整数集合作为集合键的底层实现,节省内存
编码方式,集合包含的元素量,保存元素数组
持久化机制
RDB模式(内存快照)
是指用数据集快照的方式半持久化模式记录 Redis 数据库的所有键值对
在某个时间点将数据写入一个临时文件,持久化结束后
用这个临时文件替换上次持久化的文件,达到数据恢复
优点
RDB快照是一个压缩过的非常紧凑的文件。保存着某个时间点的数据集,适合做数据的备份,灾难恢复
可最大化Redis的的性能。在保存RDB文件,服务器进程只需要fork一个子进程来完成RDB文件创建,父进程不需要做IO操作
与AOF相比,恢复大数据集的时候会更快
缺点
RDB的数据安全性是不如AOF的,保存整个数据集的过程是比繁重的,根据配置可能要几分钟才快照一次,如果服务器宕机,那么就可能丢失几分钟的数据
Redis数据集较大时,fork的子进程要完成快照会比较耗CPU、耗时
流程
创建
当 Redis 持久化时,程序会将当前内存中的数据库状态保存到磁盘中
载入
服务器在载入 RDB 文件期间,会一直处于阻塞状态,直到载入工作完成为止。
自动保存
可通过配置文件对 Redis 进行设置, 让它在“ N 秒内数据集至少有 M 个改动”这一条件被满足时, 自动进行数据集保存操作
AOF模式(日志追加)
是指所有的命令行记录以 Redis 命令请求协议的格式完全持久化存储保存为 aof 文件
Redis 是先执行命令,把数据写入内存,然后才记录日志
因为该模式是只追加的方式,所以没有任何磁盘寻址的开销,所以很快
有点像 Mysql 中的binlog,AOF更适合做热备
优点
数据更完整,安全性更高,秒级数据丢失(取决fsync策略,如果是everysec,最多丢失1秒的数据)
AOF文件是一个只进行追加的日志文件,且写入操作是以Redis协议的格式保存的,内容是可读的,适合误删紧急恢复
缺点
对于相同的数据集,AOF文件的体积要大于RDB文件,数据恢复也会比较慢
根据所使用的fsync策略,AOF的速度可能会慢于RDB。 不过在一般情况下,每秒fsync的性能依然非常高
流程
命令追加,协议格式将被执行的写命令追加到服务器状态的 aof_buf 缓冲区的末尾
文件同步,首先判断是否写入文件
数据加载,使用伪客户端重新读取命令
文件重写,新建文件,追加新命令
过期策略
过期策略用于处理过期缓存数据。Redis采用过期策略:惰性删除 + 定期删除
定时过期
key设置有效期
惰性过期
访问时判断key是否过期,是则删除
未被访问时 会导致遗留大量过期key
定期+过期
每隔一定的时间,会扫描一定数量的数据库的expires字典中一定数量的key,并清除其中已过期的key
淘汰策略
当Redis内存快耗尽时,Redis会启动内存淘汰机制,将部分key清掉以腾出内存
清理缓存LRU
LRU(最近最少使用)
LFU(最近最不经常使用)
Random(随机淘汰)
TTL(过期时间)
No-Enviction(驱逐)
哨兵机制
主要作用
监控:Sentinel 会不断的检查主服务器和从服务器是否正常运行
通知:当被监控的某个Redis服务器出现问题,Sentinel通过API脚本向管理员或者其他的应用程序发送通知
自动故障转移:当主节点不能正常工作时,指向新的可用从节点,设为主节点
分区集群
使用key进行分片算法,路由对应的节点
范围算法
hash算法
主从模式
主写从读
0 条评论
下一页