文章目录
- 一、实验内容及要求
- 二、知识总结
- 三、Docker下redis的数据持久化具体操作
- 四、散列(Hash)数据类型实验具体操作
- 简介
- 具体操作
- hset <key><field><value> :给<key>散列中的 <field>键赋值<value>
- hget <key1><field>从<key1>: <key1>散列中的<field>中取出 value
- hmset <key1><field1><value1><field2><value2>... : 在<key1>散列中为多个键设置值
- hmget <key1><field1><value1><field2><value2>... : 在<key1>散列中为获取多个键的值
- hkeys <key>: 列出hash集合<key>的所有field:
- hexists <key1> <field>: 查看哈希表<key1>中,给定域 field 是否存在
- hvals <key>: 列出hash集合<key>的所有value
- hgetall <key>: 列出hash集合<key>的所有键值对
- hincrby <key><field><increment>为哈希表 key 中的域 field 的值加上增量
- hsetnx <key> <field> <value>:当且仅当域field 不存在时,将哈希表<key>中的域 field 的值设置为value
- hdel <key> <field> [<field1> ...]: 删除散列中指定键及其相对应的值
一、实验内容及要求
(1)完成Docker下redis的数据持久化;
(2)自行设计散列(hash)型数据,并针对这些数据执行常用的集合操作。
二、知识总结
1、Redis的数据持久化
持久化可以理解为数据的永久存储,就是将数据存储到一个不会丢失的地方。如果
把数据放在内存中,电脑关闭或重启数据就会丢失,所以放在内存中的数据不是持久化 的,而放在磁盘就是一种持久化。
Redis 提供了2个不同形式的持久化方式。
- RDB(redis database backup file)(redis 默认的持久化方式)
- AOF(Append Of File)
AOF和RDB同时开启,系统默认取AOF的数据(数据不会存在丢失)
①RDB(Redis DataBase)方式
简介
RedisDatabase(RDB),就是在指定的时间间隔内将内存中的数据集快照写入磁
盘。当 Redis 实例故障重启后,从磁盘读取快照文件,恢复数据
快照文件称为 RDB 文件,保存了在某个时间点的全部数据,默认是保存在当前运行
目录,默认文件名是 dump.rdb,该文件会自动创建。
RDB 技术非常适合做数据备份,可以保存最近一个小时,一天,一个月的全部数据。
保存数据是在单独的进程中写文件,不影响 Redis 的正常使用
备份时机
RDB 持久化在四种情况下会执行:
- 执行 save 命令:save 命令会使用主进程来执行 RDB,这个过程中其它所有命令都会被阻塞,因此一般在关闭 redis 之前或在数据迁移时可能会用到该命令。
- 执行 bgsave 命令:bgsave 命令可以异步执行 RDB:执行后会开启独立进程完成 RDB,主进程可以继续处理用户请求,不受影响
- Redis 停机:停机时Redis自动执行save命令,在redis 服务器重新启动时,会自动读取 dump.rdb 文件,恢复数据
- 触发 RDB 条件:Redis 在配置文件 redis.conf 中,设置了触发 RDB 的机制,打开配置文件,可以找到以下参数:
该参数表示执行 RDB 生成快照文件的时间策略。
配置格式:save <seconds> <changes>
功能:当在“seconds 秒内数据集至少有 changes 个 key 改动”这一条件被满足时, 自动保存一次数据集。如: 900 秒内,如果至少有 1 个 key 被修改,则执行 bgsave 。
注意:
– 可以根据系统的需要,加入自己的触发机制
– save “” , 表示禁用 RDB
可以通过lastsave
命令获取最后一次成功执行快照的时间
②AOF(Append Of File)方式
简介
Append-only File(AOF),Redis 每次接收到一条 更新 数据的命令时,它将把该命
令写到一个 AOF 文件中(只记录写操作,读操作不记录),只许追加文件但不可以改写文件。当 Redis 重启时,它通过执行 AOF 文件中所有的命令来恢复数据。换言之,redis 重启的话就根据AOF 文件的内容将写指令从前到后执行一次以完成数据的恢复工作。
AOF的基本配置
默认情况下,AOF 是关闭的,如果要开启需要在redis的配置文件redis.conf中配置:
appendonly yes
③两种方式比较
2、Docker下redis的数据持久化
① Docker容器的数据卷
简介
Docker 是将系统与运行的环境打包成容器来运行,当容器删除后,容器里的系统自然也就没有了。但是,在实际的项目中,希望 Docker容器产生的数据能够持久化,同时容器之间也能够共享数据。Docker提供了数据卷技术来实现这些需求。
数据卷就是目录或文件,存在于一个或多个容器中,由 Docker 挂载到容器上,完全独立于容器的生存周期,Docker不会在容器删除时删除其挂载的数据卷。即容器删除 了,数据卷仍然存在,从而实现了容器数据的持久化。
数据卷的特点
- 数据卷是宿主机中的一个目录或文件
- 当容器目录和数据卷目录绑定后,对方的修改会立即同步
- 一个数据卷可以被多个容器同时挂载,可在容器之间共享或重用数据
- 一个容器也可以被挂载多个数据卷
②具体命令解释
基本实现
创建启动容器时,使用–v 参数来设置数据卷
语法:docker run -v /宿主机绝对路径目录:/容器内目录 镜像名.....
具体例子
以在本实验中新建的redis_2容器使用的命令为例(我的Docker是在Linux环境下运行的,不过在Windows的操作也差不多的):
docker run --name redis_2 -p 6381:6379 --privileged=true \
-v /redis_2_data/redis/data:/data \
-v /redis_2_data/redis/conf/redis.conf:/etc/redis/redis.conf \
-d redis redis-server /etc/redis/redis.conf
命令解释:
docker run --name redis_2:创建一个新的redis容器命名为redis_2
-p 6381:6379:在容器的6379端口与宿主机的6381端口创建映射
–privileged=true:使当前用户在容器内操作时,具有 root 权限
-v /redis_2_data/redis/data:/data:将容器内的/data
目录与宿主机中的/redis_2_data/redis/data
进行挂载
-v /redis_2_data/redis/conf/redis.conf:/etc/redis/redis.conf:将容器内的配置文件/etc/redis/redis.conf
与宿主机的/redis_2_data/redis/conf/redis.conf
进行挂载
-d:使容器在后台运行,并返回容器ID
redis redis-server /etc/redis/redis.conf:使容器内 redis 启动时,读取配置文件
三、Docker下redis的数据持久化具体操作
我的Docker是在Linux环境下运行的,不过在Windows的操作也差不多的
要求
- 挂载一个data数据卷,用于保存备份数据;
- 使用AOF方法,在配置文件中修改,并将该配置文件挂载到redis容器上;
- 显示备份出来的aof文件;
- 模拟服务器故障,重启后,利用aof文件恢复了数据。
具体操作
创建目录和文件
这里如果是用Windows版的话,直接根据实验指导里面在文件管理器中创建相关目录,将老师给的redis.conf复制粘贴到对应的地方就可以了
先在宿主机内创建/redis_2_data/redis/conf目录和/redis_2_data/redis/conf/redis.conf文件:
使用命令:
mkdir -p /redis_2_data/redis/conf
touch /redis_2_data/redis/conf/redis.conf
新建redis_2容器
新建容器使用的命令:
docker run --name redis_2 -p 6381:6379 --privileged=true \
-v /redis_2_data/redis/data:/data \
-v /redis_2_data/redis/conf/redis.conf:/etc/redis/redis.conf \
-d redis redis-server /etc/redis/redis.conf
命令解释:
docker run --name redis_2:创建一个新的redis容器命名为redis_2
-p 6381:6379:在容器的6379端口与宿主机的6381端口创建映射
–privileged=true:使当前用户在容器内操作时,具有 root 权限
-v /redis_2_data/redis/data:/data:将容器内的/data
目录与宿主机中的/redis_2_data/redis/data
进行挂载
-v /redis_2_data/redis/conf/redis.conf:/etc/redis/redis.conf:将容器内的配置文件/etc/redis/redis.conf
与宿主机的/redis_2_data/redis/conf/redis.conf
进行挂载
-d:使容器在后台运行,并返回容器ID
redis redis-server /etc/redis/redis.conf:使容器内 redis 启动时,读取配置文件
先查看一下容器内外挂载的目录和配置文件
宿主机内data目录(/redis_2_data/redis/data):
因为此时还未开启 AOF 持久化模式,且还未写入过数据,所以此时该目录中没有appendonly.aof 文件和 dump.rdb文件
容器内data目录(/data):
使用docker exec -it redis_2 /bin/bash
命令进入容器内,并查看/data目录:
可以看到此时容器内的/data目录也为空
宿主机内的/redis_2_data/redis/conf/redis.conf文件:
也为空
容器内的/etc/redis/redis.conf文件:
可以看到此时宿主机和容器内的配置文件均为空
RDB持久化数据实验
使用redis-cli.exe连接redis容器(命令:docker exec -it 容器名 redis-cli
,比如我的这个就是docker exec -it redis_2 redis-cli
),写入数据,执行save命令:
查看宿主机和容器内的data目录:
宿主机内(/redis_2_data/redis/data):
容器内:
可见两个data目录中都有dump.rdb文件了
RDB数据恢复实验
重启该容器:
docker restart 容器名
比如我的是docker restart redis_2
查看数据是否成功恢复:
可以看到数据已成功恢复
AOF持久化数据实验
根据要求中给定的redis.conf对宿主机内的redis.conf进行配置
要求将配置文件配置为:
port 6380
save ""
appendonly yes
databases 10
#requirepass a123
编辑配置文件(Linux版)
使用vim对redis.conf进行编辑:
重启容器:
docker restart 容器名
比如我的是docker restart redis_2
可以看到重启容器后,容器内的redis.conf也成功修改了:
编辑配置文件(Windows版)
在文件管理器中找到redis文件夹中的redis.conf文件,用老师给的那个配置文件进行替换
配置好后在docker中重启容器:
docker restart 容器名
比如我的是docker restart redis_2
测试redis.conf配置是否生效
可以看到此时宿主机(/redis_2_data/redis/data)内出现了appendonly.aof 文件:
容器(/data)内也出现了appendonly.aof 文件:
测试redis_2容器内redis的端口是否改到了6380:
使用redis-cli.exe连接redis容器指定端口(命令:docker exec -it 容器名 redis-cli 端口号
,比如我的这个就是docker exec -it redis_2 redis-cli 6380
)
测试数据库是否修改成了只有10个(0-9):
可以看到,redis.conf配置已成功生效
模拟服务器故障,重启后,利用aof文件恢复了数据
先写入几个数据:
重启redis_2容器:
docker restart redis_2
使用 redis-cli.exe 连接 redis_2 容器:
docker exec -it redis_2 redis-cli 6380
查看键值对是否存在:
可以看到数据成功恢复
四、散列(Hash)数据类型实验具体操作
简介
Redis hash 是一个键值对集合。
Redis hash是一个string类型的field和value的映射表,hash特别适合用于存储对象。
用户ID为查找的key,存储的value用户对象包含姓名,年龄,生日等信息,如果用普通的key/value结构来存储
主要有以下2种存储方式:
而使用Hash方法:
具体操作
hset <key><field><value> :给<key>散列中的 <field>键赋值<value>
hget <key1><field>从<key1>: <key1>散列中的<field>中取出 value
hmset <key1><field1><value1><field2><value2>… : 在<key1>散列中为多个键设置值
hmget <key1><field1><value1><field2><value2>… : 在<key1>散列中为获取多个键的值
hkeys <key>: 列出hash集合<key>的所有field:
hexists <key1> <field>: 查看哈希表<key1>中,给定域 field 是否存在
hvals <key>: 列出hash集合<key>的所有value
hgetall <key>: 列出hash集合<key>的所有键值对
hincrby <key><field><increment>为哈希表 key 中的域 field 的值加上增量
(<increment>可以为正数也可以为负数,也可以为0,但不可为空)