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

1.1:redis数据持久化概括:
redis 支持两种数据持久保存方式,分别是RDB和APF
RDB可以设置在多长时间内有多少个key发生变化就执行RDB快照。
AOF持久化是服务器记录和保存redis执行的所有命令,并在服务重启的时候重新执行全部的命令来还原数据,AOF文件的命令全部使用redis 协议格式保存,执行的命令会被以追加的命令保存到文件的末尾,另外redis还可以在后台对AOF文件进行rewrite即重写,这样可以使文件的大小不会超过保存数据所需要的实际大小。
redis可以同时使用AOF和RDB进行数据持久化,但是当redis重启的时候会优先使用AOF文件来还原数据,这是因为AOF保存的文件通常要比RDB文件保存的数据更加完整。

1.2:RDB的实现与优缺点:
1.2.1:实现原理:
RDB是redis从主进程先fork出一个子进程,使用写时复制机制,子进程将内存的数据保存为一个临时文件,比如dump.rdb.temp,当数据保存完成之后再将上一次保存的RDB文件替换掉,然后关闭子进程,这样可以保存每一次做RDB快照的时候保存的数据都是完整的,因为直接替换RDB文件的时候可能会出现突然断电等问题而导致RDB文件还没有保存完整就突然关机停止保存而导致数据丢失的情况,可以手动将每次生成的RDB文件进程备份,这样可以最大化保存历史数据。

1.2.2:RDB的优点:
保存了某个时间点的数据,可以通过脚本执行bgsave命令自定义时间点北备份,可以保留多个备份,当出现问题可以恢复到不同时间点的版本。
可以最大化io的性能,因为父进程在保存RDB 文件的时候唯一要做的是fork出一个子进程,然后的操作都会有这个子进程操作,父进程无需任何的IO操作
RDB在大量数据比如几个G的数据,恢复的速度比AOF的快

1.2.3:RDB的缺点:
不能时时的保存数据,会丢失自上一次执行RDB备份到当前的内存数据
数据量非常大的时候,从父进程fork的时候需要一点时间,可能是毫秒或者秒

1.3:AOF的实现和优缺点:
1.3.1:AOF的实现机制:
AOF和RDB一样使用了写时复制机制,AOF默认为每秒钟fsync一次,即将执行的命令保存到AOF文件当中,这样即使redis服务器发生故障的话顶多也就丢失1秒钟之内的数据,也可以设置不同的fsync策略,或者设置每次执行命令的时候执行fsync,fsync会在后台执行线程,所以主线程可以继续处理用户的正常请求而不受到写入AOF文件的IO影响
AOF文件是一个进行追加操作的日志文件(append only log),即操作的命令都会被追加到文件的末尾,如果因为磁盘满、突然停机等问题导致写入了不完整的命令,可以通过redis自带的命令redis-check-aof命令轻易的修复AOF文件,如下:
# redis-check-aof /data/redis/appendonly.aof
AOF analyzed: size=7683, ok_up_to=7683, diff=0
AOF is valid
redis可以在AOF文件变得过大的时候自带在后台对文件进行重写,重写后的新APF文件保存了恢复的时候需要的最新数据和最小的命令集合,这个操作是绝对安全的,因为redis 在创建新AOF文件的过程中会继续将命令追加到之前的AOF文件,这样即使服务器宕机也不会影响到当前redis 使用的AOF文件,而一旦新的AOF文件创建完成,redis就会从旧AOF文件切换到新的AOF文件,并将命令追加到新的AOF文件
AOF文件按照命令的执行顺序保存了对redis 的所以操作,使用的是redis协议,因此可以对AOF文件进行读取和分析,也可以导出,假如不小心执行了一个FLUSHALL命令,但是只要AOF文件还没有被重写可以立即停止服务器,然后删除AOF文件末尾的FLUSHALL命令并重启redis,即将可以将数恢复到FLUSHALL命令之前的数据状态。

1.3.2:AOF的缺点:
AOF的文件大小要大于RDB格式的文件
曾经有bug导致AOF重新载入AOF文件的时候无法将数据恢复到保存的时候远洋,比如执行阻塞命令BRPOPLPUSH就曾引起bug
根据所使用的fsync策略(fsync是同步内存中redis所有已经修改的文件到存储设备),默认是appendfsync everysec即每秒执行一次fsync

