Rdb(redis系统默认持久化策略)(转)

常用命令参考

Redis简介

Redis是基于内存,也可以基于磁盘持久化nosql数据库,使用c语言开发。

数据存储结构:key-value

安装环境准备

Redis使用c语言开发,需要使用gcc编译程序进行编译。

1) 安装gcc

a) 从磁盘镜像中进行安装:(重启Linux服务器需要重新挂载磁盘镜像)

b) 使用yum命令直接从mine.repo文件中本地URL下载

c) 挂载命令:mount /dev/cdrom /mnt

d) 安装命令:yum -y install gcc

2) 安装上传文件插件

a) 工具上传文件:(只能上传root目录)

b) Alt+P上传文件默认只能上传root目录

c) 安装插件:(可以把文件上传任意目录)

  1. Rz(lrzsz)
  2. 安装命令:yum –y install lrzsz (磁盘镜像中直接安装)

安装redis

上传安装包

使用rz命令上传redis安装包,到/usr/local/hadoop目录下:

[root@localhost hadoop]# ll

total 144964

drwxr-xr-x. 9 root root 4096 Jul 13 01:37 apache-tomcat-7.0.61

-rw-r–r--. 1 root root 8816567 May 5 2015 apache-tomcat-7.0.61.tar.gz

drwxr-xr-x. 8 uucp 143 4096 Oct 8 2013 jdk1.7.0_45

-rw-r–r--. 1 root root 138094686 Jul 13 01:28 jdk-7u45-linux-x64.tar.gz

-rw-r–r--. 1 root root 1358081 May 14 2015 redis-3.0.0.tar.gz

解压

解压命令:tar -zxvf redis-3.0.0.tar.gz

安装redis

1) 编译

a) 命令:make

b) 进入redis解压目录:执行编译命令。

c) 执行编译程序:生成编译文件在src目录下

2) 安装

a) 命令:make install PREFIX=/usr/local/hadoop/redis

b) 进入redis解压目录:执行安装命令

[root@localhost redis-3.0.0]# make install PREFIX=/usr/local/hadoop/redis

cd src && make install

make[1]: Entering directory `/usr/local/hadoop/redis-3.0.0/src’

Hint: It’s a good idea to run ‘make test’ 😉

INSTALL install

INSTALL install

INSTALL install

INSTALL install

INSTALL install

make[1]: Leaving directory `/usr/local/hadoop/redis-3.0.0/src’

启动redis服务

前台启动

启动命令:./redis-server

特点:默认启动前台服务,进程一种阻塞,不能直接退出,使用客户端进行登录。

后台启动

修改redis配置文件,redis.conf配置文件,此时bin安装目录没有配置文件,需要从解压目录中拷贝一份配置文件即可。

1) 拷贝redis.conf配置文件

a) redis.conf在redis解压目录中

b) 拷贝:cp redis.conf …/redis/bin/

[root@localhost bin]# ll

total 15520

-rw-r–r--. 1 root root 18 Jul 26 17:14 dump.rdb

-rwxr-xr-x. 1 root root 4587078 Jul 26 17:09 redis-benchmark

-rwxr-xr-x. 1 root root 22185 Jul 26 17:09 redis-check-aof

-rwxr-xr-x. 1 root root 45403 Jul 26 17:09 redis-check-dump

-rwxr-xr-x. 1 root root 4689993 Jul 26 17:09 redis-cli

-rw-r–r--. 1 root root 41403 Jul 26 17:16 redis.conf

lrwxrwxrwx. 1 root root 12 Jul 26 17:09 redis-sentinel -> redis-server

-rwxr-xr-x. 1 root root 6448257 Jul 26 17:09 redis-server

2) 修改redis配置文件

a) daemonize no==daemonize yes

3) 启动redis,加载配置文件

a) 命令:./redis-server redis.conf

4) 登录redis

a) 登录命令:./redis-cli –h ip –p port

b) 登录:./redis-cli (默认登录6379端口redis服务)

Redis命令

redis是一种高级的key:value存储系统,其中value支持五种数据类型:

1.字符串(strings)

2.字符串列表(lists)

3.字符串集合(sets)

4.有序字符串集合(sorted sets)

5.哈希(hashes)

而关于key,有几个点要提醒大家:

1.key不要太长,尽量不要超过1024字节,这不仅消耗内存,而且会降低查找的效率;

2.key也不要太短,太短的话,key的可读性会降低;

3.在一个项目中,key最好使用统一的命名模式,例如user:10000:passwd。

Strings

Redis存储结构是key:value,value是 strings数据类型。

命令:

语法:set key value

1) set name zhangsanfeng

