目录
频道首页
📚 redis
收藏
0
xy20118 最近修改于 2024-07-11 08:39:49

前言

image Redis,英文全称是Remote Dictionary Server(远程字典服务),是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。 与MySQL数据库不同的是,Redis的数据是存在内存中的。它的读写速度非常快,每秒可以处理超过10万次读写操作。因此redis被广泛应用于缓存,另外,Redis也经常用来做分布式锁。除此之外,Redis支持事务、持久化、LUA 脚本、LRU 驱动事件、多种集群方案。

Redis是一个开源的、遵循BSD协议的、基于内存的而且目前比较流行的键值数据库(key-value database),是一个非关系型数据库,redis 提供将内存通过网络远程共享的一种服务,提供类似功能的还有memcached,但相比memcached,redis还提供了易扩展、高性能、具备数据持久性等功能。

Redis 在高并发、低延迟环境要求比较高的环境使用量非常广泛

redis特点

  • 速度快: 10W QPS,基于内存,C语言实现
  • 单线程
  • 持久化
  • 支持多种数据结构
  • 支持多种编程语言
  • 功能丰富: 支持Lua脚本,发布订阅,事务,pipeline等功能
  • 简单: 代码短小精悍(单机核心代码只有23000行左右),单线程开发容易,不依赖外部库,使用简单
  • 主从复制
  • 支持高可用和分布式

注:Redis 6.0版本前一直是单线程方式处理用户的请求 之后的版本数据的读写命令,仍然是单线程处理的。

对比memcache

  • 支持数据的持久化:可以将内存中的数据保持在磁盘中,重启redis服务或者服务器之后可以从备份文件中恢复数据到内存继续使用
  • 支持更多的数据类型:支持string(字符串)、hash(哈希数据)、list(列表)、set(集合)、zset(有序集合)
  • 支持数据的备份:可以实现类似于数据的master-slave模式的数据备份,另外也支持使用快照+AOF
  • 支持更大的value数据:memcache单个key value最大只支持1MB,而redis最大支持512MB(生产不建议超过2M,性能受影响)
  • 在Redis6版本前,Redis 是单线程,而memcached是多线程,所以单机情况下没有memcached 并发高,性能更好,但redis 支持分布式集群以实现更高的并发,单Redis实例可以实现数万并发
  • 支持集群横向扩展:基于redis cluster的横向扩展,可以实现分布式集群,大幅提升性能和数据安全性
  • 都是基于 C 语言开发 ||memcached |redis |:--| |类型 |key-value |key-value | |过期策略 |支持 |支持 | |数据类型 |单一数据类型 |五大数据类型 | |持久化 |不支持 |支持 | |主从复制 |不支持 |支持 | |虚拟内存 |不支持 |支持 |

使用场景

  • Session 共享:常见于web集群中的Tomcat或者PHP中多web服务器session共享
  • 缓存:数据查询、电商网站商品信息、新闻内容
  • 计数器:访问排行榜、商品浏览数等和次数相关的数值统计场景
  • 微博/微信社交场合:共同好友,粉丝数,关注,点赞评论等
  • 消息队列:ELK的日志缓存、部分业务的订阅发布系统(消息队列是大型网站必用中间件,如ActiveMQ、RabbitMQ、Kafka等流行的消息队列中间件,主要用于业务解耦、流量削峰及异步处理实时性低的业务。Redis提供了发布/订阅及阻塞队列功能,能实现一个简单的消息队列系统。但是不能和专业的消息中间件比较。)
  • 地理位置: 基于GEO(地理信息定位),实现摇一摇,附近的人,外卖等功能
  • 分布式锁:几乎每个互联网公司中都使用了分布式部署,分布式服务下,就会遇到对同一个资源的并发访问的技术难题,如秒杀、下单减库存等场景。 (用synchronize或者reentrantlock本地锁肯定是不行的。 如果是并发量不大话,使用数据库的悲观锁、乐观锁来实现。 但是在并发量高的场合中,利用数据库锁来控制资源的并发访问,会影响数据库的性能。 实际上,可以用Redis的setnx来实现分布式的锁。)
  • 位操作:用于数据量上亿的场景下,例如几亿用户系统的签到,去重登录次数统计,某用户是否在线状态等等。如腾讯QQ (原理:redis内构建一个足够长的数组,每个数组元素只能是0和1两个值,然后这个数组的下标index用来表示用户id)

