Redis入门(7) - 持久化、主从复制、安全

  • 持久化
    • RDB方式
      • Redis实现快照的过程
    • AOF方式
      • 操做系统缓存
      • RDB与AOF
  • 复制
    • 主从数据库
    • 主从复制的意义
  • 安全

持久化

Redis经过将数据存储在内存中而得到了极快的速度,但为了保证Redis在重启后数据不丢失,须要将数据从内存持久化到硬盘中。redis

持久化的方式有两种,两者能够只用一种,也能够组合使用:docker

  • RDB方式
  • AOF方式

RDB方式

RDB是Redis默认采用的持久化方式,当符合必定条件时Redis会自动将内存中的全部数据进行快照(snapshotting)并存储在硬盘上。进行快照的条件能够由用户在配置文件中自定义,配置由两个参数构成:时间和改动的键的个数。当在指定的时间内被更改的键的个数大于指定的数值时就会进行快照。在配置文件redis.conf中已经预置了3个条件:数据库

save 900 1
save 300 10
save 60 10000

这些条件直接是“或”的关系。若是须要禁用自动快照,能够将全部的save配置删除。缓存

除了自动快照,还能够手动发送SAVE或BGSAVE命令让Redis执行快照,SAVE命令是由主进程进行快照操做,会阻塞住其余请求,而BGSAVE命令则会经过fork子进程进行快照操做。安全

Redis默认会将快照文件存储在当前目录的dump.rdb文件中,能够经过配置dir和dbfilename两个参数分别指定快照文件的存储路径和文件名。bash

Redis实现快照的过程

RDB快照的过程为:服务器

  1. Redis使用fork函数复制一份当前进程(父进程)的副本(子进程);
  2. 父进程继续接收并处理客户端发来的命令,子进程则开始将内存中的数据写入硬盘中的临时文件;
  3. 当子进程写入完全部数据后,会用该临时文件替换旧的RDB文件,至此一次快照操做完成。
  4. Redis从新启动时会读取RDB快照文件,将数据从硬盘载入到内存。(根据数据量大小与结构和服务器性能不一样,这个时间也不一样。一般将一个记录一千万个字符串类型键、大小为1GB的快照文件载入到内存中须要花费20~30秒钟)。

Redis在进行快照的过程当中不会修改RDB文件,只有快照结束后才会将旧的文件替换成新的,也就是说任什么时候候RDB文件都是完整的,因此能够经过定时备份RDB文件来实现Redis数据库备份。RDB文件是通过压缩的二进制格式,占用的空间会小于内存中的数据大小。但压缩过程也会增长CPU占用,若有须要能够经过修改配置rdbcompression参数以禁用压缩。并发

config set rdbcompression no

AOF方式

AOF全称为append only file,在这种持久化方式下,每执行一条会更改Redis中的数据的命令,Redis都会将该命令写入硬盘中的AOF文件。
AOF文件的保存位置和RDB文件的位置相同,均可以经过dir参数设置,默认的文件名是appendonly.aof,能够经过appendfilename参数修改。
AOF文件是纯文本文件,其内容是Redis客户端向Redis发送的原始通讯协议的内容。设想执行这样几条命令:app

SET key1 1
SET key1 2
SET key1 3

AOF文件中会记录这三次操做,但实际上前两条其实是多余的,只须要记录最终一次的命令便可。随着执行的命令愈来愈多,AOF文件也会愈来愈大,而Redis能够经过去除这类多余命令记录,自动对AOF文件进行优化。负载均衡

每当达到必定条件时Redis就会自动重写AOF文件,这个条件能够在配置文件中设置:

auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

auto-aof-rewrite-percentage设置当目前的AOF文件大小超过上一次重写时的AOF文件大小的百分之多少时会再次进行重写,若是以前没有重写过,则以启动时的AOF文件大小为依据。
auto-aof-rewrite-min-size则限制了容许重写的最小AOF文件大小,一般在AOF文件很小的状况下即便其中有不少冗余的命令也不须要重写。

除了让Redis自动执行重写外,还能够主动使用BGREWRITEAOF命令手动执行AOF重写。

在重启时Redis会逐个执行AOF文件中的命令来将硬盘中的数据载入到内存中,载入的速度相较RDB会慢一些。

操做系统缓存

虽然每次执行更改数据库内容的操做时,AOF都会将命令记录在AOF文件中,但实际上因为操做系统的缓存机制的存在,数据并无真正地写入硬盘,而是进入了系统的硬盘缓存。在默认状况下系统每30秒会执行一次同步操做,以便将硬盘缓存中的内容真正地写入硬盘,在这30秒的过程当中若是系统异常退出则会致使硬盘缓存中的数据丢失。通常来说启用AOF持久化的应用都没法容忍这样的损失,这就须要Redis在写入AOF文件后主动要求系统将缓存内容同步到硬盘中。
能够经过appendfsync参数设置同步的时机:

config set appendfsync always/eversec/no
  • always 每次执行写入都会执行同步,这种模式最安全但也最慢
  • everysec 每秒同步一次
  • no 不主动进行同步操做,操做系统没30秒同步一次

RDB与AOF

