docker部署redis持久化存储

一.redis容器部署

  • 下载redis镜像
# docker pull redis:3.2.12
  • 启动redis容器
# docker run -itd --restart=unless-stopped -v /etc/localtime:/etc/localtime -v /etc/timezone:/etc/timezone --name redis -p 16379:6379 redis:3.2.12  --requirepass 123456

注意:

安装redis时,需要将连接信息保存至安全的文件中,如上,需要保存以下信息:

Redis:
连接IP:redis服务器内网IP
连接端口:16379
连接密码:123456

二. redis持久化部署

  • 下载redis镜像
# docker pull redis:3.2.12
  • 创建redis挂载目录
# mkdir -p /opt/docker/redis/
  • 编写redis主配置文件
# vim /opt/docker/redis/redis.conf 

bind 0.0.0.0                #允许任何人连接
protected-mode no           #不启用保护模式
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize no
supervised no
pidfile /var/run/redis_6379.pid
loglevel notice
logfile ""
databases 16
#save 900 1
#save 300 10
#save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir ./
slave-serve-stale-data yes
slave-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
slave-priority 100
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
aof-rewrite-incremental-fsync yes

redis配置文件详解

#bind 127.0.0.1        #指定redis只接收来自于该IP地址的请求,如果不进行设置,那么将处理所有请求
protected-mode no          #不启用保护模式
port 6379                   #指定redis运行的端口
tcp-backlog 511
timeout 0       #指定在一个 client 空闲多少秒之后关闭连接(0表示永不关闭)

tcp-keepalive 300  #单位是秒,表示将周期性的使用SO_KEEPALIVE检测客户端是否还处于健康状态,避免服务器一直阻塞,官方给出的建议值是300s,如果设置为0,则不会周期性的检测
daemonize no    #默认情况下,redis 不是在后台运行的,如果需要在后台运行,把该项的值更改为yes
supervised no   #没有监督互动
pidfile /var/run/redis_6379.pid #当Redis 在后台运行的时候,Redis 默认会把pid 文件放在/var/run/redis.pid,你可以配置到其他地址。当运行多个redis 服务时,需要指定不同的pid 文件和端口
loglevel notice  #log 等级分为4 级,debug, verbose, notice, 和warning。生产环境下一般开启notice
logfile ""     #配置log 文件地址,默认使用标准输出,即打印在命令行终端的窗口上
databases 16  #设置数据库的个数,可以使用SELECT <dbid>命令来切换数据库。默认使用的数据库是0

#redis数据RDB持久化配置,根据给定的时间间隔和写入次数将数据保存到磁盘
save 900 1   # 900 秒内如果至少有 1 个 key 的值变化,则保存
save 300 10  # 300 秒内如果至少有 10 个 key 的值变化,则保存
save 60 10000   # 60 秒内如果至少有 10000 个 key 的值变化,则保存