缓存实现流程

image image

redis安装

安装地址源码包:http://download.redis.io/releases/

#安装依赖包
yum -y install gcc jemalloc-devel 
yum -y install gcc jemalloc-devel systemd-devel

#ubantu安装
apt -y install make gcc libjemalloc-dev libsystemd-dev 

#安装包 
cd /opt 
wget http://download.redis.io/releases/redis-5.0.7.tar.gz .
tar xvf redis-5.0.7.tar.gz 
cd redis-5.0.7/
#指定安装目录
make PREFIX=/apps/redis install 
make USE_SYSTEMD=yes PREFIX=/apps/redis install

#配置变量 使之可以被systemd管理
echo 'PATH=/apps/redis/bin:$PATH' > /etc/profile.d/redis.sh 
source /etc/profile.d/redis.sh
#配置自定义配置文件m目录  日志 数据等目录
mkdir /apps/redis/{etc,log,data,run} 
#源码包中自带 配置文件 复制到对应目录下
cp redis.conf /apps/redis/etc/ 

启动redis

#前台启动
redis-server /apps/redis/etc/redis.conf

systemd启动
useradd -s /sbin/nologin -r redis 
#授权文件给用户
chown -R redis.redis /apps/redis/
#做软链接
ln -sv /apps/redis/bin/redis-* /usr/bin/

#编辑service文件
[root@xyy7 redis-5.0.7]# vim /usr/lib/systemd/system/redis.service 

[Unit]
Description=Redis persistent key-value database
After=network.target


[Service]
ExecStart=/apps/redis/bin/redis-server /apps/redis/etc/redis.conf --supervised systemd
ExecStop=/bin/kill -s QUIT $MAINPID
#Type=notify 如果支持systemd可以启用此行
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755


[Install]
WantedBy=multi-user.target

[root@xyy7 redis-5.0.7]# systemctl daemon-reload
systemctl start redis 

排错

[root@xyy7 redis-5.0.7]# gcc -v # 查看gcc版本
[root@xyy7 redis-5.0.7]# yum -y install centos-release-scl # 升级到9.1版本
[root@xyy7 redis-5.0.7]# yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++ devtoolset-9-binutils
[root@xyy7 redis-5.0.7]# scl enable devtoolset-9 bash
以上为临时启用,如果要长期使用gcc 9.1的话:
[root@xyy7 redis-5.0.7]# echo "source /opt/rh/devtoolset-9/enable" >>/etc/profile

取消waring image

backlog参数控制的是三次握手的时候server端收到client ack确认号之后的队列值,即全连接队列

#vim /etc/sysctl.conf
net.core.somaxconn = 1024
#sysctl -p

vm.overcommit_memory 0、表示内核将检查是否有足够的可用内存供应用进程使用;如果有足够的可用内存,内存申请允许;否则,内存申请失败,并把错误返回给应用进程。 1、表示内核允许分配所有的物理内存,而不管当前的内存状态如何 2、表示内核允许分配超过所有物理内存和交换空间总和的内存

vim /etc/sysctl.conf
vm.overcommit_memory = 1
#sysctl -p 

transparent hugepage 警告:您在内核中启用了透明大页面(THP,不同于一般内存页的4k为2M)支持。 这将在Redis中造成延迟和 内存使用问题。 要解决此问题,请以root 用户身份运行命令“echo never> /sys/kernel/mm/transparent_hugepage/enabled”,并将其添加到您的/etc/rc.local中,以便在重启后保留设置。禁用THP后,必须重新启动Redis。

echo never > /sys/kernel/mm/transparent_hugepage/enabled   >> /etc/rc.d/rc.local 
chmod +x /etc/rc.d/rc.local

systemctl restart redis 

image

调用redis image

[root@xyy7 redis-5.0.7]# redis-cli 
127.0.0.1:6379> ping
PONG
--------------------------------------------------------------------
-p  端口
-h  地址
-a  密码