1.4:redis 持久化的配置参数:
1.4.1:编辑配置那文件:
# vim /etc/redis/6379.conf

save 900 1 #900秒以内有1个key发生变化就快照
save 300 10 #300秒以内有10个key发生变化就快照
save 60 10000 #60秒内有10000个key变化就快照
rdbcompression yes #持久化到RDB文件时,是否压缩,"yes"为压缩,"no"则反之
rdbchecksum yes #读取和写入的时候是否支持CRC64校验,默认是开启的
dbfilename dump.rdb #文件名
dir /data/redis #保存路径
slave-read-only yes #从redis 只读
maxmemory 512M #限制redis 最大使用内存
appendonly yes #是否开启AOF
appendfilename "appendonly.aof" #保存路径,和RDB在一起
appendfsync everysec #每秒执行一次fsync,即将内存更改的数据写入磁盘

[root@node1 src]# egrep '^[a-z]' /etc/redis/6379.conf

bind 0.0.0.0
protected-mode yes
port
tcp-backlog
timeout
tcp-keepalive
daemonize yes
supervised no
pidfile /var/run/redis_6379.pid
loglevel notice
logfile ""
databases
save
save
save
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /data/redis
slave-serve-stale-data yes
slave-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay
repl-disable-tcp-nodelay no
slave-priority
maxmemory 512M
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
lua-time-limit
slowlog-log-slower-than
slowlog-max-len
latency-monitor-threshold
notify-keyspace-events ""
hash-max-ziplist-entries
hash-max-ziplist-value
list-max-ziplist-size -
list-compress-depth
set-max-intset-entries
zset-max-ziplist-entries
zset-max-ziplist-value
hll-sparse-max-bytes
activerehashing yes
client-output-buffer-limit normal
client-output-buffer-limit slave 256mb 64mb
client-output-buffer-limit pubsub 32mb 8mb
hz
aof-rewrite-incremental-fsync yes

SAVE 与 BGSAVE:
SAVE:阻塞保存
BGSAVE:在后台保存,不阻塞
KILL -9 会丢失自上次保存以后到现在的数据

1.4.2:重启redis服务:

[root@node1 ~]# /etc/init.d/redis stop
Stopping ...
Redis stopped
[root@node1 ~]# /etc/init.d/redis start
Starting Redis server...

1.4.2:通过python连接到redis 写入几个key,验证持久保存:

#!/bin/env  python
import redis pool = redis.ConnectionPool(host='192.168.3.199',port=6379)
r = redis.Redis(connection_pool = pool)
for i in range(1000):
r.set('k%d' % i,'v%d' % i)
data = r.get('k%d' % i)
print(data)

1.4.3:redis服务器验证数据:

[root@node1 ~]# redis-cli -h 192.168.3.199
192.168.3.199:6379> keys *
1) "k941"
2) "k863"
3) "k699"
4) "k646"
5) "k833"
6) "k945"
7) "k286"
8) "k310"
9) "k546"
10) "k313"
11) "k135"
12) "k458"
......

1.4.4:验证AOF和RDB持久化保存的文件,保存的文件路径是在redis.conf文件定义的:
[root@node1 ~]# ll /data/redis/
total 48
-rw-r--r-- 1 root root 32803 Jul 11 01:51 appendonly.aof
-rw-r--r-- 1 root root 10862 Jul 11 02:03 dump.rdb
AOF是时时写入到文件的,rdb需要等达到指定的策略后才会备份

二:redis主从:
redis支持主从复制的功能,可以让从服务器从主服务器备份数据,而且从服务器还可与有从服务器,即另外一台redis服务器可以从一台从服务器进行数据同步,redis 的主从同步是非阻塞的,其收到从服务器的sync(2.8版本之前是PSYNC)命令会fork一个子进程在后台执行bgsave命令,并将新写入的数据写入到一个缓冲区里面,bgsave执行完成之后并生成的将RDB文件发送给客户端,客户端将收到后的RDB文件载入自己的内存,然后主redis将缓冲区的内容在全部发送给从redis,之后的同步从服务器会发送一个offset的位置(等同于MySQL的binlog的位置)给主服务器,主服务器检查后位置没有错误将此位置之后的数据包括写在缓冲区的积压数据发送给redis从服务器,从服务器将主服务器发送的挤压数据写入内存,这样一次完整的数据同步,再之后再同步的时候从服务器只要发送当前的offset位 置给主服务器,然后主服务器根据响应的位置将之后的数据发送给从服务器保存到其内存即可。
另外redis的key 大小不建议超过2MB,因为2MB以下的key的性能是最佳的,key比较大的时候可以使用列表、key分级等方式将key进行拆分保存到不同的hash里面,另外第一次主从同步如果有数十G的数据,如果在主redis服务器写入频繁的时候同步,可能会出现RDB文件还没有向从服务器传输完成但主服务器的缓冲区已经写满导致从服务器发送sync的时候出现数据不一致导致再次全量同步的情况发生,因此建议在晚上住redis写入较少的时候在做同步,避免此类的情况发生