若是选择RDB的持久化方式,一旦Redis异常退出,就会丢失最后一次快照之后更改的全部数据。这就须要开发者根据具体的应用场合,经过组合设置自动快照条件的方式来将可能发生的数据损失控制在可以接受的范围。若是数据很重要以致于没法承受任何损失,则能够考虑使用AOF方式进行持久化。
能够同时开启AOF和RDB,这样既保证了数据安全,又使得进行备份等操做十分容易。此时从新启动Redis后Redis会使用AOF文件来恢复数据,由于AOF方式的持久化可能丢失的数据更少。

复制

Redis的持久化功能能够保证在服务器重启的状况下不会损失(或少许损失)数据。可是因为数据只存储在一台服务器,若是这台服务器的硬盘出现故障,也会致使数据丢失。为了不单点故障,将数据库复制多个副本以部署在不一样的服务器上,组成集群,这样即便有一台服务器出现故障时,其余服务器依然能够继续提供服务,此外也提高了总体的性能。
Redis提供了复制(replication)功能用以保障构成集群的多台服务器之间数据的同步。

主从数据库

构成集群的数据库分为两类,主数据库(master)和从数据库(slave)。主数据库能够进行读写操做,当发生写操做时自动将数据同步给从数据库。而从数据库通常是只读的,并接受主数据库同步过来的数据。主从数据库是一对多的关系。

要把一个数据库做为从数据库,须要在启动参数或者配置文件中加入:

slaveof 主数据库的IP 端口

接下来使用redis的docker镜像试验主从复制,首先启动两个实例:

docker run --name redis-6379 -p 6379:6379 -d redis
docker run --name redis-6380 -p 6380:6379 -d redis

redis-6379将被做为主数据库,redis-6380为从库,首先获取redis-6379容器的内网IP地址:

docker inspect redis-6379

在"NetworkSettings"结点下能够看到IP和端口为172.17.0.2 6379

进入redis-6380,设置其为从数据库:

> docker exec -it redis-6380 /bin/bash
root@cd19cbbab6d9:/data# redis-cli
127.0.0.1:6379> SLAVEOF 172.17.0.2 6379

这样主从数据库就设置好了,能够测试下在主数据库插入一个键,而后在从数据库读取。

从数据库默认是只读的,尝试写入将提示:

SET KEY1 1
(error) READONLY You can't write against a read only replica.

能够经过设置从数据库的配置文件中的slave-read-only为no以使从数据库可写,可是对从数据库的任何更改都不会同步给其余数据库,而且一旦主数据库中更新了对应的数据就会覆盖从数据库中的改动。

在redis实例运行也可使用SLAVEOF命令,若是该数据库已是其余主数据库的从数据库,则SLAVEOF命令会中止和原来数据库的同步转而和新数据库同步。还可使用SLAVEOF NO ONE来使当前数据库中止接收其余数据库的同步转成主数据库。

主从复制的意义

  • 数据冗余:主从复制实现了数据的热备份,是持久化以外的一种数据冗余方式。

  • 故障恢复:当主节点出现问题时,能够由从节点提供服务,实现快速的故障恢复;其实是一种服务的冗余。

  • 读写分离:能够用于实现读写分离,主库写、从库读,读写分离不只能够提升服务器的负载能力,同时可根据需求的变化,改变从库的数量;

  • 负载均衡:在主从复制的基础上,配合读写分离,能够由主节点提供写服务,由从节点提供读服务分担服务器负载;尤为是在写少读多的场景下,经过多个从节点分担读负载,能够大大提升Redis服务器的并发量。

  • 高可用基石:除了上述做用之外,主从复制仍是哨兵和集群可以实施的基础,所以说主从复制是Redis高可用的基础。

安全

在安全方面,Redis提供了下面几种策略。

可信的环境

Redis安全设计都是创建在“Redis运行在可信环境”这个前提下的,在生产环境运行时不能容许外界直接链接到Redis服务器上,而应该经过应用程序进行中转,运行在可信的环境中是保证Redis安全的最重要方法。

Redis的默认会接受来自任何地址发送来的请求,要更改这一设置,能够在配置文件中修改bind参数,如只容许本机应用链接Redis,能够将bind参数改为:

bind 127.0.0.1

密码

要设置密码,能够修改配置文件中的requirepass参数,例如:

requirepass 123456

docker镜像也能够在启动容器的时候设置密码:

docker run --name redis-test -p 6379:6379 redis --requirepass 123456

添加密码后,客户端在链接时须要输入密码:

redis-cli -h 127.0.0.1 -p 6379 -a 123456

设置密码后,若是要搭建主从数据库,须要在从数据库配置文件中的masterauth添加主数据库的密码。

须要注意的是,因为Redis的性能极高,而且输入错误密码后Redis并不会进行主动延迟,因此攻击者能够经过穷举法破解Redis的密码(1秒内可以尝试十几万个密码),所以在设置时必定要选择复杂的密码。

命令重命名

Redis支持在配置文件中将命令重命名,好比将FLUSHALL命令重命名成一个比较复杂的名字,以保证只有本身的应用可使用该命令:

rename-command FLUSHALL oiuyhjkghjgyutdfhbuhbnjinjbgyvtcrd

若是但愿直接禁用某个命令,能够将命令重命名成空字符串。

相关文章
相关标签/搜索