Redis
2021-07-10 20:06:25 0 举报
AI智能生成
登录查看完整内容
Redis知识点总结
作者其他创作
大纲/内容
Redis
Redis 技术是如何诞生的
磁盘
寻址
毫秒级
带宽
I/O瓶颈
内存
纳秒级
数据库
data page
4K
索引
指向关系,指向每一个符合的data page
数据越大,索引越大
B+ 树
树干存储在内存中
区间
叶子存储在磁盘中
具体数据
检索过程
where 条件命中索引
通过 B+ 树的树干
找到磁盘中对应的数据
将数据加载到内存
存储
索引和数据都存储在磁盘中
内存中只存储索引的一些树干
最终目的
减少I/O
减少寻址
效率
前提数据量很大
增删改慢
查询快
scheam
在建表时给出
每个表有多少列
每一列的约束
存储数据时更倾向于行级存储
使用空位占位
增删改不需要移动数据
直接复写
开源的内存的数据结构存储系统
可以用作数据库、缓存和消息中间件
默认有16个库
可达每秒10W级别操作
是二进制安全的
以 key:value存储数据
Redis 安装
下载 Redis 源码包
解压源码包
安装 gcc
对解压后的文件进行编译
安装 Redis 服务
IO 模型
BIO
概述
是阻塞式IO模型
每个链接使用一个线程处理
一个线程的成本默认是1M
弊端
线程多了调度成本变高
线程多了内存成本也会变高
对系统资源会造成浪费
NIO
同步非阻塞式IO模型
一个线程可以处理多个连接
原理实现
使用一个线程轮询调用内核态中的 read
轮询发生在在User空间
每一个连接都需要调用Kernel系统调用
成本增加
IO多路复用
同步非阻塞IO模型
搓个连接使用一个线程处理
调用Kernel的select系统调用查找可用的文件描述符
然后调用read读取数据
存在从Kernel拷贝数据到User的问题
Kernel和到User传输数据成本变高
epoll
epoll内部有三个系统调用
使用共享内存空间mmap
共享内存空间中维护了一个红黑树
连接注册在红黑树中
增删改由内核完成
数据类型
string
字符串数据类型
几种表现形式
字符串形式
APPEND
在value后追加
GET
获取对应key的value
GETRANGE
获取value的部分值
GETSET
返回旧值设置新值
SETRANGE
在key的指定位置处覆盖
SET
设置值
MSET
设置多个值
MGET
获取多个值
STRLEN
获取对应key的value的长度
数值形式
INCR
INCRBY
DECR
DECRBY
INCRBYFLOAT
将值加上指定的小数
MSETNX
仅当 key 存在时才能设置 value,可以设置多个
PSETEX
设置密钥的值和有效期限(以毫秒为单位)
应用场景
抢购、秒杀
点赞,评论,看似不是很重要的数据
详情页,规避并发下对数据库的事务操作,完全有 Redis 内存操作代替
bitmaps 形式
SETBIT
设置或清除键处存储的字符串值中偏移量的位
BITPOS
查找第一个二进制位在字符串中那个位置,返回二进制位的偏移量
BITCOUNT
在给定的范围内二进制位为1出现的次数
BITOP
参与的 key 会触发二进制位的逻辑操做,与或非、异或
用户系统,统计用户的登录天数,且窗口随机
做活动送礼物,假设有2E用户,需要备多少货,活跃用户统计
list
在 key 中有 head 和 tail 两个头尾指针
快速的访问链表中的第一个元素和最后一个元素
如果使用索引操做 list 类型的数据,可以表示数组数据结构
命令
LPUSH
向链表中添加元素,丛左边向链表中推送
RPUSH
链表中添加元素,丛右边向链表中推送
LPOP
删除并返回链表中第一个元素
RPOP
删除并返回链表中最后一个元素
LRANGE
查看链表中所有的元素
LINDEX
根据指定索引获取链表中元素
LSET
根据给定的值更新到指定索引位置
LREM
删除链表中给定个数的元素
LINSERT
在链表中已存在的元素之前或之后插入一个元素
LLEN
获取链表中共有多少个元素
BLPOP
删除并获取链表中的第一个元素,阻塞获取,直到一个可用
BRPOP
删除并获取链表中最后一个元素,阻塞获取,直到一个可用
BRPOPLPUSH
从一个队列中删除一个元素并将其推到另一个队列中,阻塞获取,知道一个可用
LTRIM
保留给定区间的元素,删除给定区间两端的元素
LPUSHX
仅当列表存在时,才将元素添加到列表中
RPOPLPUSH
删除列表中的最后一个元素,将其添加到另一个列表中并返回
RPUSHX
仅当列表存在时,将元素追加到列表
同向命令可以描述栈(LIFO)数据结构逆向命令可以描述队列(FIFO)数据结构
可以描述一个简单的阻塞队列数据结构,或者是单播队列(FIFO)
hashs
在键值对中的 value 也是一个键值对
HDEL
删除 key 对应的一个或多个哈希字段
HEXISTS
确定是否存在哈希字段
HGET
在哈希字段中获取值
HGETALL
在哈希中获取多有的字段和值
HINCRBY
将哈希字段的整数值增加给定数字
HINCRBYFLOAT
将哈希字段的浮点值增加给定数量
HKEYS
获取所有的哈希字段
HLEN
获取哈希中的字段数
HMGET
获取所有给定哈希字段的值
HMSET
将多个哈希字段设置为多个值
HSCAN
递增迭代哈希字段和关联的值
HSET
设置哈希字段的字符串值
HSETNX
设置哈希字段的值(仅当该字段不存在时)
HSTRLEN
获取哈希字段值的长度
HVALS
获取哈希中的所有值
点赞
收藏
详情页
set
与list的区别
list 元素是可以有重复出现的
list 是有序的,这个顺序是存入和弹出的顺序
set去重的集合,也就是元素是不可以重复的
set 是无序的
SADD
将一个或多个成员添加到集合中
SCARD
获取集合中成员的个数
SDIFF
多个集合的差集
SDIFFSTORE
多个集合的差集并将结果集合存储在一个 key 中
SINTER
相交多个集合
SINTERSTORE
相交多个集合并将结果集合存储在一个 key 中
SISMEMBER
确定给定值是否是集合的成员
SMEMBERS
获取集合中的所有成员
SMOVE
将成员从一集合移到另一集合
SPOP
从集合中删除并返回一个或多个随机成员
SRANDMEMBER
从集合中获取一个或多个随机成员
SREM
从集合中删除一个或多个成员
SSCAN
递增迭代集合元素
SUNION
多个集合的并集
SUNIONSTORE
多个集合的并集并将结果集存储在一个 key 中
store_set
元素数据去重,且排序
内部维度
元素 member
它是一个 set 集合
分值 score
如果所有元素的分值设置为 1,是按照名称的字典序排序
索引 index
正负索引
底层实现
底层使用 skip list 实现
ZADD
获取排序集中的成员数
ZCOUNT
用给定值内的分数对排序集中的成员进行计数
ZINCRBY
增加排序集中成员的分数
ZINTERSTORE
与多个排序集相交并将结果排序后的集存储在一个 key 中
ZLEXCOUNT
计算给定分值范围之间的排序集中的成员数
ZPOPMAX
删除并返回排序集中得分最高的成员
ZPOPMIN
删除并返回排序集中得分最低的成员
ZRANGE
按索引返回排序集中的成员范围
ZRANGEBYLEX
返回按字典顺序排列的一组排序范围内的成员
ZRANGEBYSCORE
按分数返回排序集中的成员范围
ZRANK
确定排序集中成员的索引
ZREM
从排序集中删除一个或多个成员
ZREMRANGEBYLEX
删除给定分值范围之间的排序集中的所有成员
ZREMRANGEBYRANK
删除给定索引内排序集中的所有成员
ZREMRANGEBYSCORE
在给定分数内删除排序集中的所有成员
ZREVRANGE
按索引返回排序集中的一组成员,其得分从高到低排序
ZREVRANGEBYLEX
返回按字典顺序排列的一组排序范围内的成员范围,按从高到低的字符串排序。
ZREVRANGEBYSCORE
按分数返回排序集中的一组成员,分数从高到低排序
ZREVRANK
确定成员在排序集中的索引,其得分从高到低排序
ZSCAN
增量迭代排序的集合元素和相关分数
ZSCORE
获取排序集中与给定成员相关的分数
ZUNIONSTORE
添加多个排序集并将结果排序集存储在新密钥中
BZPOPMAX
从一个或多个排序集中删除得分最高的成员,或者将其阻塞直到一个可用
BZPOPMIN
从一个或多个排序集中删除得分最低的成员,或者将其阻塞,直到一个可用为止
关联知识
正反索引
Reids中有正反两种索引
正向索引是从0开始,从前向后
反向索引是从-1开始,从后向前
Key
value
encoding
二进制安全
客户端给 Redis 的数据永远都是二进制数组
Redis 底层按照字节去存储数据
管道
一次发送多个命令,节省往返时间
将通信的成本变低
发布/订阅
不需要知道有什么样的发布者和订阅者
解耦
PSUBSCRIBE
收听发布到与给定模式匹配的频道的消息
PUBLISH
将消息发布到频道
PUBSUB
检查发布/订阅子系统的状态
PUNSUBSCRIBE
停止收听发布到与给定模式匹配的频道的消息
SUBSCRIBE
收听发布到给定频道的消息
UNSUBSCRIBE
停止收听发布到给定频道的消息
注意
订阅者需要先订阅频道,发布者在发布消息的时候再能收到
事务
事务可以一次执行多个命令
带有以下两个重要的保证
事务是一个单独的隔离操作
事务是一个原子操作
EXEC 命令
负责触发并执行事务中的所有命令
Redis 是单进程的,所有的命令像是排队执行的。谁先调用 exec 谁先执行
用法
MULTI 命令用于开启一个事务,它总是返回 OK
MULTI 执行之后, 客户端可以继续向服务器发送任意多条命令, 这些命令不会立即被执行, 而是被放到一个队列中
当 EXEC命令被调用时, 所有队列中的命令才会被执行
通过调用 DISCARD , 客户端可以清空事务队列, 并放弃执行事务
Modules
Redis 除了自己本身的功能之外,还可以添加一些扩展库来增加 Redis 的功能
RedisBloom
布隆过滤器是概率的
Bloom 可以解决缓存穿透问题
优点
使用小的空间解决大量数据匹配的过程
使用
使用二进制位数组标记商品信息
缓存穿透
持久化
持久化的场景
Redis作为缓存
数据不一定是100%可靠的,缓存挂了,重启服务时数据是否恢复
Redis作为数据库
数据是不可丢失的,持久性
持久化的两种方式
快照/副本
Redis将数据从内存移到磁盘
日志
在发生写操作时,记录每一个操作,服务故障重启时,可执行恢复数据
RDB
以快照/副本的形式持久化数据,Redis默认开启
特点
快照/副本这类数据的持久化
可靠性保证是时点性的
两种方式
阻塞
Redis不对外提供服务,将数据直接写入到磁盘,是正确的时点
非阻塞
Redis对外提供服务,一边提供服务,一边将数据持久化到磁盘,时点混乱
实现
通过调用fork系统调用创建子进程,对数据进行持久化
fork的实现原理
创建一个子进程
将父进程指向的物理内存指针复制一份
在父进程中数据发生改变时通过写时复制来解决父进程中数据发生改变
最终实现数据互不影响
save
触发前台阻塞
使用场景
关机维护
bgsave
后端非阻塞,触发 fork,创建子进程
正常情况下几乎都使用此模式
配置文件
配置save标识,触发的是bgsave
注意:
不可能每秒都触发 RDB,I/O成本太高
不支持拉链
丢失数据相对多
将内存中的字节数组,以最快的序列化方式将数据直接放到磁盘中,恢复也是直接恢复。
恢复的速度相对快。
AOF
相当于使用日志的形式持久化数据
只会向文件追加,追加的数据就是服务器发生的写操作
丢失数据相对少
RDB 和 AOF 可以同时开启
如果开启了 AOF,只会使用 AOF 恢复数据,数据的完整性好
4.0 版本之后,AOF 中包含 RDB 全量,增加记录新的写操作
体量无线变大,恢复慢
4.0 之前:重写,删除抵消的命令和合并重复的命令
4.0 之后:重写,将老的文件 RDB 到 AOF 文件中,将增量的以指令的方式 Append 到 AOF
AOF 是一个混合体,利用了 RDB 的快,利用了日志的全量
I/O的三个级别
no
不调用Kernel的刷新
将决定权交给Kernel
会丢失一部分数据
always
发生写操作就调用刷新
数据最可靠
最多丢失数据量是几条数据
everysec
一秒钟调用一次刷新
最大丢失数据量是接近一个 Buffer
这是一种概率
no-appendfsync-on-rewrite no 配置项
Redis 集群
单机存在的问题
单点故障,无法提供服务
容量有限
压力
Socket
I/O
CPU 操作
AFK 拆分原则
拆分原则
X 轴
主备模式
全量、镜像
会造成机器的浪费
可以使用读写分离
Y 轴
业务或功能
按照功能或业务拆分
解决单点故障要依赖于 X 轴的主备
Z 轴
多主多备
按照优先级、逻辑拆分
将数据分段存储
拆分带来的问题
数据一致性
高可用性
分区容错性
CAP 原则
强一致性
弱一致性
最终一致性
在主备之间使用类消息中间件的服务
存在脏读的问题
实现的模式
主从模式
客户端可以访问主服务,同时也可以访问从服务。
就是主服务挂了,访问备服务,在主服务正常运行时,不会使用备服务。
Reids 中两种模式都实现了
使用更多的是:主从复制
强调当主服务挂掉之后,会有一个新的主服务出现,对外无感知,自动故障转移。
脑裂
允不允许有一部分的数据丢失
以上三个要素最多同时实现两点,不可能三者兼顾
哨兵
自身也应当是集群的
数据一致性问题
单机存在单点故障问题
作用:
监控Redis服务
自动切换主服务
故障切换
决策
当有过半数的哨兵表示主服务不可用,那么切换主服务
一般监控服务使用奇数台
容忍度
偶数台比奇数台更容易出现故障
Reids 实现集群
默认是异步复制
其主要目的是快
默认从服务器是禁止写入的,配置文件可修改。
0 条评论
回复 删除
下一页