本文记录下之前文章没记录的东西亦或者已有然后深入记录下
redis 为啥可以高并发
因为他快,他是基于内存的,不用从物理磁盘里取值,从 存储器的种类和速度拿票文章中知道,内存就是比从磁盘里快,尤其是那种机械硬盘
redis 是单线程的么
redis 不是单线程,因为他还会开启后台线程来进行关闭文件、持久化、释放 Redis 内存等操作
但是 接收客户端请求->解析请求 ->进行数据读写等操作->发送数据给客户端 这个过程是在一个线程里执行的,所以平时说的单线程是这个意思,但是这个也只是redis 6.0 之前的
redis 采用单线程为什么还这么快
- Redis 的大部分操作都在内存中完成,并且采用了高效的数据结构,因此 Redis 瓶颈可能是机器的内存或者网络带宽,而并非 CPU,既然 CPU 不是瓶颈,那么自然就采用单线程的解决方案了;
- Redis 采用单线程模型可以避免了多线程之间的竞争,省去了多线程切换带来的时间和性能上的开销,而且也不会导致死锁问题。
- Redis 采用了 I/O 多路复用机制处理大量的客户端 Socket 请求,多路复用请看 http://laiyong.wang/2022/07/14/I-O
redis 6.0 为啥引入了多线程
因为基于内存,所以 CPU 并不是制约 redis 性能表现的瓶颈所在,但是随着网络硬件的性能提升,压力那就来到了 网络 I/O 上,于是采用了多个 I/O 线程来处理网络请求
但是进行数据读写操作还是一个线程里执行的
AOF 重写机制
aof文件是追加的,会越来愈大,避免 AOF 文件越写越大,所以提供了 AOF 重写机制
在使用重写机制后,就会读取 name 最新的 value(键值对) ,然后用一条 「set name wanglaiyong」命令记录到新的 AOF 文件
重写机制请自行谷歌,太多了,我哦大概说下,开启子线程处理,不影响主线程,当一个 name 已经重写但是在主线程被修改时,主线程将执行后的写命令追加到 「AOF 重写缓冲区」,子进程完成 AOF 重写工作辉通知到主线程,主线程辉做两件事:
1、将 AOF 重写缓冲区中的所有内容追加到新的 AOF 的文件中,使得新旧两个 AOF 文件所保存的数据库状态一致;
2、新的 AOF 的文件进行改名,覆盖现有的 AOF 文件
RDB 写时复制技术
子线程异步 RDB 持久化时,为了主线程还能执行命令的技术,主要方式是:
fork() 创建子进程,子进程和父进程共享同一片内存数据,因为创建子进程的时候,会复制父进程的页表,但是页表指向的物理内存还是一个,此时如果主线程执行读操作,则主线程和 bgsave 子进程互相不影响
如果主线程执行写操作,则被修改的数据会复制一份副本,然后 bgsave 子进程会把该副本数据写入 RDB 文件
这样就实现了在持久化的同时主线程仍然可以直接修改原来的数据
脑裂 是什么
哨兵模式下,主服务器与从服务器不通,等从服务器选出个新服务器时,主服务器网络又通了,根据哨兵模式的机制,主服务器的内容会被全清掉,但是这期间有客户端写入,会导致结果不正确
怎么处理:
Redis 的配置文件中有两个参数我们可以设置:
- min-slaves-to-write x,主节点必须要有至少 x 个从节点连接,如果小于这个数,主节点会禁止写数据。
- min-slaves-max-lag x,主从数据复制和同步的延迟不能超过 x 秒,如果超过,主节点会禁止写数据。
这两个配置项组合后的要求是,主库连接的从库中至少有 N 个从库,和主库进行数据复制时的 ACK 消息延迟不能超过 T 秒,否则,主库就不会再接收客户端的写请求了
等到新主库上线时,就只有新主库能接收和处理客户端请求,此时,新写的数据会被直接写到新主库中。而原主库会被哨兵降为从库,即使它的数据被清空了,也不会有新数据丢失。
大key怎么处理
我看那么多文档,咋都说怎么查出来然后删掉
我认为不是应该查出来是什么key,怎么生成的,去优化代码?
若是大key影响到系统稳定性,可以删,但是删也有风险,,太多的话分批次删除,最好时异步删除不影响主线程
redis 支持事务么
有事务,但是没有执行错误时的事务回滚
有函数可以放弃整个事务
分布式锁
是不是一看见这几个字就想到redis分布式锁,为啥呢
我认为是redis是基于内存的,快,没错,就是快,还有方便,那个公司没有redis服务,而且还是多台,哨兵模式
设置方法:
SET lock_key wanglaiyong NX PX 10000
- lock_key 就是 key 键;
- wanglaiyong 是客户端生成的唯一的标识,区分来自不同客户端的锁操作;
- NX 代表只在 lock_key 不存在时,才对 lock_key 进行设置操作;
- PX 10000 表示设置 lock_key 的过期时间为 10s,这是为了避免客户端发生异常而无法释放锁。