a) 给Strings类型key是name 添加一个值。

2) get name

a) 获取key是name属性的值。

3) incr age

a) 给数字字符类型自动加1

b) 把数字字符类型自动转换成integer类型,然后执行再加上1

4) decr age

a) 给数字字符类型自动减1

b) 把数字字符类型自动转换成integer类型,然后执行减去1

5) incrby age 10

a) 给指定键值加速10

6) decrby age 10

a) 给指定键值减去10

Hash

Hash是集合类型,适合于用来存储对象。Java集合类型是用来存储对象。

存储数据结构分析:

存取对象,使用一个key,使用一个key获取一个对象,必须使用反序列化。

缺点:

占用IO资源。

第二种数据结构:

缺点:

用户ID被多次使用,数据冗余。资源浪费。

第三种数据结构:

Redis存储结构:key是用户ID value:就是hash类型数据。

命令:

1) hset user username zhaowuji

a) 给user中Username属性设置一个值

2) hget user username

a) 获取User中Username属性的值

3) hdel user password ……

a) 删除User中属性

4) hsetnx user email 123@qq.com

a) 如果user中email属性值已经存在,不会覆盖

b) 如果不存在,设置值。

5) hmset user password 123 age 11

a) 同时设置多个值

6) Hmget user username age password

Lists

List集合数据结构:类似数组,数据是顺序存储。

List集合链表结构:通过指针从头指针查询到尾指针查找元素。

命令:

1) lpush mylist a b c d

a) 给list类型数据结构设置多个值

2) lrange mylist 0 -1

a) 获取mylist集合中所有值

b) 0:值链表开始位置

c) -1:链表的结束位置

3) lpop mylist

a) 出栈集合mylist:出栈链表头指针元素。

4) lrem mylist 3 a

a) 删除链表mylist中前3个等于a的值。

5) lset mylist 2 s

a) 给链表mylist集合中2角标位置设置一个值,覆盖原值。

6) linsert mylist after s b

a) 在集合链表mylsit中s元素后面插入一个b

Set

命令:

1) sadd myset a b c

a) 给set集合myset设置值:a b c

b) Set集合元素值不允许重复

2) smembers myset

a) 获取集合myset中值

3) srem myset a b

a) 删除集合myset中元素

4) smove myset myset1 c

a) 把集合myset中的元素c移动到集合myset1中

Sorted set

Set集合:有序集合。

给set集合中每一元素都设置一个得分,根据得分排序。

Set集合元素不允许重复,得分可以重复。

设置得分语法:ZADD key score member [score] [member]

命令:

1) zadd mysset 1 one 2 two 12 three 9 four 10 five

a) 给集合mysset集合添加5个元素,每一个元素都设置一个得分。

2) zcount mysset 1 10

a) 获取分数1到10的元素个数,默认是闭区间。

3) zcount mysset (1 10

a) 获取分数1到10的元素个数,左边是开区间(不包含1元素)

4) zcount mysset -inf +inf

a) 获取所有元素

b) –inf:最低值

c) +inf:最高值

5) zrange mysset 0 -1 withscores

a) 获取集合mysset中所有元素

b) 0:头部元素

c) -1表示尾部元素

d) Withscores:查询元素时候,把分数查询出来

6) zrangebyscore mysset 1 10 withscores limit 2 2

a) 根据分数大小来获取元素:

b) Limit分页获取值。

多数据库实例

Redis支持16个数据库实例,数据库实例角标从0—15,使用redis客户端登录redis服务器,默认登录0号数据库。

登录其他数据库实例:

登录语法:select 数据库实例ID(角标)

登录1号数据库:

127.0.0.1:6379> select 1

OK

127.0.0.1:6379[1]>

需求:把0号数据库数据移动1号数据库

命令:move user 1 //移动user到1号数据库

事务

事务命令:

开启事务:multi

提交事务:exec

回滚事务:discard

监听事务:watch(乐观锁)

用户A,用户B 同时读取商品数量itemNum=1,用户A,用户B都需要购买商品,商品数量需要减去1,使用乐观锁解决问题:

事务一致性

设计:商品数量添加,在添加过程中出一个错误,查看程序执行一致性。

127.0.0.1:6379> multi//开启事务

OK

127.0.0.1:6379> incr itemNum

QUEUED

127.0.0.1:6379> incr itemNum

QUEUED

127.0.0.1:6379> incrby itemNum 10

QUEUED

127.0.0.1:6379> lpop itemNum//使用操作list数据结构命令操作String类型,出现错误

QUEUED

127.0.0.1:6379> decr itemNum

QUEUED

127.0.0.1:6379> decrby itemNum 10

QUEUED

