Redis的数据类型事务以及持久化
Posted 小生凡一
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redis的数据类型事务以及持久化相关的知识,希望对你有一定的参考价值。
目录
1. 基本的数据类型
1.1 字符串String
命令 | 操作名称 |
---|---|
set | 设置一个key和value |
mset | 设置多个key和value |
get | 通过key获取一个value |
mget | 通过多个key可以获取多个value |
setrange | 把key的value中的一个范围内的数值进行替换 |
append | 追加 |
getrange | 获取key的value中的一个范围内的数值 |
getset | 使用GETSET命令将给定key的值设置为value,并返回key的旧值。 返回值:返回给定key的旧值。如果key不存在,则返回nil;如果key存在但不是字符串类型的,则返回错误。 |
incr | 将这个key的value+1 |
incrby | 将这个key的value + n |
incrbyfloat | 将这个key的value + 浮点的n |
decr | 将这个数 - 1 |
decrby | 将这个数进行 - n |
getbit | 获取这个位置对应的二进制 |
setbit | 设置对应的二进制上的值 |
bitop | 使用BITOP命令对一个或多个保存二进制位的字符串key进行位元运算,并将运算结果保存到destkey中 |
1.2 列表 list
命令 | 操作 |
---|---|
LPUSH/RPUSH | |
LPOP/RPOP | |
lrange | |
lrem | |
ltrim | |
LSET | |
lindex | |
llen | |
linsert | |
Brpop/blpop | |
rpoplpush |
1.3 集合 set
命令 | 操作名称 |
---|---|
sadd | |
srem | |
spop | |
srandmember | |
sismember | |
smembers | |
scard | |
smove | |
Sinter /suNion /sdiff | |
SINTERSTORE/SUNIONSTORE/SDIFFSTORE |
1.4 有序集合 zset
命令 | 操作 |
---|---|
zadd | |
zrem | |
zremrangebyscore | |
zremrangebyrank | |
zrank | |
zrevrank | |
ZRANGE | |
zrevrange | |
zrangebyscore | |
zcard | |
zcount | |
Zinterstore/ ZUNIONSTORE |
1.5 哈希 hash
命令 | 操作 |
---|---|
hset | |
hmset | |
hget | |
hmget | |
hgetall | |
hdel | |
hlen | |
hexists | |
hinCrby | |
hinCrby | |
float | |
hkeys | |
Hvals |
2. Redis 事务
事务的本质是一组命令的集合,一个事务中的所有的命令都会序列化,按顺序地串行化而不会被其他命令插入,不许阻塞。
2.1 事务对比
我们可以用mysql的事务进行对比。
事务 | Redis | MySQL |
---|---|---|
开启事务 | MULTI | start transaction |
失败 | DISCARD 取消 | rollback 回滚 |
成功 | EXEC 执行 | commit 执行 |
redis中使用multi命令表示事务开始,在multi之后再输入redis命令,返回的不是ok,而是queued
,表示该命令并没有执行,而是放入了队列
中,这时候我们就要用exec
命令完成事务。在执行队列中的命令过程中,不允许执行其他redis命令。
关于执行错误的语句:
- 语法错误的命令,该条命令回车后直接报错。执行exec之后,所有事务中的语句均得不到执行。
- 语法正确的而执行后会报错的命令,回车后先存到队列,exec之后会执行正确的语句,并跳过执行后会报错的语句。
为什么redis没有回滚功能:
- 没有任何机制能避免程序员自己造成的错误,并且这类错误通常不会出现在生产环境中出现,所以Redis选择了更简单,更快速的无回滚方式来处理事务。
- 这类错误应该由程序员负责
悲观锁:常用来数据备份,格式化
乐观锁:常用来多读应用
2.2 事务过程
-
当服务器接收到客户端发送过来的命令是
MULTI
、EXEC
、WATCH
、DISCARD
、UNWATCH
中的任意一个时,服务器会立即执行这个命令 -
否则服务器不会立即执行这个命令,而是将该命令放入一个事务队列中,然后返回
QUEUED
标识给客户端
2.3 一个面试题
Redis 是否支持事务?
答:事务的原子性要求:**一个原子事务要么完整执行,要么干脆不执行。 **
在redis事务中语法错误的命令不会存到队列,该条命令回车后直接报错,exec之后所有事务中的语句得不到执行;而语法没错而执行后会报错的命令,会先存到队列中,exec后会执行正确的语句,跳过执行后会报错的语句
6,因此不完全满足原子性特征
3. Redis 持久化
Redis 作为数据库存储数据,希望长久保存数据库,就需要持久化
3.1 RDB 方式
根据指定的规则“定时”将内存中的数据(快照)保存到硬盘中
每隔N分钟或者N次写操作后,Redis会自动将内存中的所有数据生成一份副本,经过压缩成二进制文件存储在硬盘目录,这个过程也被称为快照。
快照文件可以还原当时的数据库状态,由于快照文件保存在硬盘上,就算服务器停止服务,也可以利用RDB文件来还原数据库状态
3.1.1 快照的实现过程
- Redis 调用执行fork函数复制一份当前进程(父进程)的副本(子进程)
- 父进程继续处理来自客户端的命令请求,而子进程则将内存中的数据写到硬盘中的一个
临时RDB
文件中. - 当子进程把所有数据写完后,也就表示快照生成完毕,此时旧的RDB文件将会被这个临时RDB文件替换,这个旧的RDB文件也会被删除。
- 在执行fork函数的过程中,父、子进程共享同一内存数据
- 当父进程要修改某个数据时,操作系统会将这个
共享内存数据
另外复制一份给子进程使用,以此来保证子进程的正确运行
如果写操作比较多,内存使用量变大(复制很多)
3.1.2 RDB优点
- RDB 文件是一个经过压缩的二进制文件,文件紧凑,体积较小(如果开启压缩模式),非常适用于进行
数据库数据备份
- RDB持久化用于
灾难恢复
,而且恢复数据时的速度快(因为是内存快照,将快照文件直接读到内存里) - 并行性好,单独的进程
保存RDB快照
,保存RDB的过程中,其他进程继续处理其他相关的操作
3.1.3 RDB的缺点
- 如果两个RDB保存点之间发生了断电,那么就会损失两个保存点之间时间段写入的数据。
- 当数据量非常庞大时,在生成和保存RDB文件的时候,操作比较耗时,将会占用太多CPU时间,从而影响服务器的性能。
- RDB文件存在兼容性问题,老版本的Redis不支持新版本的RDB文件
3.2 AOF持久化
3.2.1 AOF简介
将每次执行的命令及时形成日志保存到硬盘中
- 保存服务器执行的所有写操作命令到单独的日志文件中
- 在服务器重启时,通过加载日志文件中的这些命令并执行来恢复数据(实时性更好,也就是当进程意外退出时,丢失的数据更少)
3.2.2 AOF 重写
- AOF持久化的实现是通过保存被执行的
写命令
来保存数据库数据 - 随着运行时间的增加,
AOF文件
的内容增大,占空间变多 - 太大的AOF文件会影响服务器的正常运行,在执行数据恢复时,将会耗费更多的时间
AOF重写是指把内存中的数据,逆化成命令,写入AOF日志中,以解决AOF日志过大的问题
重写会丢弃过期的数据
,无效
的命令,也可以 多条命令合并为一条命令
3.3 持久化面试题
问:RDB恢复的速度快,还是AOF恢复的速度快?
RDB快,因为其是数据的内存映射,即快照,直接载入到内存即可,AOF文件记录的是一行一行的命令,需要逐条执行才能得到数据库的最终形态。
以上是关于Redis的数据类型事务以及持久化的主要内容,如果未能解决你的问题,请参考以下文章