2.1:主从同步的一些概念:
redis使用异复制数据,从redis 2.8开始,从服务器会以每秒一次的频率向主服务器报告复制流(replication stream)的处理进度
一个主服务器可以同时有多个从服务器
从服务器还可以有自己的从服务器
复制功能不会阻塞从服务器,只要在redis.conf中做了设置,及时从服务器正在和主服务器进行初次同步,从服务器也可以使用之前的数据类处理客户端请求,不过从服务器删除就版本数据并载入新数据的时间段内,连接请求会被阻塞,可以设置从服务器让他在和主服务器之间断开连接时,向客户端发送一个错误信息
复制功能用于实现数据冗余,可以在从服务器执行复杂的命令在从服务器执行,以减轻主服务器的压力
可以在从服务器执行数据持久化而关闭主服务器的持久化功能,然后在从服务器执行数据持久化即可
2.2:是否需要在主服务器打开持久化功能:
有一个场景,有三个服务器,主服务器,从服务器A和从服务器B,从服务器A从主服务器同步数据,而从服务器B从服务器A同步数据,假如主服务器没有开启数据持久化,那么当主服务器出现问题重启redis服务后由于没有做数据持久会丢失所以数据为空,而从服务器A同步主服务器后也没有数据,从服务器B同步从服务器A的数据之后也会没有数据,因此主服务器还是推荐开启数据持久化以避免产生一系列的问题。
另外
2.3:配置redis主从同步,在另外一台服务器安装同版本的redis,并执行以下操作:
2.3.1:在从服务器进行操作:

[root@node1 src]# redis-cli -h 192.168.3.13
192.168.3.13:6379> SLAVEOF 192.168.3.199 6379 # 配置3.199为主服务器
OK

2.3.2:查看redis从服务器的状态:
192.168.3.13:6379> info

#其他信息省略
# Replication
role:slave # 状态为从服务器
master_host:192.168.3.199 # 主服务器的IP和端口信息
master_port:6379
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:15
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0 192.168.3.13:6379> set key001 value001 #从服务器默认为read only即只读模式,无法写入数据
(error) READONLY You can't write against a read only slave

2.3.3:在redis主服务器执行INFO查看服务器信息:

# Replication
#其他信息省略
role:master #状态为主服务器
connected_slaves:1 #已经有一个从服务器连接
slave0:ip=192.168.3.13,port=6379,state=online,offset=477,lag=1
master_repl_offset:477
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:476

2.3.4:redis主从之间的心跳检测,可以通过MONITOR命令查看:

192.168.3.13:6379> MONITOR
OK
1499680760.936254 [0 192.168.3.199:6379] "PING"
1499680770.341823 [0 192.168.3.199:6379] "PING"
1499680779.735807 [0 192.168.3.199:6379] "PING"
1499680789.117626 [0 192.168.3.199:6379] "PING"

2.4:将从服务器设置为主服务器:

192.168.3.13:6379> SLAVEOF no one #将从服务器切换为主服务器
OK
192.168.3.13:6379> info
# 其他信息省略
# Replication
role:master #即切换为主服务器
connected_slaves:0
master_repl_offset:981
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

