缓存的意义?
缓存:数据可丢失
数据库:数据绝对不能丢
缓存追求的是速度,内存掉电易失
存储层:
1,快照/副本 : 时点性的一个数据整体
2,日志 :是操作指令的历史记录
单机持久化
主从复制
一,基础只是引入
1,如果快照从8点写到8点半,怎么解决时点混乱(那么数据的时间是怎么样的?8点?8点半?8-8点半之间?)的问题
8点的,使用的是fork()的方式
liunx管道
1,衔接前一个命令的输出作为后一个命令的输入
2,管道会触发创建 【子进程】
num=0 # 创建按变量
echo $num # 输出
((num++)) #加法
((num++)) | echo ok #不会做加法
echo $$ # 获取当前进程的进程号
echo $$ | more #more把管道给的东西写出来
echo $BASHPID | more
echo $$ 和 echo $BASHPID 的区别?
都可以打印进程号,**
优
先
级
高
于
管
道
∗
∗
这
是
e
c
h
o
优先级高于管道** 这是echo
优先级高于管道∗∗这是echo | more , echo $BASHPID | more 打印的进程号不一样的原因。
父子进程
父子进程对数据的修改,对方看不到
1,子进程能看的到父进程的数据么?
进程是数据隔离的
子进程无法直接拿到父进程的数据(指针是私有的)
export 环境变量
父进程可以让子进程看到数据
2,子进程对变量进行修改,父进程是否可以看到?
创建脚本 test.sh
#!/bin/bash
echo $$ # 打印子进程的进程号
echo $num # 子进程中是否能得到变量
num=999 # 重新赋值
echo num:$num # 获取这个值
sleep 20 # 休眠20秒
echo $num # 重新获取这个值
chmod +x test.sh # 给脚本赋予执行权限
./test.sh & # &使脚本在后台运行
子进程修改不会影响父进程
父进程对变量进行修改,子进程是否可以看到?
父进程修改不会影响子进程
二,fork
创建子进程的速度,如果父进程是redis,内存数据是10G?
复制的是指针,所以速度和空间成本小,也解决了时点的问题,复制的是几点的指针,十点就是几点的
三,RDB
默认支持
save 时间/s 操作数
save 900 1 #900秒操作数到达1
save 300 10 #300秒操作数到达10
save 60 10000 #60秒操作数到达10000
#save “” #关闭rdb
dbfilename dump.rdb 默认写覆盖,需要额外写程序每日迁出这个文件,保证历史文件。
dir var/lib/redis/6379 #默认存储位置
主进程修改数据,子进程只会读并写到磁盘。
RDB的弊端和有点
不支持拉链
只有一个 dump.rdb
丢失数据相对多一些
时点记录,时点之间数据,8,9点落数据,8点半挂机了,会导致9点的数据无法落盘。
恢复速度快
类似JAVA的序列化,恢复的速度相对快
代码越多bug越多:最好的代码是没有代码
三,AOF
append only mode
向文件中追加数据
写操作的IO级别
fulsh
所有磁盘操作都要调用内核
no
把写的命令写在内核缓存区内,内核缓存区满后再写,可能会丢失一个buffer的数据。
always
内核没有满,也要写磁盘。最可靠,大小可调整4K
everyes
折中方案,根据每秒刷新到磁盘。丢失数据比no少。
四,RDB&AOF混合使用
默认开启
REDIS 开头区分是否开启
如果都开,只会用AOF恢复,因为AOF相对完整。
4.0以后,AOF中包含RDB全量,增加记录新的操作。
redis运行了10年,开启了AOF,10年头redi挂了AOF很大10T,恢复会不会溢出?
数据丢失 | 恢复 | |
---|---|---|
RDB | 比较多 | 快 |
AOF | 比较少 | 慢 |
五,实践检验
ps -fe |grep redis #查看,保证没有运行redis
vi /etc/redis/6379.conf
daemonize no #因为要看日志,禁止在后端服务执行,前台阻塞运行。
#logfile #把日志文件关掉,为了在前台窗口打印日志
appendonly yes #开启追加日志
aof-use-rdb-preamble yes#混合可以先关闭 no
rm -rf /var/lib/redis/6379/dump.rdb #删除rdb文件
redis-server /etc/redis/6379.conf
redis-check-rdb dump.rdb
删除dump.rdb文件,修改6379.conf 文件
启动
启动后多了一个空内容的文件appendonly.aof
使用第三台机器打开一个客户端redis-cli,设置一个k1
appendonly.aof发生变化
*2 *后边的数字代表几个元素组成
$6 $后有几个字符组成
选择0号库,设置一个k1是hello。
现在在添加k2,但是没有出现rdb,这时候可以用 bjsave(save会阻塞,不对外提供服务),出现rdb,混合体的开头是REDIS
REDIS0009ú redis-ver^E5.0.7ú
redis-bits?@ú^Ectime?5ó<93>`ú^Hused-mem??^F^M^@ú^Laof-preamble?^@?^@?^B^@^@^Bk2^Dooxx^@^Bk1^Ehello?^W<91>ó?9¤<9a>?
重写
给k1设置 3次值,appendonly.aof追加文件内会有很多k1的操作。但是get k1是获取的是最后的值,之前的命令就没必要执行了。客户端执行BGREWRITEAOF,170字节变为了82字节。
把曾经对k1的操作消除掉,减少文件大小,方便redis加载速度,执行没意义的指令。
新版本-融合
rm -fr ./* #删除appendonly.aof和dump.rdb
no-appendfsync-on-rewrite yes #把混合打开
启动,设置多个key,但是由于没有触发混合,文件内没有发送变化,重写没有发生。客户端使用BGREWRITEAOF开启重写,
aof文件中出现rdb的序列化的内容,然后在设置key,会以明文追加,这样的好处是恢复速度快。
如何找到历史
FLUSHALL 后有没有BGREWRITEAOF ,重写后历史信息会被覆盖掉。
自动重写
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
它的工作原理:Redis会记住最新重写(如果重新启动后没有发生重写,则使用启动时的AOF)。
此基本大小与当前大小进行比较。如果当前大小为大于指定的百分比时,将触发重写。
需要为要重写的AOF文件指定最小大小,这是即使百分比增加,也可以避免重写AOF文件但它仍然很小。
指定0的百分比以禁用自动AOF重写功能。