redis(2)

redis 配置和优化

一、redis主要配置

  • redis常用配置参数
cat /apps/redis/etc/redis_6379.conf
bind 0.0.0.0 #监听地址,可以使用空格隔开后多个监听IP
protected-mode yes #redis3.2之后加入的新特性,在没有设置bind IP和密码的时候,redis只允许访问127.0.0.1:6379,可以远程连接,但当访问将提示警告信息并拒绝远程访问
port 6379 #监听端口,默认6379/tcp
tcp-backlog 511 #三次握手的时候server端收到client ack确认号之后的队列值,即全连接队列长度
timeout 0 # 客户端和Redis服务端的连接超时时间,默认是0秒,表示永不超时
tcp-keepalive 300 #tcp 会话保持时间300s
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/redos/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”为压缩,
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创建一个新进程直接dumpRDB至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不可用,哨兵Sential会根据slave的优先级选举一个master,此值最低的slave会当选master,而配置成0,永远不会被选举,一般多个slave都设为一样的值,让其自动选择
# min-replicas-to-write 3 # 至少有3个可连接的slave,master才接受写操作
# min-replicas-max-lag 10 # 和上面至少3个slave的ping延迟不能超过10秒,否则master也将停止写操作
requirepass foobard # 设置redis连接密码,之后取消AUTH pass,如果有特殊复合,用" "引起来,生产建议设置
rename-command # 重命名一些高危命令,示例:rename-command FLUSHALL "" 禁用命令
# 示例:rename-command del areyouok
  • 客户端配置
maxclients 10000 # Redis最大连接客户端
maxmemory <bytes> #redis使用的最大内存,单位为bytes字节,0为不限制,建议设为物理内存一半,8G内存的计算方式8(G)*1024(MB)*1024(kbyte),需要注意的是缓冲区是不计算在maxmemory内,生产中如果不设置此项,可能会导致OOM
appendonly no # 是否开启AOF日志记录,默认redis使用的是rdb方式持久化,这种方式在许多应用中已经足够用了,但是redis如果中途宕机,会导致可能有几分钟的数据丢失(取决于dump数据的间隔时间),根据save策略来进行持久化,Append Onnly 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秒,最多会丢失30秒的数据,但由于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
auto-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-migrantion-barrier 1 #集群迁移屏障,一个主节点至少拥有1个正常工作的从节点,即如果主节点的salve节点故障后会将多余的从节点分配到当前主节点成为其新的从节点。
cluster-require-full-coverage yes #集群请求槽位全部覆盖,覆盖一个主库宕机且没有备库就会出现集群槽位不全,那么yes时redis集群槽位验证不全,就不再对外提供服务(对key赋值时,会出现CLUSTERDOWN The cluster is down提示,cluster_state:fail,但ping仍PONG),而no则可以继续使用,但是会出现查询数据查不到的情况(因为有数据丢失)。生成建议为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
slowlog-max-len 128 #最多记录多少条慢日志的保存队列长度,达到此长度后,记录新命令会将最旧的命令从命令队列中删除,以此滚动删除,即,先进先出,队列固定长度,默认128,值偏小,生产建议设为1000以上

二、CONFIG动态修改配置

  • config命令用于查看当前redis配置、以及不重启redis服务实现动态更改redis配置等
  • 注意:不是所有配置都可以动态修改,且此方式无法持久保存
redis 127.0.0.1:6379> config set parameter value
时间复杂度:O(1)
config set 命令可以动态地调整redis服务器的配置(configuration)而无须重启
redis 127.0.0.1:6379> config get slowlog-max-len
1) "slowlog-max-len"
2) "1024"
redis 127.0.0.1:6379> config set slowlog-max-len 1000
ok
redis 127.0.0.1:6379> config get slowlog-max-len
1) "slowlog-max-len"
2) "1000"

设置连接密码

# 设置连接密码
redis 127.0.0.1:6379> config set requirepass linux
OK
# 查看连接密码
redis 127.0.0.1:6379> config get requirepass
1) "requirepass"
2) "linux"

获取当前配置

#奇数行为键,偶数行为值
127.0.0.1:6379> config get *
# 查看bind
127.0.0.1:6379> config get bind
1) "bind"
2) "0.0.0.0"
# 有些设置无法修改
127.0.0.1:6379> config set bind 127.0.0.1

更改最大内存

127.0.0.1:6379> config set maxmemory 8589934592
OK
127.0.0.1:6379> config get maxmemory
1) "maxmemory"
2) "8589934592"

三、慢查询

img

  • 可以通过config set命令动态修改参数,并使配置持久化到配置文件中
config set slowlog-log-slower-than 20000
config set slowlog-max-len 1000
config rewrite
  • 获取慢查询日志,将查询的时间改为1微秒