stop-writes-on-bgsave-error yes  #如果用户开启了RDB快照功能,那么在redis持久化数据到磁盘时如果出现失败,默认情况下,redis会停止接受所有的写请求。此配置可以让用户很明确的知道内存中的数据和磁盘上的数据已经存在不一致了。
rdbcompression yes    #存储至本地数据库时(持久化到rdb文件)是否压缩数据,默认为yes
rdbchecksum yes  # 在存储快照后,我们还可以让redis使用CRC64算法来进行数据校验,但是这样做会增加大约10%的性能消耗,如果希望获取到最大的性能提升,可以关闭此功能。
dbfilename dump.rdb
dir ./    # 数据库镜像备份的文件放置的路径,AOF文件也会存放在这个目录下面
slave-serve-stale-data yes # 当从库同主机失去连接或者复制正在进行,如果slave-serve-stale-data设置为yes(默认设置),从库会继续相应客户端的请求
slave-read-only yes  # 你可以配置一个 slave 实体是否接受写入操作。从 redis 2.6 版起,默认 slaves 都是只读的。
repl-diskless-sync no #主从数据复制是否使用无硬盘复制功能。
repl-diskless-sync-delay 5 #当启用无硬盘备份,服务器等待一段时间后才会通过套接字向从站传送RDB文件,这个等待时间是可配置的。延迟时间以秒为单位,默认为5秒。要关掉这一功能,只需将它设置为0秒,传送会立即启动。
repl-disable-tcp-nodelay no #同步之后是否禁用从站上的TCP_NODELAY,如果选择no,从站的数据延时不会那么多,但备份需要的带宽相对较多。
slave-priority 100  # 从站优先级是可以从redis的INFO命令输出中查到的一个整数。当主站不能正常工作时,redis sentinel使用它来选择一个从站并将它提升为主站。 默认优先级是100
appendonly yes  
#默认redis使用的是rdb方式持久化,这种方式在许多应用中已经足够用了。但是redis如果中途宕机,
#会导致可能有几分钟的数据丢失,根据save来策略进行持久化,Append Only File是另一种持久化方式,
#可以提供更好的持久化特性。Redis会把每次写入的数据在接收后都写入appendonly.aof文件,
#每次启动时Redis都会先把这个文件的数据读入内存里,先忽略RDB文件。
appendfilename "appendonly.aof"    #aof文件名
appendfsync everysec
#aof持久化策略的配置
#  no表示不执行fsync,由操作系统保证数据同步到磁盘,速度最快。
#  always表示每次写入都执行fsync,以保证数据同步到磁盘。
#  everysec表示每秒执行一次fsync,可能会导致丢失这1s数据

no-appendfsync-on-rewrite no
#在aof重写或者写入rdb文件的时候,会执行大量IO,此时对于everysec和always的aof模式来说,执行fsync会造成阻塞过长时间,no-appendfsync-on-rewrite字段设置为默认设置为no。
#如果对延迟要求很高的应用,这个字段可以设置为yes,否则还是设置为no,这样对持久化特性来说这是更安全的选择。
#设置为yes表示rewrite期间对新写操作不fsync,暂时存在内存中,等rewrite完成后再写入,默认为no,建议yes。

auto-aof-rewrite-percentage 100 #aof自动重写配置,当目前aof文件大小超过上一次重写的aof文件大小的百分之多少进行重写,即当aof文件增长到一定大小的时候,Redis能够调用bgrewriteaof对日志文件进行重写。
#当前AOF文件大小是上次日志重写得到AOF文件大小的二倍(设置为100)时,自动启动新的日志重写过程。

auto-aof-rewrite-min-size 64mb  # 设置允许重写的最小aof文件大小,避免了达到约定百分比但尺寸仍然很小的情况还要重写
aof-load-truncated yes
#aof文件可能在尾部是不完整的,当redis启动的时候,aof文件的数据被载入内存。
#重启可能发生在redis所在的主机操作系统宕机后,尤其在ext4文件系统没有加上data=ordered选项,出现这种现象redis宕机或者异常终止不会造成尾部不完整现象,可以选择让redis退出,或者导入尽可能多的数据。
#如果选择的是yes,当截断的aof文件被导入的时候,会自动发布一个log给客户端然后load。
#如果是no,用户必须手动redis-check-aof修复AOF文件才可以。

lua-time-limit 5000
#如果达到最大时间限制(毫秒),redis会记个log,然后返回error。
#当一个脚本超过了最大时限。只有SCRIPT KILL和SHUTDOWN NOSAVE可以用。第一个可以杀没有调write命令的东西。要是已经调用了write,只能用第二个命令杀

slowlog-log-slower-than 10000
# slog log是用来记录redis运行中执行比较慢的命令耗时。
#当命令的执行超过了指定时间,就记录在slow log中,slog  log保存在内存中,所以没有IO操作。
#执行时间比slowlog-log-slower-than大的请求记录到slowlog里面,单位是微秒,所以1000000就是1秒。
#注意,负数时间会禁用慢查询日志,而0则会强制记录所有命令。

slowlog-max-len 128
#慢查询日志长度。当一个新的命令被写进日志的时候,最老的那个记录会被删掉,这个长度没有限制。只要有足够的内存就行,你可以通过 SLOWLOG RESET 来释放内存

