1.什么是持久化 持久化就是将数据从掉电易失的内存同步到能够永久存储的设备上的过程 2.Redis为什么需要持久化
redis将数据保存在内存中,一旦Redis服务器被关闭,或者运行Redis服务的主机本身被关闭的话,储存在内存里面的数据就会丢失
如果仅仅将redis用作缓存的话,那么这种数据丢失带来的问题并不是非常大,只需要重启机器,然后再次将数据同步到缓存中就可以了
但如果将redis用作数据库的话,那么因为一些原因导致数据丢失的情况就不能接受
Redis的持久化就是将储存在内存里面的数据以文件形式保存硬盘里面,这样即使Redis服务端被关闭,已经同步到硬盘里面的数据也不会丢失
除此之外,持久化也可以使Redis服务器重启时,通过载入同步的持久文件来还原之前的数据,或者使用持久化文件来进行数据备份和数据迁移等工作
3.Redis持久化方式 3.1 RDB(Redis DB)方式RDB持久化功能可以将Redis中所有数据生成快照并以二进行文件的形式保存到硬盘里,文件名为.RDB文件
在Redis启动时载入RDB文件,Redis读取RDB文件内容,还原服务器原有的数据库数据
过程如下图所示:
Redis服务端创建RDB文件,有三种方式
3.1.1 使用SAVE命令手动同步创建RDB文件客户端向Redis服务端发送SAVE命令,服务端把当前所有的数据同步保存为一个RDB文件
通过向服务器发送SAVE命令,Redis会创建一个新的RDB文件
在执行SAVE命令的过程中(也就是即时创建RDB文件的过程中),Redis服务端将被阻塞,无法处理客户端发送的其他命令请求
只有在SAVE命令执行完毕之后(也就时RDB文件创建完成之后),服务器才会重新开始处理客户端发送的命令请求
如果已经存在RDB文件,那么服务器将自动使用新的RDB文件去代替旧的RDB文件
例子:
1.修改Redis的配置文件/etc/redis.conf,把下面三行注释掉
#save 900 1 #save 300 10 #save 60 100002.执行下面三条命令
127.0.0.1:6379> flushall # 清空Redis中所有的键值对 OK 127.0.0.1:6379> dbsize # 查看Redis中键值对数量 (integer) 0 127.0.0.1:6379> info memory # 查看Redis占用的内存数为834.26K # Memory used_memory:854280 used_memory_human:834.26K used_memory_rss:5931008 used_memory_rss_human:5.66M used_memory_peak:854280 used_memory_peak_human:834.26K total_system_memory:2080903168 total_system_memory_human:1.94G used_memory_lua:37888 used_memory_lua_human:37.00K maxmemory:0 maxmemory_human:0B maxmemory_policy:noeviction mem_fragmentation_ratio:6.94 mem_allocator:jemalloc-3.6.03.从Redis的配置文件可以知道,Redis的RDB文件保存在/var/lib/redis/目录中
[root@mysql redis]# pwd /var/lib/redis [root@mysql redis]# ll # 查看Redis的RDB目录下的文件 total 04.执行python脚本,向Redis中插入500万条数据
import redis client = redis.StrictRedis(host='192.168.81.101',port=6379) for i in range(5000000): client.sadd('key' + str(i),'value'+ str(i))5.向Redis中写入500万条数据完成后,执行SAVE命令
127.0.0.1:6379> save # 执行SAVE命令,花费5.72秒 OK (5.72s)6.切换另一个Redis-cli窗口执行命令
127.0.0.1:6379> spop key1 # 执行spop命令弹出'key1'的值,因为SAVE命令在执行的原因,spop命令会阻塞直到save命令执行完成,执行spop命令共花费4.36秒 "value1" (4.36s)7.查看Redis占用的内存数
127.0.0.1:6379> info memory # 向Redis中写入500万条数据后,Redis占用1.26G内存容量 # Memory used_memory:1347976664 used_memory_human:1.26G used_memory_rss:1381294080 used_memory_rss_human:1.29G used_memory_peak:1347976664 used_memory_peak_human:1.26G total_system_memory:2080903168 total_system_memory_human:1.94G used_memory_lua:37888 used_memory_lua_human:37.00K maxmemory:0 maxmemory_human:0B maxmemory_policy:noeviction mem_fragmentation_ratio:1.02 mem_allocator:jemalloc-3.6.0 127.0.0.1:6379> dbsize # 查看Redis中数据总数 (integer) 49999998.在系统命令提示符中查看生成的RDB文件
[root@mysql redis]# ls -lah # Redis的RDB文件经过压缩后的大小为122MB total 122M drwxr-x--- 2 redis redis 22 Oct 13 15:31 . drwxr-xr-x. 64 root root 4.0K Oct 13 13:38 .. -rw-r--r-- 1 redis redis 122M Oct 13 15:31 dump.rdbSAVE命令的时间复杂度为O(N)
3.1.2 使用BGSAVE命令异步创建RDB文件执行BGSAVE命令也会创建一个新的RDB文件
BGSAVE不会造成redis服务器阻塞:在执行BGSAVE命令的过程中,Redis服务端仍然可以正常的处理其他的命令请求
BGSAVE命令执行步骤:
1.Redis服务端接受到BGSAVE命令 2.Redis服务端通过fork()来生成一个名叫redis-rdb-bgsave的进程,由redis-rdb-bgsave子进程来创建RDB文件,而Redis主进程则继续处理客户端的命令请求 3.当redis-rdb-bgsave子进程创建完成RDB文件,会向Redis主进程发送一个信号,告知Redis主进程RDB文件已经创建完毕,然后redis-rdb-bgsave子进程退出 4.Redis服务器(父进程)接手子进程创建的RDB文件,BGSAVE命令执行完毕BGSAVE命令执行过程如下图所示