redis
概览
https://class.imooc.com/lesson/1229#mid=29233
面试题
https://class.imooc.com/lesson/1229#mid=29235
https://blog.csdn.net/lxw1844912514/article/details/103115527
nosql
列存储数据库 Hbase、Cassandra(主要用于大数据)
MongoDB(C++开发,分布式文件存储数据库)
redis可以做到每秒10w次的读取速度
Redis、Memcache、MongoDB是国内使用最多的Nosql数据库;
一个项目中没有一个Nosql数据库,说明这个项目非常传统
分布式缓存
背景
Redis 是归类为 NoSQL 的,所以需要先了解一下什么是 NoSQL
MySQL、Oracle、等都是关系型数据库,
NoSQL的全称是 Not Only SQL,即它除了做数据存储以外,还有其它的一些功能。
传统项目使用纯关系型数据库,访问量不会很大,并发量也不会很高。
随着互联网和大数据的发展,已经不适合把超大量的数据提供出去做并发型的查询。因为数据库单表的性能是有限的。普通关系型数据库只能达到 400-500 万。
一旦数据量庞大了以后,NoSQL就横空出世了。
分布式缓存优点
- NOSQL 水平(横向)扩展方便高效,增加删除缓存能够做到非常的高效
- 高性能读取(内存)
- 可以搭建集群,实现高可用
- 存数据,做缓存(缓存可以持久化)。
概念
- 在高并发的场景下,通过分布式缓存,是可以提升读取速度的。(写操作是需要入库的,遵循二八原则(在互联网的环境下,百分之八十的操作都是读操作))
- 分布式计算领域,将系统垂直的进行拆分以后,就需要使用缓存来提升系统整体的读性能。
- 为数据库降低查询压力(缓存承担查询功能之后,数据库的查询压力就会降低,数据库是整个项目的瓶颈所在)
- 跨服务器缓存(分布式)
- 内存式缓存。内存的读取效率是远远高于硬盘存储的数据的。可以让大多数的请求去命中缓存,而少量的请求在有需求的时候才会去访问到数据库,从而就可以增加提高整个系统的并发量,能够减少数据库的压力,为其进行降压。
什么是 Redis
- NoSQL
- 分布式缓存中间件
- key-value 存储。类似于 hashMap,可以存储一些字符串,list、set集合等数据。
- 提供海量数据存储访问。
- 数据存储在内存里,读取更快。
总结: 非关系型 、分布式、开源、水平扩展(构建集群)
redis与memcache ehcache对比
Ehcache 适用于单体应用
优点:
- 基于java开发,和java项目整合"健壮性"更好;
- 在JVM中,使用Ehache速度更快,性能更高
- 整合简单,轻巧,方便
MyBatis,Habanati 都会使用 Ehcache,整合方便
缺点: - 不支持集群
- 不支持缓存共享,集群使用起来非常复杂,维护也非常不方便;
- 设计到缓存恢复等;
- 不支持分布式;
Memcache
只能做缓存
优点:
- 简单的key-value存储, 仅仅支持字符串(是缺点也是优点)
- 内存使用率比较高
- 多核处理,多线程, Redis是单线程的
缺点: - 无法容灾
- 无法数据持久化
Redis
可做缓存、存储 支持数据持久化
优点:
- 丰富的数据结构
- 支持持久化
- 支持主从同步,故障转义
- 内存数据库,查询效率高
缺点: - 单线程(存储大数据性能较低,但是小数据比Memcache更好)
- 单核(对企业中的多核服务处理器的利用率不高)
(作者认为,单核单线程更加简单不容易出错, 优先考虑多实例实现高吞吐量)
redis和memcahe的区别
redis支持持久化,memcache不支持,redis支持的数据类型更丰富,memcache支持string,redis是单核单线程模型,memcache是多核多线程模型。
单线程的效率为什么这么高
1>.纯内存操作;
2>.核心是基于非阻塞的IO多路复用机制;
3>.底层使用C语言实现,一般来说,C 语言实现的程序"距离"操作系统更近,执行速度相对会更快;
4>.单线程同时也避免了多线程的上下文频繁切换问题,预防了多线程可能产生的竞争问题;
redis安装与配置
配合生产实现开机自启动,使用脚本启动;还可以通过redis-server外加配置文件启动
https://www.cnblogs.com/dtyy/p/14348165.html
https://class.imooc.com/lesson/1228#mid=29188
redis5
- 解压缩,编译(/home/software/)
tar -zxvf redis-5.0.5.tar.gz
ln -s redis-5.0.5 redis
yum install gcc-c++
cd redis
make && make install
此时,便可以通过redis-server启动Redis服务了。
- 核心文件配置(/usr/local/redis/)
创建 /usr/local/redis,用于存放配置文件
cd /home/software/redis
mkdir working
# 从编译目录拷贝配置文件
cp redis.conf /usr/local/redis/
vim redis.conf
# 访问密码设置
requirepass 123456
# 设置后台服务
daemonize yes
# 解除远程ip限制, 代表可以远程连接
bind 0.0.0.0
# 设置工作目录
dir /usr/local/redis/working
- 配置初始化脚本(/etc/init.d/)
配置redis,在utils下,拷贝redis_init_script到/etc/init.d目录,目的要把redis作为开机自启动
cp /utils/redis_init_script /etc/init.d/
cd /etc/init.d/
vim redis_init_script
# 修改配置位置
CONF="/usr/local/redis/redis.conf"
#chkconfig: 22345 10 90
#description: Start and Stop redis
chmod 777 redis_init_script
./redis_init_script start
- 设置redis开机启动
chkconfig redis_init_script on
- 然后 reboot 重启即可。
查看开机服务
chkconfig --list
查看redis
ps -ef | grep redis
- redis启动关闭
/etc/init.d/redis_init_secript stop
/etc/init.d/redis_init_secript start
ll --full-time
redis命令
基本命令
redis-cli -a password shutdown/ping:关闭redis
./redis_init_script stop:关闭redis
redis-cli:进入到redis客户端
auth pwd:输入密码
set key value:设置缓存
get key:获得缓存
del key:删除缓存
redis-cli -a password ping:查看是否存活
redis进阶命令
redis中默认有16个库,默认使用0号库,在reds.conf
配置文件中可以修改。可以使用select n
进行修改当前使用的库
string 字符串
string: 最简单的字符串类型键值对缓存,也是最基本的
key相关
keys *:查看所有的key (不建议在生产上使用,有性能影响)
type key:key的类型
string类型
get/set/del:查询/设置/删除
set rekey data:设置已经存在的key,会覆盖
setnx rekey data:设置已经存在的key,不会覆盖
set key value ex time:设置带过期时间的数据
expire key:设置过期时间
ttl:查看剩余时间,-1永不过期,-2过期
append key:合并字符串
strlen key:字符串长度
incr key:累加1
decr key:类减1
incrby key num:累加给定数值
decrby key num:累减给定数值
getrange key start end:截取数据,end=-1 代表到最后
setrange key start newdata:从start位置开始替换数据
mset:连续设值
mget:连续取值
msetnx:连续设置,如果存在则不设置
其他
select index:切换数据库,总共默认16个
flushdb:删除当前下边db中的数据
flushall:删除所有db中的数据
hash相关命令
hash:类似于map,存储结构化数据结构,比如存储一个对象(不能有嵌套对象)
hset usr usrkey usrvalue 创建一个hash对象
hget usr usrkey 获取hash中某一属性的值
hmset/hmget 设置多个属性 同 mset/mget
hgetall 获取当前对象中所有键值对
hlen usr 查看当前对象(hash)中包含了多少属性
hkeys usr 查询当前对象中所包含的所有key
hvals usr 查询当前对象中所包含的所有key
HINCRBY usr key 数值 对对象中某一属性值(必须为数值)进行 加减操作
HINCRBYfloat usr key 数值 增加小数
HEXISTS usr key 判断对象中某一属性是否存在(1存在 / 0不存在)
HDEL usr age 删除对象属性,没有属性后对象会自动删除
list数据类型及命令
list:列表,[a, b, c, d, …]
lpush list value1 value2 value3 加入一个list
lrange list 0 -1 查看某list ,下标0到 -1(无穷大)
rpush list value valu2
lpush list 1 2 3 4 5从左到右存放(顺序和下标相反), rpush从右往左存放(顺序和下标顺序),构建一个list,从右边开始存入数据
lpol/rpop
lpop:从左侧开始拿出一个数据
rpop:从右侧开始拿出一个数据
lpush+lpop 先入先出 (队列) rpush+rpop先入后出(栈)
llen list 查看数组长度
lindex list index list数组 index下标的值
lset list index value 替换下标对应值
linsert key before/after value newvalue 在数组中某一元素 前/后 插入新元素
lrem list count value 删除多少个 为 “value”值的元素
ltrim list startindex stopindex 截取,保留我们的截取内容
del list 删除list
set数据类型及命令
不能有重复值的数据
1. sadd set value1 value2 value3 添加,会自动去重
2. SMEMBERS set 查看set中元素
3. scard set 查看set中元素包含多少数量
4. SISMEMBER set value 查看set中是否包含某元素(1存在/0不存在)
5. srem set value 删除某元素
6. spop set (count) 加了count就是 出几个元素, 不加就默认出一个
7. SRANDMEMBER set count 从当前set中随机获取 conut个元素内容
8. 在用户中(前几名随机获取几位幸运观众)
9. smove set1(源) set2(移动到这里) value 将set1中的value移动到set2中
差集/交集/并集
差集 sdiff set1 set2 去set1中包含的内容,set2不包含的取出来
sinter set1 set2 取交集
sunion set1 set2 取并集
zset数据类型及命令
按分数排序(可排序,去重)的set ,= sort set
(需要和分数结合使用,分数用来排序)
例如:可以用来用户积分排名
1. zadd zset 10 value1 20 value2 30 value3 添加
2. zrange zset 0 -1 展示所有
1. zrange zset 0 -1 withscores 带上分数
2. 继续使用 zadd zset 25 value4 插入新的
3. zrank zset value 查看value 的下标
4. zscore zset value 获取value元素的分数
5. zcard zset 查看集合 大小
6. zcount zset 分数1 分数2 取大于等于分数1,小于等于分数2有多少数量
7. ZRANGEBY zset 分数1 分数2 (withscores) 展示大于等于分数1小于等于分数2 (是否展示分数)
1. ZRANGEBY zset (分数1 (分数2 大于分数一,小于分数2
2. ZRANGEBY zset 分数1 分数2 LIMIT 1 2 分页
8. zrem zset value value2 删除 元素
命令参考文档
阻塞与非阻塞
阻塞
用户有服务器通信,要发起请求。服务器会去做相应的处理,一个请求正在处理的时候,后续所有的请求都要等待正在处理的请求处理完毕(后续的请求都会被第一个请求阻塞住的,直到第一个请求处理完毕返回响应给客户端以后,第二个、第三个才能去处理),这种一对一处理的模式就是阻塞的通信模式。效率非常低下,开销非常大;
阻塞模型
- 单个线程,后面用户需要等待上个用户请求完成才能继续执行请求;
- 多线程,一定程度上解决请求处理慢的问题,但是如果用户量一多,服务器开辟对应数量的线程对服务器压力很大;
- 线程池:伪异步模型,针对客户端的处理,本质上还是阻塞的模式去处理
非阻塞模型
上一个请求阻塞会轮训往下面一个个找,找到新的请求就处理,不会阻塞等待上一个请求处理完,是同步 非阻塞的模式,也是多路复用的模式,性能和并发非常高;
redis线程模型也是用的多路复用,io多路复用是环状型的东西;
redis线程模型用的io多路复用器(只接受请求,不处理)也是用的非阻塞模式;
多路复用器
多路复用器同步非阻塞接收请求交由服务器处理,这样性能就很高了
简而言之,独立出接受请求的模块
总结
- 阻塞和非阻塞是从程序(线程)等待消息的状态来说的,阻塞就是说程序接收到一个请求。执行不完不执行下一件事,非阻塞指程序接收到请求后不能立刻执行完则先放下该请求,转而执行下一请求。
- 在Redis中,非阻塞模式指的是多路复用器来接收请求,然后分发给具体执行任务的其它模块。
redis线程模型
虽然文件事件处理器以单线程方式运行,但通过使用 I/O 多路复用程序来监听多个套接字,文件事件处理器既实现了高性能的网络通信模型,又可以很好地与 Redis 服务器中其他同样以单线程方式运行的模块进行对接,这保持了 Redis 内部单线程设计的简单性。
Redis-server 启动之后是会产生一个进程,内部有多路复用器和文件事件分配器,专门是用于去分配一些事件的,分配器下边有三个不同的处理器,分别是连接应答处理器、命令请求处理器、命令恢复处理器
概念
连接应答处理器主要作用是和客户端保持连接,在Redis Server启动之后,就会有 Read 事件和连接应答处理器捆绑在一起,这个事件的全称是 AE_Readable 事件。
当客户端和 Server 要建立连接的时候,客户端就会发送一个 Read 标志(其实就是一个 Readable 事件),这时候在 Redis 中会产生一个 server-socket,这个 server-socket 和客户端的 socket是对应的(属于网络编程中的socket通信)。接受到read事件以后, 随后就会交由多路复用器进行处理,它是非阻塞的,接收到之后会丢到传向文件事件分配器的管道中(箭头,管道pipeline,队列 ),然后到达文件事件分配器 ,当它识别到这个事件是 Read 事件之后,就会把它交由连接应答处理器,和连接应答处理器做到一个匹配,也就是AE_Readable时间,这时候 client 和 server 端就建立了连接。建立好连接之后,这个事件会交给命令请求处理器(处理请求),命令处理完毕之后,Redis会分配一个Write(AE_Writeable事件)标记,进行回写,将Write结果显示在控制台下方(匹配到命令回复处理器,将write内容回写给客户端在客户端进行展示)。
总结
经过server-socket,丢给多路 复用器,拿到放到队列里面,然后交由文件事件分配器,应用处理器判断是个read事件,交由请求处理器处理,把键值存储存到内存里,命令请求的处理,request,处理完分配一个write写的标识,可以作为响应;把响应回写给客户端,在客户端上做一个展示;
read,write就是相对于从客户端上读取还是写入数据;连接,处理请求,返回处理结果;
redis为什么快
io多路复用器采用非阻塞的模型响应比较快(不需要等待上一个请求获得回复即可处理下一个请求,耗时请求直接跳过);然后文件事件分配器负责内存部分的操作,响应也很快(可能处理请求没有线程池,单纯内存操作就够快了,redis是单线程模型);
避免多线程,多线程涉及上下文的切换,避免问题和损耗和线程安全问题,单线程并发性和效率高
中间管道pipeline/队列
springboot整合redis
https://class.imooc.com/lesson/1228#mid=29224
- 引入 redis 依赖
<!-- 引入 redis 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
- 配置redis
spring:
redis:
database: 1
host: 192.168.1.191
port: 6379
password: imooc
- controller测试
@Autowired
private RedisTemplate redisTemplate;
redisTemplate.opsForValue().set(key, value);
(String)redisTemplate.opsForValue().get(key);
redisTemplate.delete(key);
redisTemplate序列化规则
redisTemplate有自己默认的序列化机制,序列化会有乱码
StringRedisTemplate序列化没有乱码
如何解决缓存与数据库不一致的情况
- 后台管理系统,如果更新了轮播图,则同步更新redis中的数据
- 定时更新,设置一个时间点更新,不要全部都设置在一个时间
- 设置过期时间,到过期时间后再重新赋值
redis的发布和订阅
redis的订阅与发布
在同一客户端下,
SUBSCRIBE ch # 订阅某个信道,可以同时订阅多个
订阅之后,订阅者处于监听的状态。
输入命令PUBLIC ch 消息
此时响应的订阅者即可收到消息。
同时也可以输入命令PSUBSCRIBE name* 实现批量订阅消息。
注意:基于专人做专事原则;
就好比数据库的主要作用就是存储,我们尽量不要给他一些额外的计算负担;
Redis也是一样,redis的主要作用就做缓存,消息的发布和订阅主要是由MQ负责实现的,所以一般很少有人用Redis做消息发布订阅。
redis的持久化方案
如果没有使用持久化的功能,程序跑多久Redis存在多久。
恢复数据:将备份到硬盘的文件恢复到内存中
RDB(Redis DataBase)
https://class.imooc.com/lesson/1228#mid=29489
什么是RDB
隔一段时间,把内存中的数据写入磁盘的零食文件,作为快照,恢复的时候把快照文件读进内存中。如果宕机重启,那么内存里的数据肯定会没有的,那么再次启动redis后,则会恢复。
备份与恢复
内存备份-->磁盘临时文件
临时文件-->恢复到内存
RDB优势
- 30d每天或者24h每小时全量备份,以不同的时间点命名文件,利于恢复
- 以单个文件保存备份数据,灾备简单,利于灾难恢复,可以保存到远程数据中心
- 备份时由父进程fork出子进程进行备份,且备份时父进程不会进行io操作(不会有写入或者删除),保证了备份数据的完整性
- 对于数据集比较大的数据较AOF更迅速(相对AOF来说,当有更大文件的时候可以快速重启恢复)
RDB缺点
- 发生故障时,可能会丢失最后一次的备份数据
- 在备份时子进程会copy父进程的数据,在数据比较大时,可能会影响服务器性能,如果是云服务器性能很高,那么这是没有关系的。
- 不能做到实时的备份,因为备份机制为按照时间间隔的某个时间点(由于定时全量备份是重量级操作,所以对于实时备份,就无法处理
配置文件
stop-writes-on-bgsave-error yes 保存发生错误,停止写操作,如果不停止会造成数据不一致。
rdbcompression yes 数据压缩 lzf压缩模式 如果文件会比较大,压缩会占用cpu性能。
rdbchecksum yes 数据校验 用CRC64 校验会消耗10%开销。
dbfilename 数据库名称
dir 备份数据路径
redis.conf中修改
./dir 更改为 dir /usr/local/redis/working
save注释放开 save seconds(间隔时间) change(更改次数)
save 900 1 # 如果1个缓存更新,则15分钟后备份
save 300 10 # 如果10个缓存更新,则5分钟后备份
save 60 10000 # 如果10000个缓存更新,则1分钟后备份
save 10 3 # 更新3个缓存,10秒后备份
压缩文件
总结
RDB适合大量数据的恢复,但是数据的完整性和一致性可能会不足
AOF(Append Only File)
https://class.imooc.com/lesson/1228#mid=29490
引子
RDB会丢失最后一次备份的rdb文件,但是其实也无所谓,其实也可也以忽略不计,毕竟是缓存丢了就丢了,但是如果追求数据的完整性,那么就得考虑使用AOF了。
AOF特点
1.以日志的形式来记录用户请求的写操作。读操作不记录,因为写操作会存储。
2.文件已追加的形式而不是修改的形式。
3.redis的aof恢复其实就是把追加的文件从开始到结尾读取执行写操作。
AOF重写
redis会把当前所有的数据以rdb形式存入到aof中,这都是二进制数据,数据量小,随后新的数据以aof形式追加到这个aof中,那么这个aof中包含两种文件类型数据,一个是rdb,一个是aof,那么恢复的时候redis会同时恢复,这样恢复过程会更快。这相当于是一个混合体。
AOF注意事项
- AOF日志文件的占用空间比RDB的备份文件大的多
- AOF的根据每一次请求就append到日志文件中的写操作是非常损耗性能的(每秒存储一次日志形式其实也还好)
- 当使用AOF时,比较容易出现BUG(恢复数据时候可能会不一致)
优势
1.AOF更加耐用,可以以秒级别为单位备份,如果发生问题,也只会丢失最后一秒的数据,大大增加了可靠性和数据完整性。所以AOF可以每秒备份一次,使用fsync操作。
2.以log日志形式追加,如果磁盘满了,会执行redis-check-aof工具。
3.当数据太大的时候,redis可以在后台自动重新AOF。当redis继续把日志追加到老的文件中去时,重写也是非常安全的,不会影响客户端的读写操作。
4.AOF日志包含的所有写操作,会更加便于redis的解析恢复。
劣势
1.相同的数据,同一份数据。AOF比RDB大
2.针对不同的同步机制,AOF会比RDB慢,因为AOF每秒都会备份做写操作,这样相对于RDB来说就略低。每秒备份fsync就没问题,但是如果客户端的每次写入就做一次备份fsync,那么redis的性能就会下降。
3.AOF发生过bug,就是数据恢复的时候数据不完整,这样显得AOF会比较脆弱,容易出现bug,因为AOF没有RDB那么简单,但是为了反之bug的产生,AOF就不会根据旧的指令去重构,而是根据当时缓存中的数据指令去重构,这样就更加健壮和可靠了。
AOF的配置
# AOF 默认关闭,yes可以开启
appendonly no
# AOF 的文件名
appendfilename "appendonly.aof"
# no:不同步
# everysec:每秒备份,推荐使用
# always:每次操作都会备份,安全并且数据完整,但是慢性能差
appendfsync everysec
# 重写的时候是否要同步,no可以保证数据安全
no-appendfsync-on-rewrite no
# 重写机制:避免文件越来越大,自动优化压缩指令,会fork一个新的进程去完成重写动作,新进程里的内存数据会被重写,此时旧的aof文件不会被读取使用,类似rdb
# 当前AOF文件的大小是上次AOF大小的100% 并且文件体积达到64m,满足两者则触发重写
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
到底采用RDB还是AOF呢?
1.如果你能接受一段时间的缓存丢失,那么就可以使用RDB
2.如果你对实时性的数据比较在意,那么就用AOF
3.使用RDB和AOF结合一起做持久化,RDB做冷备,可以在不同时期对不同版本做恢复,AOF做热备,保证数据仅仅只有1秒的损失。当AOF破损不可用了,那么再用RDB恢复,这样就做到了两者的相结合,也就是说redis恢复会先加载AOF,如果AOF有问题会加载RDB,这样就达到了冷热备份的目的。
redis的主从复制(读写分离)
主从架构
可以理解为一种水平扩展的方式来提高Redis性能;
主从就是读写分离;
根据读写二八原则,主节点负责处理写操作,从节点负责处理读操作;
主节点起到了请求分发的作用。
主从原理
- 初始化阶段,slave节点启动成功后,会向master节点发送ping,表示需要进行同步,master节点将此时的内存数据copy到磁盘中作为.rdb文件,通过内网将.rdb文件发送给slave节点,slave节点收到后,将文件下载到本地磁盘,然后读到内存中,完成数据的同步(全量同步)。
- 运行阶段,master写入了新数据,则直接向slave发送新增的数据,不经过硬盘(增量同步)。
- 在数据同步过程中,不会阻塞阻止master的写操作,以及slave的读操作,此时进行的读操作读取到的数据均为同步完成之前的旧数据。(同步完成,用新数据提供服务)
- 主节点必须开启持久化。否则主节点重启后数据清空(会同步清空slave),数据同步会导致从节点的所有数据丢失。
主从模式
一主两从最常用(避免从节点过多,主从节点之间的数据同步,文件的上传下载占用内网网络带宽
这种树状模式也比较少见,多个叶子节点降低主节点的同步压力
总结
主从第一次建立连接后,会触发全量复制。master节点会执行bgsave命令基于当前内存快照保存RDB文件到master节点本地,而不是用之前的生成的RDB文件。然后master节点就会把RDB文件通过网络传输发送给slave节点。由于这个时候master节点还会响应写命令,所以在这个传输期间会把写命令数据保存到积压缓冲区里面。当slave节点加载完成RDB文件后,master节点再把缓冲区的数据发送给从节点,保证主从节点数据一致性。slave节点完成RDB文件加载后,master都是通过缓存区内把写命令数据发给slave节点,而不是再次通过rdb文件。
https://class.imooc.com/course/qadetail/213488
redis主从复制搭建
主从模式
- 即读写分离,即1主1从、1主多从(主写操作,从读操作,主将数据同步给从)
主从配置
- 查看redis信息
info replication
- 修改从节点配置文件
redis.conf
1. 搜索 / Rep 关键字
2. 配置 replicaof <masterip> <masterport>
replicaof 192.168.57.103 6379
3. 配置 masterauth 主节点密码
masterauth imooc
4. replica-read-only yes 从节点只读
5. 保存重启即可
/etc/init.d/redis_init_script stop
/etc/init.d/redis_init_script start
主从模式测试
主节点不挂,从节点保持slave状态
主节点挂机,从节点保持slave状态,但是不会自动选举master
心跳检测到之后会 将信息列表修改
info replication
查看节点状态 master_link_status:
redis 无磁盘化主从复制(硬盘不行的替换方式
主Redis生成的RDB文件不落在磁盘上,而是直接在内存中通过网络发送;
一般是磁盘io比较慢,网络传输比较快, maser创建新的进程,同步内存数据,通过socket传输到从节点,在内存中读取文件数据
而从Redis也不是将RDB下载到磁盘,而是直接获取在内存中)
配置
redis.conf ----- diskless
开启 yes
开启后,rdb文件不会写入硬盘(disk),而是直接写入socket网络连接中;
开发送前等待从redis连接的等待时间
设置delay的必要性
在无磁盘化复制过程,一个slave第一次连上master节点,master节点会生成RDB文件,然后直接发送给slave节点。如果不设置delay,就会每个slave连上时就要重新生成RDB文件并发送给新连上的slave节点。master节点发送RDB文件给salve节点是通过网络传输的,而RDB的生成、RDB通过网络传输是很耗时间的,特别是跨机房跨地域传输。如果生成的RDB文件大小在4G~6G之间,那么很可能全量复制时间消耗要1分半到2分钟。所以为了尽量节省带宽资源 cpu资源消耗,delay要设置一下的
https://class.imooc.com/course/qadetail/205827
主从复制选型
硬盘的类型,有ssd固态硬盘、机械硬盘(如果使用的是这种,读写效率很低,这个时候就会采用无磁盘化复制,提高读写效率)
Redis 缓存过期处理与内存淘汰机制
https://class.imooc.com/lesson/1228#mid=29225
Redis的key设置了过期时间后(expire);虽然key过期查询不了,但是还是会占用服务器内存;
定期删除 (主动删除)
redis定时检测缓存key是否过期,默认10次一秒 (区间 1-500)
也可以提升他的检查频率,但是这样做会使CPU被占用的更多;
惰性删除
客户端请求的时候,当检测到这个key是过期的时候,才会对这个过期缓存进行删除;
这么做就对cpu非常友好,但是缺点就是用户如果一直不请求这个资源,那么这个过期key就会一直存在在内存中,占用内存资源;
内存淘汰管理机制
memory management maxmemory 最大内存阈值,到达阈值之后,redis会自动清理,自动清理有几种算法maxmemory policy
- noeviction:旧缓存永不过期,新缓存设置不了,返回错误
- allkeys-lru:清除最少用的旧缓存,然后保存新的缓存(推荐使用)
- allkeys-random:在所有的缓存中随机删除(不推荐)
- volatile-lru:在那些设置了expire过期时间的缓存中,清除最少用的旧缓存,然后保存新的缓存
- volatile-random:在那些设置了expire过期时间的缓存中,随机删除缓存
- volatile-ttl:在那些设置了expire过期时间的缓存中,删除即将过期的
LRU:least recently used 最近最少使用
LFU:least Frequetly used 最不经常使用
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?