latency-monitor-threshold 0
#迟监控功能是用来监控redis中执行比较缓慢的一些操作,用LATENCY打印redis实例在跑命令时的耗时图表。
#只记录大于等于下边设置的值的操作,0的话,就是关闭监视。
# 默认延迟监控功能是关闭的,如果你需要打开,也可以通过CONFIG SET命令动态设置。

notify-keyspace-events ""
#键空间通知使得客户端可以通过订阅频道或模式,来接收那些以某种方式改动了 Redis 数据集的事件。因为开启键空间通知功能需要消耗一些 CPU ,所以在默认配置下,该功能处于关闭状态。

hash-max-ziplist-entries 512
#这个参数指的是ziplist中允许存储的最大条目个数,,默认为512,建议为128

hash-max-ziplist-value 64
# ziplist中允许条目value值最大字节数,默认为64,建议为1024

list-max-ziplist-size -2
#当取正值的时候,表示按照数据项个数来限定每个quicklist节点上的ziplist长度。比如,当这个参数配置成5的时候,表示每个quicklist节点的ziplist最多包含5个数据项。
#当取负值的时候,表示按照占用字节数来限定每个quicklist节点上的ziplist长度。这时,它只能取-1到-5这五个值,每个值含义如下:
#2: 每个quicklist节点上的ziplist大小不能超过8 Kb。(-2是Redis给出的默认值)

list-compress-depth 0
#这个参数表示一个quicklist两端不被压缩的节点个数

set-max-intset-entries 512
# 数据量小于等于set-max-intset-entries用intset,大于set-max-intset-entries用set

zset-max-ziplist-entries 128
zset-max-ziplist-value 64
#数据量小于等于zset-max-ziplist-entries用ziplist,大于zset-max-ziplist-entries用zset

hll-sparse-max-bytes 3000
#value大小小于等于hll-sparse-max-bytes使用稀疏数据结构(sparse)
#大于hll-sparse-max-bytes使用稠密的数据结构(dense),一个比16000大的value是几乎没用的,
#建议的value大概为3000。如果对CPU要求不高,对空间要求较高的,建议设置到10000左右

activerehashing yes
#Redis将在每100毫秒时使用1毫秒的CPU时间来对redis的hash表进行重新hash,可以降低内存的使用。
# 如果没有这么严格的实时性要求,可以设置为yes,以便能够尽可能快的释放内存

client-output-buffer-limit normal 0 0 0
#对客户端输出缓冲进行限制可以强迫那些不从服务器读取数据的客户端断开连接,用来强制关闭传输缓慢的客户端。
#对于normal client,第一个0表示取消hard limit,
#第二个0和第三个0表示取消soft limit,normal client默认取消限制,因为如果没有寻问,他们是不会接收数据的

client-output-buffer-limit slave 256mb 64mb 60
#对于pubsub client,如果client-output-buffer一旦超过32mb,又或者超过8mb持续60秒,那么服务器就会立即断开客户端连接。

client-output-buffer-limit pubsub 32mb 8mb 60
# 对于pubsub client,如果client-output-buffer一旦超过32mb,又或者超过8mb持续60秒,那么服务器就会立即断开客户端连接。

hz 10
# redis执行任务的频率为1s除以hz

aof-rewrite-incremental-fsync yes
# 在aof重写的时候,如果打开了aof-rewrite-incremental-fsync开关,系统会每32MB执行一次fsync。
  这对于把文件写入磁盘是有帮助的,可以避免过大的延迟峰值
  • 创建redis持久化数据挂载目录
# mkdir /opt/docker/redis/data
  • 启动redis容器
]# docker run -itd --restart=unless-stopped -v /etc/localtime:/etc/localtime -v /etc/timezone:/etc/timezone -v $(pwd)/redis/redis.conf:/usr/local/etc/redis/redis.conf -v $(pwd)/redis/data:/data --name redis -p 16379:6379 redis:3.2.12 redis-server /usr/local/etc/redis/redis.conf --requirepass 123456
27e72b706e40e01fbe1724b02faaf00930ed2be3d20314cb8b7e465a955fcc98