#跨主机密码连接
redis-cli -h HOSTNAME/IP -p PORT -a PASSWORD 

redis配置优化

#监听地址,可以用空格隔开后多个监听IP
bind 0.0.0.0

#redis3.2之后加入的新特性,在没有设置bind IP和密码的时候,redis只允许访问127.0.0.1:6379,可以远程连接,但当访问将提示警告信息并拒绝远程访问
protected-mode yes 

#监听端口,默认6379/tcp
port 6379

#三次握手的时候server端收到client ack确认号之后的队列值,即全连接队列长度timeout 0 #客户端和Redis服务端的连接超时时间,默认是0,表示永不超时
tcp-backlog 511 

#tcp 会话保持时间300s
tcp-keepalive 300 

daemonize no #默认no,即直接运行redis-server程序时,不作为守护进程运行,而是以前台方式运行,如果想在后台运行需改成yes,当redis作为守护进程运行的时候,它会写一个 pid 到/var/run/redis.pid 文件

supervised no #和OS相关参数,可设置通过upstart和systemd管理Redis守护进程,centos7后都使用systemd

pidfile /var/run/redis_6379.pid #pid文件路径,可以修改为/apps/redis/run/redis_6379.pid

loglevel notice #日志级别

logfile "/path/redis.log" #日志路径,示例:logfile "/apps/redis/log/redis_6379.log"databases 16 #设置数据库数量,默认:0-15,共16个库

always-show-logo yes #在启动redis 时是否显示或在日志中记录记录redis的logo 

save 900 1 #在900秒内有1个key内容发生更改,就执行快照机制
save 300 10 #在300秒内有10个key内容发生更改,就执行快照机制
save 60 10000  #60秒内如果有10000个key以上的变化,就自动快照备份

stop-writes-on-bgsave-error yes #默认为yes时,可能会因空间满等原因快照无法保存出错时,会禁止redis写入操作,生产建议为no 
                                #此项只针对配置文件中的自动save有效

rdbcompression yes #持久化到RDB文件时,是否压缩,"yes"为压缩,"no"则反之 

rdbchecksum yes #是否对备份文件开启RC64校验,默认是开启

dbfilename dump.rdb #快照文件名

dir ./ #快照文件保存路径,示例:dir "/apps/redis/data"
#主从复制相关

# replicaof <masterip> <masterport> #指定复制的master主机地址和端口,5.0版之前的指令为slaveof 

# masterauth <master-password> #指定复制的master主机的密码

replica-serve-stale-data yes #当从库同主库失去连接或者复制正在进行,从机库有两种运行方式:
1、设置为yes(默认设置),从库会继续响应客户端的读请求,此为建议值
2、设置为no,除去特定命令外的任何请求都会返回一个错误"SYNC with master in progress"。

replica-read-only yes #是否设置从库只读,建议值为yes,否则主库同步从库时可能会覆盖数据,造成数据丢失

repl-diskless-sync no #是否使用socket方式复制数据(无盘同步),新slave第一次连接master时需要做数据的全量同步,redis server就要从内存dump出新的RDB文件,然后从master传到slave,有两种方式把RDB文件传输给客户端:
1、基于硬盘(disk-backed):为no时,master创建一个新进程dump生成RDB磁盘文件,RDB完成之后由父进程(即主进程)将RDB文件发送给slaves,此为默认值
2、基于socket(diskless):master创建一个新进程直接dump RDB至slave的网络socket,不经过主进程和硬盘

#推荐使用基于硬盘(为no),是因为RDB文件创建后,可以同时传输给更多的slave,但是基于socket(为yes), 新slave连接到master之后得逐个同步数据。只有当磁盘I/O较慢且网络较快时,可用diskless(yes),否则一般建议使用磁盘(no)

repl-diskless-sync-delay 5 #diskless时复制的服务器等待的延迟时间,设置0为关闭,在延迟时间内到达的客户端,会一起通过diskless方式同步数据,但是一旦复制开始,master节点不会再接收新slave的复制请求,直到下一次同步开始才再接收新请求。即无法为延迟时间后到达的新副本提供服务,新副本将排队等待下一次RDB传输,因此服务器会等待一段时间才能让更多副本到达。推荐值:30-60