缓存系列之四:redis持久化与redis主从复制的更多相关文章

  1. Redis持久化存储与主从复制

    4. redis持久化 Redis是一种内存型数据库,一旦服务器进程退出,数据库的数据就会丢失,为了解决这个问题,Redis提供了两种持久化的方案,将内存中的数据保存到磁盘中,避免数据的丢失. 4.1 ...

  2. 初识Redis系列之四:.net使用Redis存储数据

    首先Redis在Windows上的安装前面的文章已经介绍过,这里不介绍了,直奔主题, 直接来看看.net怎么使用Redis 首先需要引用redis相关的dll,两个途径,意识网上下载编译好的dll : ...

  3. 【redis持久化】redis持久化理解

    1.以下内容仅为个人理解和总结,仅供参考,万万不可全盘真信,内容会进行实时改进和修正 2.redis持久化: 参考链接1.https://redis.io/topics/persistence  -- ...

  4. redis介绍、安装、redis持久化、redis数据类型

    1.redis介绍  2.安装管网:https://redis.io/下载:wget -c http://download.redis.io/releases/redis-4.0.11.tar.gz解 ...

  5. (转)淘淘商城系列——Redis持久化方案

    http://blog.csdn.net/yerenyuan_pku/article/details/72858975 Redis中设置key的过期时间 Redis中的expire命令用于设置key的 ...

  6. 配置方案:Redis持久化RDB和AOF

    Redis持久化方案 Redis是内存数据库,数据都是存储在内存中,为了避免进程退出导致数据的永久丢失,需要定期将Redis中的数据以某种形式(数据或命令)从内存保存到硬盘.当下次Redis重启时,利 ...

  7. redis学习(三)redis持久化

    redis持久化 1.redis持久化介绍 我们知道redis性能之所以强悍,是因为redis在运行时将数据都存放在了访问效率远高于硬盘的内存之中.可是这带来了新的问题:在redis或者外部系统重启时 ...

  8. Part_three:Redis持久化存储

    redis持久化存储 Redis是一种内存型数据库,一旦服务器进程退出,数据库的数据就会丢失,为了解决这个问题,Redis提供了两种持久化的方案,将内存中的数据保存到磁盘中,避免数据的丢失. 1.RD ...

  9. 详解Redis持久化(RDB和AOF)

    详解Redis持久化(RDB和AOF) 什么是Redis持久化? Redis读写速度快.性能优越是因为它将所有数据存在了内存中,然而,当Redis进程退出或重启后,所有数据就会丢失.所以我们希望Red ...

随机推荐

  1. Linux命令(十一)gcc

    1. gcc -E 预处理 头文件展开 宏替换 2. gcc -S: 生成汇编指令 3. gcc - c: 生成二进制文件 4. gcc -I: (包含头文件) 5. gcc -o: 指定输出 6. ...

  2. solr插件导入数据库中的数据

    solr插件导入数据库中的数据 1:自定义与数据库对应的域: 1.1. 设置业务系统Field 如果不使用Solr提供的Field可以针对具体的业务需要自定义一套Field. 例如:如下是商品信息Fi ...

  3. Docker-02 无人值守安装 docker

    #!/bin/bash # # 无人值守安装 docker # # # .关闭SELinux # setenforce sed -i 's/SELINUX=enforcinf/SELINUX=disa ...

  4. 通配符 Globbing赏析

    什么是 Globing? https://www.techopedia.com/definition/14392/globbing   Definition - What does Globbing ...

  5. KMP模板(HDU1711)

    #include<stdio.h> #include<math.h> #include<string.h> #include<stack> #inclu ...

  6. java乱码解决方法

    String name = request.getParameter("name"); 乱码解决:String name = new String(request.getParam ...

  7. NPOI 列宽自适应 代码示例

    //列宽自适应,只对英文和数字有效 for (int i = 0; i <= maxColumn; i++) { sheet.AutoSizeColumn(i); } //获取当前列的宽度,然后 ...

  8. Python基础6 面向对象

    本节内容 面向对象编程介绍 为什么要面向对象开发? 面向对象的特性:封装,继承,多态 类,方法 引子 假设现在我们需要开发一款简单的游戏,譬如叫做人兽战争.我们需要简单的2个角色,一个人,一个怪兽,而 ...

  9. 【mmall】学习Spring要善用Spring的Github

    官网:https://projects.spring.io/spring-framework 宠物医院项目(非常经典的Spring项目):https://github.com/spring-proje ...

  10. Core Mvc传值ViewData、ViewBag和return view(model)

    先定义一个Model类Student namespace Lession.Models { public class Student { public string Name { get; set; ...