127.0.0.1:6379> exec//提交事务

  1. (integer) 2

  2. (integer) 3

  3. (integer) 13

  4. (error) WRONGTYPE Operation against a key holding the wrong kind of value

  5. (integer) 12

  6. (integer) 2

特点:redis事务不遵循ACID大一统理论,即使中间执行出现错误,后面不影响执行。

12.2 事务回滚

127.0.0.1:6379> mult//开启事务

OK

127.0.0.1:6379> incr itemNum

QUEUED

127.0.0.1:6379> incr itemNum

QUEUED

127.0.0.1:6379> discard//事务回滚

OK

127.0.0.1:6379> get itemNum

“2”

12.3 Watch

Watch监听事务:乐观锁

乐观锁:一旦发现被监听事务变量发生了变化,事务回滚。

127.0.0.1:6379> watch itemNum

OK

127.0.0.1:6379> multi

OK

127.0.0.1:6379> decr itemNum //当检测到itemNum发生变化时,此命令不执行。

QUEUED

127.0.0.1:6379> exec

(nil)

127.0.0.1:6379> get itemNum

“0”

Redis持久化

Rdb(redis系统默认持久化策略)

Rdb持久化优点

1) 持久化文件将只包含一个文件

2) 对灾难恢复,主从复制 效率比较高。

3) 持久化工作:子进程

Rdb缺点

1) 数据安全性不是很好

Rdb数据持久化同步策略

缺省情况下,Redis会将数据集的快照dump到dump.rdb文件中。此外,我们也可以通过配置文件来修改Redis服务器dump快照的频率,在打开redis.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

Aof持久化优点

1) 根据redis aof同步策略,数据有更高安全性

Aof缺点

1) 性能比rdb低

AOF 详解

AOF :Redis 默认不开启。它的出现是为了弥补RDB的不足(数据的不一致性),所以它采用日志的形式来记录每个写操作,并追加到文件中。Redis 重启的会根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作。

从配置文件了解AOF

打开 redis.conf 文件,找到 APPEND ONLY MODE 对应内容
1 redis 默认关闭,开启需要手动把no改为yes

appendonly yes

2 指定本地数据库文件名,默认值为 appendonly.aof

appendfilename "appendonly.aof"

3 指定更新日志条件

# appendfsync always
appendfsync everysec
# appendfsync no

解说:
always:同步持久化,每次发生数据变化会立刻写入到磁盘中。性能较差当数据完整性比较好(慢,安全)
everysec:出厂默认推荐,每秒异步记录一次(默认值)
no:不同步

4 配置重写触发机制

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

解说:当AOF文件大小是上次rewrite后大小的一倍且文件大于64M时触发。一般都设置为3G,64M太小了。

触发AOF快照

根据配置文件触发,可以是每次执行触发,可以是每秒触发,可以不同步。

根据AOF文件恢复数据

正常情况下,将appendonly.aof 文件拷贝到redis的安装目录的bin目录下,重启redis服务即可。但在实际开发中,可能因为某些原因导致appendonly.aof 文件格式异常,从而导致数据还原失败,可以通过命令redis-check-aof --fix appendonly.aof 进行修复 。从下面的操作演示中体会。

AOF的重写机制

前面也说到了,AOF的工作原理是将写操作追加到文件中,文件的冗余内容会越来越多。所以聪明的 Redis 新增了重写机制。当AOF文件的大小超过所设定的阈值时,Redis就会对AOF文件的内容压缩。

重写的原理:Redis 会fork出一条新进程,读取内存中的数据,并重新写到一个临时文件中。并没有读取旧文件(你都那么大了,我还去读你??? o(゚Д゚)っ傻啊!)。最后替换旧的aof文件。

触发机制:当AOF文件大小是上次rewrite后大小的一倍且文件大于64M时触发。这里的“一倍”和“64M” 可以通过配置文件修改。

AOF 的优缺点

优点:数据的完整性和一致性更高
缺点:因为AOF记录的内容多,文件会越来越大,数据恢复也会越来越慢。

操作演示