repl-ping-replica-period 10 #slave根据master指定的时间进行周期性的PING master,用于监测master状态,默认10s 

repl-timeout 60 #复制连接的超时时间,需要大于repl-ping-slave-period,否则会经常报超时 

repl-disable-tcp-nodelay no #是否在slave套接字发送SYNC之后禁用 TCP_NODELAY,如果选择"yes",Redis将合并多个报文为一个大的报文,从而使用更少数量的包向slaves发送数据,但是将使数据传输到slave上有延迟,Linux内核的默认配置会达到40毫秒,如果 "no" ,数据传输到slave的延迟将会减少,但要使用更多的带宽 

repl-backlog-size 512mb #复制缓冲区内存大小,当slave断开连接一段时间后,该缓冲区会累积复制副本数据,因此当slave 重新连接时,通常不需要完全重新同步,只需传递在副本中的断开连接后没有同步的部分数据即可。只有在至少有一个slave连接之后才分配此内存空间,建议建立主从时此值要调大一些或在低峰期配置,否则会导致同步到slave失败 

repl-backlog-ttl 3600 #多长时间内master没有slave连接,就清空backlog缓冲区 

replica-priority 100 #当master不可用,哨兵Sentinel会根据slave的优先级选举一个master,此值最低的slave会优先当选master,而配置成0,永远不会被选举,一般多个slave都设为一样的值,让其自动选择
#min-replicas-to-write 3 #至少有3个可连接的slave,mater才接受写操作
#min-replicas-max-lag 10 #和上面至少3个slave的ping延迟不能超过10秒,否则master也将停止写操作 

requirepass foobared #设置redis连接密码,之后需要AUTH pass,如果有特殊符号,用" "引起来,生产建议设置 

rename-command #重命名一些高危命令,示例:rename-command FLUSHALL "" 禁用命令
 &nbsp; #示例: rename-command del 123456 

maxclients 10000   #Redis最大连接客户端 

maxmemory <bytes> #redis使用的最大内存,单位为bytes字节,0为不限制,建议设为物理内存一半,8G内存的计算方式8(G)*1024(MB)1024(KB)*1024(Kbyte),需要注意的是缓冲区是不计算在maxmemory内,生产中如果不设置此项,可能会导致OOM 

appendonly no #是否开启AOF日志记录,默认redis使用的是rdb方式持久化,这种方式在许多应用中已经足够用了,但是redis如果中途宕机,会导致可能有几分钟的数据丢失(取决于dump数据的间隔时间),根据save来策略进行持久化,Append Only File是另一种持久化方式,可以提供更好的持久化特性,Redis会把每次写入的数据在接收后都写入 appendonly.aof 文件,每次启动时Redis都会先把这个文件的数据读入内存里,先忽略RDB文件。默认不启用此功能 

appendfilename "appendonly.aof" #文本文件AOF的文件名,存放在dir指令指定的目录中 

appendfsync everysec #aof持久化策略的配置
#no表示由操作系统保证数据同步到磁盘,Linux的默认fsync策略是30秒,最多会丢失30s的数据
#always表示每次写入都执行fsync,以保证数据同步到磁盘,安全性高,性能较差
#everysec表示每秒执行一次fsync,可能会导致丢失这1s数据,此为默认值,也生产建议值

#同时在执行bgrewriteaof操作和主进程写aof文件的操作,两者都会操作磁盘,而bgrewriteaof往往会涉及大量磁盘操作,这样就会造成主进程在写aof文件的时候出现阻塞的情形,以下参数实现控制 

no-appendfsync-on-rewrite no #在aof rewrite期间,是否对aof新记录的append暂缓使用文件同步策略,主要考虑磁盘IO开支和请求阻塞时间。#默认为no,表示"不暂缓",新的aof记录仍然会被立即同步到磁盘,是最安全的方式,不会丢失数据,但是要忍受阻塞的问题
#为yes,相当于将appendfsync设置为no,这说明并没有执行磁盘操作,只是写入了缓冲区,因此这样并不会造成阻塞(因为没有竞争磁盘),但是如果这个时候redis挂掉,就会丢失数据。丢失多少数据呢?Linux默认fsync策略是30秒,最多会丢失30s的数据,但由于yes性能较好而且会避免出现阻塞因此比较推荐
#rewrite 即对aof文件进行整理,将空闲空间回收,从而可以减少恢复数据时间 