# docker ps
CONTAINER ID        IMAGE                  COMMAND                  CREATED             STATUS              PORTS                     NAMES
27e72b706e40        redis:3.2.12           "docker-entrypoint.s…"   4 seconds ago       Up 3 seconds        0.0.0.0:16379->6379/tcp   redis
  • 测试redis持久化

向redis内插入一条 key-value数据,查看持久化的存储文件内是否有数据

# docker exec -it redis sh                      #进入redis容器
# redis-cli                                               #连接redis
127.0.0.1:6379> auth Credit2016Admin                      #登录redis,输入redis密码
OK 
127.0.0.1:6379> keys *                                    #查看key
(empty list or set)
127.0.0.1:6379> set block_height 630                    #插入key-value数据
OK
127.0.0.1:6379> keys *                                  #再次查看key
1) "block_height"
127.0.0.1:6379> 
127.0.0.1:6379> get block_height                         #查看key的value值
"630"
127.0.0.1:6379> exit                                      #退出redis
# exit                                                    #退出redis容器
# ls

# cat /opt/docker/redis/data/appendonly.aof      #查看存储持久化数据的文件夹,是否已存入数据
*2
$6
SELECT
$1
0
*3
$3
set
$12
block_height
$3
630

三、扩展知识

3.1 redis两种持久化存储方式的区别

  • Redis是一种高级key-value数据库。它跟memcached类似,不过数据可以持久化,而且支持的数据类型很丰富。有字符串,链表,集 合和有序集合。支持在服务器端计算集合的并,交和补集(difference)等,还支持多种排序功能。所以Redis也可以被看成是一个数据结构服务 器。

  • Redis的所有数据都是保存在内存中,然后不定期的通过异步方式保存到磁盘上(这称为“半持久化模式”);也可以把每一次数据变化都写入到一个append only file(aof)里面(这称为“全持久化模式”)。

  • 由于Redis的数据都存放在内存中,如果没有配置持久化,redis重启后数据就全丢失了,于是需要开启redis的持久化功能,将数据保存到磁盘上,当redis重启后,可以从磁盘中恢复数据。redis提供两种方式进行持久化,一种是RDB持久化(原理是将Reids在内存中的数据库记录定时dump到磁盘上的RDB持久化),另外一种是AOF(append only file)持久化(原理是将Reids的操作日志以追加的方式写入文件)。

RDB持久化存储
  • RDB持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘,实际操作过程是fork一个子进程,先将数据集写入临时文件,写入成功后,再替换之前的文件,用二进制压缩存储。

  • RDB方式是通过快照完成的,当符合一定条件时Redis会自动将内存中的所有数据进行快照,并且存储到硬盘上。就像拍照一样,将这一瞬间的所有东西都保存下来。进行快照的条件在配置文件中指定。主要有两个参数构成:时间和改动的键值的个数,即当在指定时间内被更改的键的个数大于执行数值时,就会进行快照。RDB是Redis的默认持久化方式。

  • RDB持久化存储原理:
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nlq9cuf3-1619350872427)(https://segmentfault.com/img/remote/1460000018452698?w=699&h=490)]

1.执行bgsave命令,Redis父进程判断当前是否存在正在执行的子进程,如果存在则直接返回.

2.父进程fork一个子进程(fork的过程中会造成阻塞的情况),这个过程可以使用info stats命令查看latest_fork_usec选项,查看最近一次fork操作小号的时间,单位是微妙.

3.父进程fork完之后,则会返回Background saving started信息提示,此时fork阻塞解除.

4.fork出的子进程开始根据父进程内存数据生成临时的快照文件,然后替换原文件.使用lastsave命令可以查看最后一次生成rdb的时间,对应info的rdb_last_save_time选项.

5.当备份完毕之后向父进程发送完成信息,具体可以见info Persistence下的rbd_*选项.

  • RDB持久化的优势与劣势
    优势:

1.文件实现的数据快照,全量备份,便于数据的传输.比如我们需要把A服务器上的备份文件传输到B服务器上面,直接将rdb文件拷贝即可.

2.文件采用压缩的二进制文件,当重启服务时加载数据文件,比aof方式更快.

劣势:

1.rbd采用加密的二进制格式存储文件,由于Redis各个版本之间的兼容性问题也导致rdb由版本兼容问题导致无法在其他的Redis版本中使用.

2.时效性差,容易造成数据的不完整性.因为rdb并不是实时备份,当某个时间段Redis服务出现异常,内存数据丢失,这段时间的数据是无法恢复的,因此易导致数据的丢失.

AOF持久化存储
  • AOF持久化存储原理
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZbVo63vw-1619350872430)(https://segmentfault.com/img/remote/1460000018452699)]

1.redis命令写入,此时会将redis命令写入aof_buf换从区.

2.缓冲区中数据根据备份策略实现写入日志文件.

3.当aof的文件越来越庞大,会根据我们的配置策略来实现aof的重写,实现文件的压缩,减少体积.

4.当redis重新启动时,在去重写加载aof文件,达到数据恢复的目的.

  • AOF持久化的优势与劣势

AOF的优势:

1). 该机制可以带来更高的数据安全性,即数据持久性。Redis中提供了3种同步策略,即每秒同步、每修改同步和不同步。事实上,每秒同步也是异步完成的,其效率也是非常高的,所差的是一旦系统出现宕机现象,那么这一秒钟之内修改的数据将会丢失。而每修改同步,我们可以将其视为同步持久化,即每次发生的数据变化都会被立即记录到磁盘中。可以预见,这种方式在效率上是最低的。至于无同步,无需多言,我想大家都能正确的理解它。