127.0.0.1:6379> config set slowlog-log-slower-than 1
OK
127.0.0.1:6379> config set slowlog-max-len 1000
OK
127.0.0.1:6379> slowlog len
# 获取慢查询日志列表当前的长度
(integer) 2
127.0.0.1:6379> slowlog get


  • 可以看到每个慢查询日志有4个属性组成,分别是慢查询日志的标记id、发生时间戳、命令耗时、执行命令和参数
  • 慢查询日志重置
127.0.0.1:6379> slowlog reset
OK
127.0.0.1:6379> slowlog len
(integer) 0

四、redis持久化

Redis虽然是一个内存级别的缓存程序,也就是redis是使用内存进行数据的缓存的,但是其可以将内存的数据按照一定的策略保存到硬盘上,从而实现数据持久保存的目的

目前redis支持两种不同方式的数据持久化保存机制,分别是RDB和AOF

RDB 模式

RDB 模式工作原理

img

RDB(Redis DataBase):基于时间的快照,其默认只保留当前最新的一次快照,特点是执行速度比较快,缺点是可能会丢失从上次快照到当前时间点直接未做快照的数据

RDB bgsave实现快照的具体过程

img

  • Redis从master主进程先fork出一个子进程,使用写时复制机制,子进程将内存的数据保存为一个临时文件
  • 当数据保存完成之后再将上一次保存的RDB文件替换掉,然后关闭子进程,这样可以保证每一次做RDB快照保存的数据都是完整的
  • 因为直接替换RDB文件的时候,可能会出现突然断电等问题,而导致RDB文件还没保存完整就因为突然关机停止保存,而导致数据丢失的情况。后续可以手动将每次生成的RDB文件进行备份,这样可以最大化保存历史数据
pstree -p |grep redis-server; ll -h /apps/redis/data

RDB 相关配置
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rbdchecksum yes
dbfilename dump.rdb
dir /var/lib/redis #编译按照,默认rdb文件存放在启动redis的工作目录,建议明确指定存入目录
实现RDB方式
  • save:同步,会阻塞其他命令,不推荐使用
  • bgsave:异步后台执行,不影响其他命令的执行
  • 自动:制定规则,自动执行
RDB 模式优点
  • RDB快照保存了某个时间点的数据,可以通过脚本执行redis指令bgsave或save命令自定义时间点备份,可以保留多个备份,当出现问题可以恢复到不同时间点的版本,很适合备份,并且文件格式也支持有不少第三方工具可以进行后续的数据分析
  • 比如:可以在最近的24小时内,每小时备份一次RDB文件,并且在每个月的每一天,也备份一个RDB文件。这样的话,即时遇上问题,也可以随时将数据集还原到不同的版本。
  • RDB可以最大化Redis性能,父进程在保存RDB文件时唯一要做的就是fork出一个子进程,然后这个子进程就会处理接下来的所有保存工作,父进程无须执行任何磁盘I/O工作。
  • RDB在大量数据,比如几个G的数据,恢复的速度比AOF的快
RDB 模式缺点
  • 不能实时保存数据,可能会丢失自上一次执行RDB备份到当时的内存数据
  • 如果需要尽量避免在服务器故障时丢失数据,那么RDB不合适。虽然Redis运行设置不同的保存点(save point)来控制保存RDB文件的频率,但是,因为RDB文件需要保存整个数据集的状态,所以它并不是一个轻松的操作。因此可能会至少5分钟才保存一次RDB文件。在这种情况下,一旦发生故障停机,就可能会丢失好几分钟的数据。
  • 当数据量非常大的时候,从父进程fork子进程进行保存至RDB文件时需要一点时间,可能是毫秒或者秒,取决于磁盘IO性能
  • 在数据集比较庞大时,fork()可能会非常耗时,造成服务器在一定时间内停止处理客户端:如果数据集非常巨大,并且CPU时间非常紧张的话,那么这种停止时间甚至可能会长达整整一秒或更久。虽然AOF重写也需要进行fork(),但无论AOF重写的执行间隔有多长,数据的持久性都不会有任何损失。

img

  1. 执行bgsave命令,redis父进程判断当前是否存在正在执行的子进程,如RDB/AOF子进程,如果存在bgsave命令直接返回。
  2. 父进程执行fork操作创建子进程,fork操作过程中父进程会阻塞,通过info status命令查看latest_fork_usec选项,可以获取最近一个fork操作的耗时,单位为微秒。
  3. 父进程fork完成之后,bgsave命令返回“background saving started”信号 并不再阻塞父进程,可以继续响应其他命令。
  4. 子进程创建RDB文件,根据父进程内存生成临时快照文件,完成后对原有文件进行子替换。执行lastsave命令可以获取最后一次生成RDB的时间,对应info统计的rdb_last_save_time选项。
  5. 进程发送信号给父进程表示完成,父进程更新统计信息

AOF 模式