auto-aof-rewrite-percentage 100 #当Aof log增长超过指定百分比例时,重写AOF文件,设置为0表示不自动重写Aof日志,重写是为了使aof体积保持最小,但是还可以确保保存最完整的数据 

auto-aof-rewrite-min-size 64mb #触发aof rewrite的最小文件大小 

aof-load-truncated yes #是否加载由于某些原因导致的末尾异常的AOF文件(主进程被kill/断电等),建议yes 

aof-use-rdb-preamble no #redis4.0新增RDB-AOF混合持久化格式,在开启了这个功能之后,AOF重写产生的文件将同时包含RDB格式的内容和AOF格式的内容,其中RDB格式的内容用于记录已有的数据,而AOF格式的内容则用于记录最近发生了变化的数据,这样Redis就可以同时兼有RDB持久化和AOF持久化的优点(既能够快速地生成重写文件,也能够在出现问题时,快速地载入数据),默认为no,即不启用此功能 

lua-time-limit 5000 #lua脚本的最大执行时间,单位为毫秒 

cluster-enabled yes #是否开启集群模式,默认不开启,即单机模式 

cluster-config-file nodes-6379.conf #由node节点自动生成的集群配置文件名称 

cluster-node-timeout 15000 #集群中node节点连接超时时间,单位ms,超过此时间,会踢出集群 

cluster-replica-validity-factor 10 #单位为次,在执行故障转移的时候可能有些节点和master断开一段时间导致数据比较旧,这些节点就不适用于选举为master,超过这个时间的就不会被进行故障转移,不能当选master,计算公式:(node-timeout * replica-validity-factor) + repl-pingreplica-period 

cluster-migration-barrier 1 #集群迁移屏障,一个主节点至少拥有1个正常工作的从节点,即如果主节点的slave节点故障后会将多余的从节点分配到当前主节点成为其新的从节点。 

cluster-require-full-coverage yes #集群请求槽位全部覆盖,如果一个主库宕机且没有备库就会出现集群槽位不全,那么yes时redis集群槽位验证不全,就不再对外提供服务(对key赋值时,会出现CLUSTERDOWN The cluster is down的提示,cluster_state:fail,但ping 仍PONG),而no则可以继续使用,但是会出现查询数据查不到的情况(因为有数据丢失) 

cluster-replica-no-failover no #如果为yes,此选项阻止在主服务器发生故障时尝试对其主服务器进行故障转移。 但是,主服务器仍然可以执行手动强制故障转移,一般为no
#Slow log 是 Redis 用来记录超过指定执行时间的日志系统,执行时间不包括与客户端交谈,发送回复等I/O操作,而是实际执行命令所需的时间(在该阶段线程被阻塞并且不能同时为其它请求提供服务),由于slow log 保存在内存里面,读写速度非常快,因此可放心地使用,不必担心因为开启 slow log 而影响Redis 的速度 

slowlog-log-slower-than 10000 #以微秒为单位的慢日志记录,为负数会禁用慢日志,为0会记录每个命令操作。默认值为10ms,一般一条命令执行都在微秒级,生产建议设为1ms-10ms之间 

slowlog-max-len 128 #最多记录多少条慢日志的保存队列长度,达到此长度后,记录新命令会将最旧的命令从命令队列中删除,以此滚动删除,即,先进先出,队列固定长度,默认128,值偏小,生产建议设为1000以上 

CONFIG动态修改配置 config 命令用于查看当前redis配置、以及不重启redis服务实现动态更改redis配置等 注意:不是所有配置都可以动态修改,且此方式无法持久保存

CONFIG SET parameter value
config   set  参数值
时间复杂度:O(1)
CONFIG SET 命令可以动态地调整 Redis 服务器的配置(configuration)而无须重启。

