导图社区 redisredis简要思维导图
redisredis简要思维导图,一张图带你完全了解相关内容,通过思维导图帮你提高效率,赶紧来试一试吧~
编辑于2023-01-11 20:51:05 广东redis
常识
秒s>毫秒ms>微秒us>纳秒ns
磁盘
寻址:ms
带宽:G/M
内存
寻址:ns
带宽:很大
I/O buffer
成本
扇区
磁盘和磁道 一扇区 512Byte带来一个成本变大:索引4K
操作系统读取最少4k
信息系统基础设施
冯诺依曼的硬件体系
以太网 tcp/ip的网络
介绍
mysql
redis
用处
数据库
缓存
消息中间件
支持多种数据类型(特点)
基本结构key:value
String
* 字符类型 * 数值类型 * bitmaps
hashes
lists
sets
sorted sets
运行原理
单线程处理
指处理用户的对数据的操作是一个线程完成的
"顺序"性
每连接内的命令顺序
事务一致,线程安全
单个连接内的顺序需要进行注意,需要保证顺序正确
I/O
BIO
当一个文件要冲内核加载到内存的时候,进程/线程在执行内核系统调用read,socket数据包没到的时候,read阻塞状态blocking
NIO
一个线程/进程死循环一直读取socket的数据包,读不到就读取下一个,轮询的读,nonblocking,减少多线程的切换
多路复用NIO
NIO多路复用,NIO的io次数还是太高,因为如果有1000个read,那么会有1000次io,多路复用体现在批量调用内核select,一次性返回数据状态,这样线程/进程可以根据有数据的这些fd,去再次去内核拿数据read,减少io次数
epoll mmap
内核和jvm在用户空间里的一个共享空间,基于mmap读写磁盘文件不会招致系统调用以及额外的内存copy开销
同步,非阻塞多路复用
epoll(I/O模型)
运行原理
零拷贝
用户空间
共享空间(既属于用户空间,又属于内存空间)
内存空间kernel
其他实例
nginx
多少颗cpu启动多少个进程work
* 每个work用epoll
kafka
mmap(共享空间)
AIO(WIN实现)
异步非阻塞IO,目前只有win实现,linux没有实现
jvm I/O结构
JVM:一个线程的成本1M
1.线程多了调度成本CPU浪费
2.内存成本
使用
使用
默认有16个库
基本语法
set key value
select 0~15(选择0-15的库)
help (tab键查看关键字的使用)
key value
string(Byte)
字符串(常用命令)
set
get
append(添加)
setrange(修改offset)
getrange(获取offset)
strlen(获取value长度)
数值
incr(+1)
incrby(+数字)
incrbyfloat
decr(-1)
decrby(-数字)
decrbyfloat
mget(多个获取)
mset(多个设置)
字符引申
Object encoding(查看数据编码类型)
二进制安全
字节流
* 拿出去的,一个字符一个字节
字符流
* 内部转换,内部计算使用
事务
原子事务指令中如果有失败,则整条命令都失败
ASCII
getset(获取时同时修改)
bitmap
setbit offset(二进制位的偏移量,非字节的便宜量)
bitpos(找到value字符二进制二进制位的偏移量)
bitcount(统计1出现几次,二进制1的统计)
bitop(二进制位移操作的与或非,亦或计算)
list(有序,可重复)
lpush,lpop
从左往右压入数组
rpush,rpop
从右往左压入数组
lindex,rlindex
类似数组的操作
blpop
阻塞,单波队列,FIFO先进先出顺序
hash(map{k-v})
不用hash实现的例子
set stone::name 'zpq' set stone::age 31 (set对象stone的姓名和age属性).可以这么查看 keys stone*
优化,hash的命令用法
set
hset stone name zpq(hset id id属性 值),hmset
get
hget stone name(获取stone的name属性)
hmget(获取key的多个属性)
hkeys stone(获取idkey的所有键)
hvals stone (获取id key的所有值)
hgetall stone(获取idkey的所有键值对信息)
对field进行操作和计算
sort(无需,去重)
sadd
smembers,查看集合的所有元素
sinter,查看多个集合的交集
sinterstore,查看多个集合的交集并存入指定的key
sunion,并集
sunionstore
sdiff,差集,取决于key的方向,外差和内差取决于左边
srandmembers 随机元素结果集 正数取出一个去重的结果集,负数去除一个带重复的结果集,一定满足数量,如果为0 不返回
spop 取出一个(不重复)元素
sorted set(有序集)
数据结构分为,元素,分值(数字自己定义),排名(redis计算得出)
zscore k1 apple 根据value获取分值
zrank k1 apple 根据value获取排名
zrange k1 0 -1 (withscores显示分值)正向排行
zrevrange k1 0 -1 (withscores显示分值)逆向排行
底层原理
具备集合操作,并集,交集
ZUNIONSTORE unkey2 2 k1 k2 weights 1 1 aggregate max
zunionstore 交集 unkey2 保存到目的kye 2 几个集合进行交集计算 k1 k2 取交集的sortedset weights 权重 根据顺序填写(默认为1) aggregate 计算方式 (max min等等,默认为sum)
排序是如何实现的,增删改查的速度
sklip list 跳表
* 每个元素存了,链表的指针之外还存了到上一层的指针 * 插入数据之后是随机造层 * 平衡树的概念 * 增删改就是修改指针 * 牺牲存储空间换取查询的速度
物理内存左小右大,不随命令发生变化,zrange,zrevrange
redis其他用途
消息订阅
pipeline
事务
modules
布隆过滤器
缓存LRU
进阶使用
管道
通信的成本变低,多命令一次输入
例如: echo -e "set k2 99\nincr k2\n get k2" | nc localhost 6379 (使用linux的nc命令来传输给redis命令,当中用\n来断)
冷启动,大量插入数据
换行符只支持dos格式的\r\n
发布订阅
例如:实时的聊天室
help @subpub
subscribe 监听指定通道
psubscribe 发送消息,只有监听状态下另一边能够收到
事务处理
无回滚事务
按顺序执行
多个事务开启,放在不同的缓存区存储,谁先exec谁先执行
布置实例
缓存穿透
某查询缓存中没有命中,会尝试在数据库中获取,从而导致大量请求访问数据库,如果数据库中本身没有该数据,这就会导致数据库执行很多不必要的操作,增加了数据库的压力
解决方法
1.对于热点查询,设置kye-null,为其缓存空间
2.使用布隆过滤器
维护一个bimmap,布隆过滤器也可以通过客户端实现,也可以使用redis中额外应用的,bitmap可以由客户端维护,也可以由redis维护,大致是bitmap中标记已有的数据,没有的数据直接由维护的bitmap过滤掉,从而不再访问数据库,存在一定的概率误标记,但是成本会很低
redis的持久化
作为缓存/数据库的区别
数据库
重要数据
缓存
数据"不重要",不是全量数据,
缓存应该随着访问变化
热数据
key的有效期
由业务逻辑推动
业务运转淘汰冷数据,因为内存有限
lru
回收最近最少使用的(维度:时间+最少使用次数)
lfu
回收最少没用过的(维度:最少使用)
有效期不会随着访问而延长(刷新)
人工干预过期时间expire
修改值之后会剔除过期时间
redis作为缓存 怎么能随着业务变化,只保留热数据,因为内存大小是有限制的,瓶颈点
过期
主动过期
客户端访问,对比时间判断是否过期
被动过期
每10秒检测,测试20个keys进行相关过滤检测,删除所有过期的keys,如果由多于25%的key过期,重复前面的步骤
知识点
单机持久化
快照/副本
RBD
时点性
阻塞,进行快照时redis不提供其他服务
不阻塞,进行快照时仍旧提供服务
* 会有时点混乱问题 * 管道,借鉴linux的more
管道
* 衔接 前一个命令的输出会作为后一个命令的输入 * 管道会创建子进程 * $$ 高于 | * 常规思想 进程的数据是要进行隔离 * 进阶思想 父进程可以让子进程看到数据 * 子进程的修改不会影响到父进程 * 父进程的修改不会影响到子进程 * 引申问题进程的成本 * 速度 * 内存 * fork,1速度快 2空间小
save
同步,请求服务阻塞
* 关机维护
bgsave
fork创建子进程
配置文件中给出bgsave的规则:save这个标识
弊端
不支持拉链,只有一个dump.rdb,需要另外运维策略去处理
丢失数据相对多,时点与时点之间的窗口数据容易丢失
优点
类似java的序列化,恢复的速度相对快
日志
AOF
redis的写操作记录到文件中
丢失数据少
redis RDB和AOF可以同时开,
* 如果开启了AOF,只会用AOF恢复
恢复速度慢
* 4.0前 重写,命令进行合并 * 4.0后将老的RDB文件到AOF文件中,后续增量以指令的方式append到AOF * 混合体,利用了RDB的快和日志的全量
redis是内存数据库
* 写操作会触发I/O * no (最快,buffer满了再刷) * aways 每操作(速度最慢) * everysec 每秒(默认级别)
集群
单实例缺点:单点故障,容量有限,压力
AKF
概念AKF原理(X:全量,镜像 Y:每个redis存放不同模块的数据 Z:将每个业务再次进行分库,即拆分为多个redis)
主从
主和从
主备
主和备用
高可用
分布式遇到问题
主从复制
全量复制
基于长连接的命令传播
增量复制
面试(分布式协调很麻烦)
击穿
击穿概念:高并发场景下,redis缓存客户端请求的key过期,导致DB压力增大。
击穿原因:redis作为缓存使用时,存在过期时间和淘汰机制,导致访问的key可能会不存在的情况。
解决方式:设置过期时间(根据业务)
2.死锁问题(分布式)
第一个人挂了,后面阻塞住了
设置锁的过期时间
没挂,但是锁超时了
1 使用多线程,一个线程取DB
2 一个线程监控是否取回来,更新锁时间
穿透
穿透概念:从业务查询的是系统根本不存在的数据,消耗性能
布隆过滤器
客户端包含过滤器算法
算法
bitmap->redis无状态
redis继承布隆
雪崩
概念:大量的key同时失效(同时到期,例如凌晨12点过期),间接造成大量访问到DB
解决思路:随机过期时间
比如0点,避免0点
可以用强依赖击穿方案
时点性无关,时间没调好
分布式锁
1.setnx
2.过期时间
3.多线程(守护线程) 延长过期时间
举例:redission,最好用zookeeper做分布式锁
API(jedis,luttce,springboot,low/high level
Jedis
lettuce(线程安全)
Redisson
springboot中支持