AOF 模式工作原理
  • AOF:AppendOnlyFile,按照操作顺序一次将操作追加到指定的日志文件末尾
  • AOF和RDB一样使用了写时复制机制,AOF默认为每秒钟fsync一次,即将执行的命令保存到AOF文件中,这样即使redis服务器发送故障的话最多只丢失一秒钟之内的数据,也可以设置不同的sync策略always,即设置每次执行命令的时候执行fsync,fsync会在后台执行线程,所以主线程可以继续处理用户的正常请求而不受到写入AOF文件的I/O影响
  • 同时启动RDB和AOF,进行恢复时,默认AOF文件优先级高于RDB文件,即会使用AOF文件进行恢复
  • 注意:AOF模式默认是关闭的,第一次开启AOF后,并重启服务生效后,会因为AOF的优先级高于RDB,而AOF第一次默认没有文件内容存在,从而导致所有数据丢失,因为启动时会去读数据文件,读AOF文件
AOF rewrite 重写

将一些重复的,可以合并的,过期的数据重新写入一个新的AOF文件,从而节约AOF备份占用的磁盘空间,也能加速恢复过程

可以手动执行bgrewriteaof触发AOF,或定义自动rewrite策略

AOF rewrite 过程

img

1.执行AOF重写请求

2.父进程执行fork创建子进程,开销等同于bgsave过程。

3.1主进程fork操作完成后,继续响应其他命令。所有修改命令依然写入AOF缓冲区并根据appendfsync策略同步到硬盘,保证原有AOF机制正确性。

3.2由于fork操作运用写时复制技术,子进程只能共享fork操作时的内存数据。由于父进程依然响应命令,Redis使用“AOF重写缓冲区”保存这部分新数据,防止新AOF文件生成期间丢失这部分数据。

4.子进程根据内存快照,快照命令合并规则写入到新的AOF文件。每次批量写入硬盘数据量由配置aof-rewrite-incremental-fsync控制,默认为32MB,防止单次刷盘数据过多造成硬盘阻塞。

5.1新AOF文件写入完成后,子进程发送信号给父进程,父进程更新统计信息,具体见info persistence下的aof_*相关统计。

5.2父进程把AOF重写缓冲区的数据写入到新的AOF文件

5.3使用新AOF文件替换老文件,完成AOF重写。

# 用aof功能的正确方式
ll
redis-cli
127.0.0.1:6379> config get appendonly

127.0.0.1:6379> config set appendonly yes
127.0.0.1:6379> config rewrite

ll

AOF 相关配置
appendonly yes
appendfilename "appendonly.aof" 
appendfsync everysec 
dir /path
no-appendfsync-on-rewrite yes
auto-aof-rewrite-percentage 100 
auto-aof-rewrite-min-size 64mb 
aof-load-truncated yes
AOF 模式优点
  • 数据安全性相对较高,根据所使用的fsync策略,默认是appendfsync everysec,即每秒执行一次fsync,在这种配置下,redis仍然可以保存良好的性能,并且就算发生故障停机,也最多只会丢失一秒钟的数据
  • 由于该机制对日志文件的写入操作采用的是append模式,因此在写入过程中不需要seek,即使出现宕机现象,也不会破坏日志文件中已经存在的内容。然而如果本次操作只是写入了一半数据就出现了系统崩溃问题,不用担心,在redis下一次启动之前,可以通过redis-check-aof工具来解决数据一致性的问题
  • redis可以在aof文件体积变大过大时,自动地在后台对aof进行重写,重写后的新aof文件包含了恢复当前数据集所需的最小命令集合。整个重写操作是绝对安全的,因为redis在创建新aof文件的过程中,append模式不断的将修改数据追加到现有的aof文件里面,即使重写过程中发生停机,现有的aof文件也不会丢失。而一旦新aof文件创建完毕,redis就会从旧aof文件切换到新aof文件,并开始对新aof文件进行追加操作。
  • aof包含一个格式清晰、易于理解的日志文件用于记录所有的修改操作。事实上,也可以通过该文件完成数据的重建。
  • aof文件有序地保存了对数据库执行的所有写入操作,这些写入操作以redis协议的格式保存,因此aof文件的内容非常容易被人读懂,对文件进行分析也很轻松。导出aof文件也非常简单:举个例子,如果你不小心执行了flushall命令,但只要aof文件未被重写,那么只要停止服务,移除aof文件末尾的flushall命令,并重启redis,就可以将数据集恢复到flushall之前的状态。
AOF 模式缺点
  • 即使有些操作是重复的也会全部记录,AOF文件大小要大于RDB格式的文件
  • AOF在恢复大数据集时的速度比RDB的恢复速度要慢
  • 根据fsync策略不同,AOF速度可能会鳗鱼RDB
  • bug出现的可能性更多

RDB和AOF的选择

如果主要充当缓存功能,或者可以承受数分钟数据的丢失,通常生产环境一般只需启用RDB即可,此也是默认值

如果数据需要持久保存,一点不能丢失,可以选择同时开启RDB和AOF,一般不建议只开启AOF

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值