[root@itdragon bin]# vim appendonly.aof
appendonly yes
[root@itdragon bin]# ./redis-server redis.conf
[root@itdragon bin]# ./redis-cli -h 127.0.0.1 -p 6379
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> set keyAOf valueAof
OK
127.0.0.1:6379> FLUSHALL 
OK
127.0.0.1:6379> SHUTDOWN
not connected> QUIT
[root@itdragon bin]# ./redis-server redis.conf
[root@itdragon bin]# ./redis-cli -h 127.0.0.1 -p 6379
127.0.0.1:6379> keys *
1) "keyAOf"
127.0.0.1:6379> SHUTDOWN
not connected> QUIT
[root@itdragon bin]# vim appendonly.aof
fjewofjwojfoewifjowejfwf
[root@itdragon bin]# ./redis-server redis.conf
[root@itdragon bin]# ./redis-cli -h 127.0.0.1 -p 6379
Could not connect to Redis at 127.0.0.1:6379: Connection refused
not connected> QUIT
[root@itdragon bin]# redis-check-aof --fix appendonly.aof 
'x              3e: Expected prefix '*', got: '
AOF analyzed: size=92, ok_up_to=62, diff=30
This will shrink the AOF from 92 bytes, with 30 bytes, to 62 bytes
Continue? [y/N]: y
Successfully truncated AOF
[root@itdragon bin]# ./redis-server redis.conf
[root@itdragon bin]# ./redis-cli -h 127.0.0.1 -p 6379
127.0.0.1:6379> keys *
1) "keyAOf"

第一步:修改配置文件,开启AOF持久化配置。
第二步:重启Redis服务,并进入Redis 自带的客户端中。
第三步:保存值,然后模拟数据丢失,关闭Redis服务。
第四步:重启服务,发现数据恢复了。(额外提一点:有教程显示FLUSHALL 命令会被写入AOF文件中,导致数据恢复失败。我安装的是redis-4.0.2没有遇到这个问题)。
第五步:修改appendonly.aof,模拟文件异常情况。
第六步:重启 Redis 服务失败。这同时也说明了,RDB和AOF可以同时存在,且优先加载AOF文件。
第七步:校验appendonly.aof 文件。重启Redis 服务后正常。

补充点:aof 的校验是通过 redis-check-aof 文件,那么rdb 的校验是不是可以通过 redis-check-rdb 文件呢???

主从复制

主从复制是什么:
行话:也就是我们所说的主从复制,主机数据更新后根据配置和策略,自动同步到备机的master/slaver机制,Master以写为主,Slave以读为主
命令
连接主机
SLAVEOF 127.0.0.1 6379
将使得这个从属服务器关闭复制功能,并从从属服务器转变回主服务器,原来同步所得的数据集不会被丢弃。
SLAVEOF NO ONE 

一、能干什么:

  1. 读写分离
  2. 容灾恢复

二、怎么用:

  1. 配从(库)不配主(库)
  2. 从库配置:slaveof 主库IP 主库端口 如slaveof 127.0.0.1: -> 每次与master断开之后,都需要重新连接,除非你配置进redis.conf文件
  1. 同一台机器上需要修改配置文件细节操作

master server 配置文件master.conf, 主要配置如下:

daemonize yes  
pidfile /var/run/redis_6379.pid  
port 6379  
#save 900 1  
#save 300 10  
#save 60 10000  
dbfilename dump.rdb  
dir /var/lib/redis/6379  

slave server 配置文件redis80.conf,主要配置如下:

daemonize yes  
pidfile /var/run/redis_6379.pid  
port 6380  
save 900 1  
save 300 10  
save 60 10000  
dbfilename dump.rdb  
dir /var/lib/redis/6380  
slaveof 127.0.0.1 6379 

三、常用三招

  • 一主二仆

    ​ 一个Master,两个Slave,Slave只能读不能写;当Slave与Master断开后需要重新slave of连接才可建立之
    ​ 前的主从关系;Master挂掉后,Master关系依然存在,Master重启即可恢复。
  • 薪火相传

    ​ 上一个Slave可以是下一个Slave的Master,Slave同样可以接收其他slaves的连接和同步请求,那么该slave作为了
    ​ 链条中下一个slave的Master,如此可以有效减轻Master的写压力。如果slave中途变更转向,会清除之前的数据,重新
    ​ 建立最新的。
  • 反客为主
    当Master挂掉后,Slave可键入命令 slaveof no one使当前redis停止与其他Master redis数据同步,转成Master redis。

总结

  1. Redis 默认开启RDB持久化方式,在指定的时间间隔内,执行指定次数的写操作,则将内存中的数据写入到磁盘中。
  2. RDB 持久化适合大规模的数据恢复但它的数据一致性和完整性较差。
  3. Redis 需要手动开启AOF持久化方式,默认是每秒将写操作日志追加到AOF文件中。
  4. AOF 的数据完整性比RDB高,但记录内容多了,会影响数据恢复的效率。
  5. Redis 针对 AOF文件大的问题,提供重写的瘦身机制。
  6. 若只打算用Redis 做缓存,可以关闭持久化。
  7. 若打算使用Redis 的持久化。建议RDB和AOF都开启。其实RDB更适合做数据的备份,留一后手。AOF出问题了,还有RDB。