2). 由于该机制对日志文件的写入操作采用的是append模式,因此在写入过程中即使出现宕机现象,也不会破坏日志文件中已经存在的内容。然而如果我们本次操作只是写入了一半数据就出现了系统崩溃问题,不用担心,在Redis下一次启动之前,我们可以通过redis-check-aof工具来帮助我们解决数据一致性的问题。

3). 如果日志过大,Redis可以自动启用rewrite机制。即Redis以append模式不断的将修改数据写入到老的磁盘文件中,同时Redis还会创建一个新的文件用于记录此期间有哪些修改命令被执行。因此在进行rewrite切换时可以更好的保证数据安全性。

4). AOF包含一个格式清晰、易于理解的日志文件用于记录所有的修改操作。事实上,我们也可以通过该文件完成数据的重建。

AOF的劣势:

1). 对于相同数量的数据集而言,AOF文件通常要大于RDB文件。RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。

2). 根据同步策略的不同,AOF在运行效率上往往会慢于RDB。总之,每秒同步策略的效率是比较高的,同步禁用策略的效率和RDB一样高效。

  • 二者选择的标准,就是看系统是愿意牺牲一些性能,换取更高的缓存一致性(aof),还是愿意写操作频繁的时候,不启用备份来换取更高的性能,待手动运行save的时候,再做备份(rdb)。rdb这个就更有些 eventually consistent的意思了。
常用配置

RDB持久化配置

Redis会将数据集的快照dump到dump.rdb文件中。此外,我们也可以通过配置文件来修改Redis服务器dump快照的频率,在打开6379.conf文件之后,我们搜索save,可以看到下面的配置信息:

save 900 1 #在900秒(15分钟)之后,如果至少有1个key发生变化,则dump内存快照。

save 300 10 #在300秒(5分钟)之后,如果至少有10个key发生变化,则dump内存快照。

save 60 10000 #在60秒(1分钟)之后,如果至少有10000个key发生变化,则dump内存快照。

AOF持久化配置

在Redis的配置文件中存在三种同步方式,它们分别是:

appendfsync always #每次有数据修改发生时都会写入AOF文件。

appendfsync everysec #每秒钟同步一次,该策略为AOF的缺省策略。

appendfsync no #从不同步。高效但是数据不会被持久化。

参考资料:

http://www.jb51.net/article/65264.htm/

https://segmentfault.com/a/1190000018452695?utm_source=tag-newest/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

杰哥的技术杂货铺

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值