可以使用它修改配置参数,或者改变 Redis 的持久化(Persistence)方式。
CONFIG SET 可以修改的配置参数可以使用命令 CONFIG GET * 来列出,所有被 CONFIG SET 修改的配
置参数都会立即生效。

CONFIG GET parameter
时间复杂度: O(N),其中 N 为命令返回的配置选项数量。
CONFIG GET 命令用于取得运行中的 Redis 服务器的配置参数(configuration parameters),在
Redis 2.4 版本中, 有部分参数没有办法用 CONFIG GET 访问,但是在最新的 Redis 2.6 版本中,所
有配置参数都已经可以用 CONFIG GET 访问了。

CONFIG GET 接受单个参数 parameter 作为搜索关键字,查找所有匹配的配置参数,其中参数和值以“键-
值对”(key-value pairs)的方式排列。
比如执行 CONFIG GET s* 命令,服务器就会返回所有以 s 开头的配置参数及参数的值:

持久化

Redis 虽然是一个内存级别的缓存程序,也就是redis 是使用内存进行数据的缓存的,但是其可以将内存的数据按照一定的策略保存到硬盘上,从而实现数据持久保存的目的目前redis支持两种不同方式的数据持久化保存机制,分别是RDB和AOF

Redis是基于内存的非关系型K-V数据库,既然它是基于内存的,如果Redis服务器挂了,数据就会丢失。为了避免数据丢失了,Redis提供了持久化,即把数据保存到磁盘。(K-V数据库指的是使用键值(key-value)存储的数据库,其数据按照键值对的形式进行组织、索引和存储。

持久化功能:Redis是内存数据库,所有数据都是保存在内存中,为了避免服务器断电等原因导致Redis进程异常退出后数据永久丢失,需要定期将Redis中的数据以某种形式(数据或者命令)从内存保存到硬盘;当下次Redis重启时,利用持久化文件实现数据恢复。除此之外为了进行灾难备份,可以持久将文件拷贝到一个远程位置(比如备份服务器)。

Redis 提供两种方式进行持久化:

  • RDB 持久化:原理是将Redis在内存中的数据库记录 定时保存到磁盘上
  • AOF 持久化(append only file):原理是将Redis的 操作日志已追加的方式写入文件,类似于mysql的 binlog

由于AOF的持久性实时性更好,即发生特殊情况导致数据丢失时,丢失的数据更少,因此是目前主流的持久化方式,不过RDB持久化仍然有其用武之地

持久化的具体流程: image

RDB

RDB模式工作原理就是把内存数据以快照的形式保存到磁盘上。 RDB持久化,是指在指定的时间间隔内,执行指定次数的写操作,将内存中的数据集快照写入磁盘中,它是Redis默认的持久化方式。执行完操作后,在指定目录下会生成一个dump.rdb文件,Redis 重启的时候,通过加载dump.rdb文件来恢复数据。 image

ave 9001 &nbsp; &nbsp; &nbsp; &nbsp; #900s内修改了1个key即触发保存RDB
save 30010 &nbsp; &nbsp; &nbsp; &nbsp;#300s内修改了10个key即触发保存RDB
save 6010000 &nbsp; &nbsp; &nbsp;#60s内修改了10000个key即触发保存RDB
dbfilename dump.rdb
dir ./ &nbsp; &nbsp; &nbsp; &nbsp; #编泽编译安装,默认RDB文件存放在启动redis的工作目录,建议明确指定存入目录stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes

save m n 自动触发最常见的情况是在配置文件中通过save m n,指定当m秒内发生n次变化时,会触发bgsave

vim /etc/redis/6379.conf
--219行--以下三个save条件满足任意一个时,都会引起bgsave的调用
save 900 1 :当时间到900秒时,如果redis数据发生了至少1次变化,则执行bgsave
save 300 10 :当时间到300秒时, 如果redis数据发生了至少10次变化,则执行bgsave
save 60 10000 :当时间到60秒时,如果redis数据发生了至少10000次变化, 则执行bgsave

--242行--是否开启RDB文件压缩
rdbcompression yes

--254行--指定RDB文件名
dbfilename dump.rdb

--264行--指定RDB文件和AOF文件所在目录
dir /var/lib/redis/6379

RDB优点: 适合大规模的数据恢复场景,如备份,全量复制等

RDB缺点:

  • 没办法做到实时持久化/秒级持久化。 一旦发生故障停机,你就可能会一段时间的数据。
  • 新老版本存在RDB格式兼容问题

AOF模式

AppendOnylFile 持久化,采用日志的形式来记录每个写操作,追加到文件中,重启时再重新执行AOF文件中的命令来恢复数据。它主要解决数据持久化的实时性问题。默认是不开启的。

注意: AOF 模式默认是关闭的,第一次开启AOF后,并重启服务生效后,会因为AOF的优先级高于RDB,而AOF默认没有数据文件存在,从而导致所有数据丢失 image

AOF优点: 数据的一致性和完整性更高

AOF缺点:

OF记录的内容越多,文件越大,数据恢复变慢。

相关配置:

appendonly no #是否开启AOF日志记录,默认redis使用的是rdb方式持久化,这种方式在许多应用中已经足够用了,但是redis如果中途宕机,会导致可能有几分钟的数据丢失(取决于dump数据的间隔时间),根据save来策略进行持久化,Append Only File是另一种持久化方式,可以提供更好的持久化特性,Redis会把每次写入的数据在接收后都写入 appendonly.aof 文件,每次启动时Redis都会先把这个文件的数据读入内存里,先忽略RDB文件。默认不启用此功能

存放路径  默认和rdb 存放在一起   共用  dir  选项 
appendfilename "appendonly.aof"#文本文件AOF的文件名,存放在dir指令指定的目录中 

#在700行左右
700 appendonly no

700 appendonly yes 


appendfsync everysec #aof持久化策略的配置
#no表示由操作系统保证数据同步到磁盘,Linux的默认fsync策略是30秒,最多会丢失30s的数据
#always表示每次写入都执行fsync,以保证数据同步到磁盘,安全性高,性能较差
#everysec表示每秒执行一次fsync,可能会导致丢失这1s数据,此为默认值,也生产建议值

#重新规则rewrite

no-appendfsync-on-rewrite yes
auto-aof-rewrite-percentage 100 
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes

AOF rewrite 重写配置

#同时在执行bgrewriteaof操作和主进程写aof文件的操作,两者都会操作磁盘,而bgrewriteaof往往会涉及大量磁盘操作,这样就会造成主进程在写aof文件的时候出现阻塞的情形,以下参数实现控制

no-appendfsync-on-rewrite no #在aof rewrite期间,是否对aof新记录的append暂缓使用文件同步策略,主要考虑磁盘IO开支和请求阻塞时间。
#默认为no,表示"不暂缓",新的aof记录仍然会被立即同步到磁盘,是最安全的方式,不会丢失数据,但是要忍受阻塞的问题
#为yes,相当于将appendfsync设置为no,这说明并没有执行磁盘操作,只是写入了缓冲区,因此这样并不会造成阻塞(因为没有竞争磁盘),但是如果这个时候redis挂掉,就会丢失数据。丢失多少数据呢?Linux 的默认fsync策略是30秒,最多会丢失30s的数据,但由于yes性能较好而且会避免出现阻塞因此比较推荐



#rewrite 即对aof文件进行整理,将空闲空间回收,从而可以减少恢复数据时间
auto-aof-rewrite-percentage 100#当Aof log增长超过指定百分比例时,重写AOF文件,设置为0表示不自动重写Aof日志,重写是为了使aof体积保持最小,但是还可以确保保存最完整的数据

auto-aof-rewrite-min-size 64mb #触发aof rewrite的最小文件大小

aof-load-truncated yes#是否加载由于某些原因导致的末尾异常的AOF文件(主进程被kill/断电等),建议yes

RDB和AOF的选择

  • 如果主要充当缓存功能,或者可以承受数分钟数据的丢失, 通常生产环境一般只需启用RDB即可,此也是默认值
  • 如果数据需要持久保存,一点不能丢失,可以选择同时开启RDB和AOF
  • 一般不建议只开启AOF
内容大纲
批注笔记
📚 redis
ArticleBot
z
z
z
z
主页
会议室
Git管理
文章
云文档
看板