redis的事务和持久化

141 阅读7分钟

一.redis事务

1.redis事务的本质:一组命令的集合

2.redis当条命令保证原子性,但是事务不保证原子性。

3.redis事务特性:一次性(进入一个执行队列执行)、顺序性(顺序执行命令)、排他性(不允许被干扰)

4.事务执行流程:开启事务(multi) 命令入队 执行事务(exec)

5.取消事务:discard

6.运行期异常,其他命令也会正常执行。

image.png

.编译期异常,所有命令都不会执行

image.png

注意

  • 存在语法错误的情况下,所有命令都不会执行
  • 存在运行错误的情况下,除执行中出现错误的命令外,其他命令都能正常执行 redis中的事务是不满足原子性的,在运行错误的情况下,并没有提供类似数据库中的回滚功能。
  • redis命令失败只会发生在语法错误或数据类型错误的情况,这一结果都是由编程过程中的错误导致,这种情况应该在开发环境中检测出来,而不是生产环境
  • 不使用回滚,能使redis内部设计更简单,速度更快
  • 回滚不能避免编程逻辑中的错误,如果想要将一个键的值增加2却只增加了1,这种情况即使提供回滚也无法提供帮助 基于以上原因,redis官方选择了更简单、更快的方法,不支持错误回滚。这样的话,如果在我们的业务场景中需要保证原子性,那么就要求了开发者通过其他手段保证命令全部执行成功或失败,例如在执行命令前进行参数类型的校验,或在事务执行出现错误时及时做事务补偿。

7.redis可以使用watch监视机制,当作乐观锁操作。 image.png

另外线程修改money为200后,导致事务执行不成功。获取money时,事务会使用watch比较money是否已经改变,改变了则不能执行成功。

二.redis持久化

1.了解配置文件redis.conf

通用配置

大小写不敏感: units are case insensitive so 1GB 1Gb 1gB are all the same.

可以把多个配置文件组合 include /path/to/local.conf include /path/to/other.conf include /path/to/fragments/*.conf

网络:默认只能本机访问 bind 127.0.0.1 -::1

是否受保护的 protected-mode no

启动端口 port 6379

后台运行(默认 no,需改成守护线程) daemonize yes

如果以后台运行就需要指定pid文件 pidfile /var/run/redis_6379.pid

日志级别 loglevel notice

生成日志文件位置名 logfile ""

默认数据库数量:16 databases 16

SNAPSHOTTING快照配置

持久化:rdb和aof ,redis时内存数据库,没有持久化,断电即失

持久化规则:如果3600S内至少有一个key进行修改,就进行持久化操作,依次类推 save 3600 1 300 100 60 10000

持久化如果出错了,redis是否还需要继续工作 stop-writes-on-bgsave-error yes

是否压缩rdb文件,需要消耗cpu资源 rdbcompression yes

保存rdb文件时,是否校验 rdbchecksum yes

rdb文件保存目录,默认当前目录,redis持久化恢复就是从这个目录下的dump.rdb文件进行恢复 dir ./

rdb文件名字 dbfilename dump.rdb

异步删除rdb rdb-del-sync-files no

REPLICATION主从复制

SECURITY安全配置

设置密码 requirepass foobared 如: requirepass 123456 或者命令:config get requirepass(查看密码)`` config set requirepass 123456(设置密码) 登录时:auth 123456

CLIENTS

最多客户端连接数 maxclients 10000

MEMORY MANAGEMENT

redis设置内存 64位操作系统默认不限制,一般设置为最大内存的3/4 maxmemory <bytes>

命令设置:config set maxmemory 1 单位 byte(字节)

查看内存:info memory 超出内存会报oom

内存淘汰策略
maxmemory-policy noeviction 默认的淘汰策略,*Don't evict anything, just return an error on write operations.*内存满了返回错误。

1、volatile-lru: 只对设置了过期时间的key进行LRU(默认值) 

2、allkeys-lru : 删除lru算法的key   

3、volatile-random: 随机删除即将过期key   

4、allkeys-random: 随机删除   

5、volatile-ttl : 删除即将过期的  

6、noeviction : 永不过期,返回错误

redis是惰性删除,到期的key不会删除,只有使用时判断是否过期才会删除(到期删除会占用cpu资源,对cpu不友好,选择用时删除,减轻cpu压力) 这种导致存在很多过期key占用空间,得不到释放。

定时删除(过期就删,对cpu不友好)-->惰性删除(用时才删,占用内存,对内存不友好)-->定期删除(淘汰算法,定期淘汰一些过期数据)

最终选择定期删除:每隔一段时间执行一次删除过期键操作,通过限制删除操作的时长和频率来减少对cpu的影响。 定期抽查过期数据,存在漏网之鱼,一直没有被用到或者被查到,从而一直占用空间。

内存淘汰策略: 一般用:allkeys-lru 最近最少使用

配置方式:

1.文件方式:maxmemory-policy allkeys-lru

2.命令方式:config set maxmemory-policy allkeys-lru

APPEND ONLY MODE

aof模式(默认不开启,默认使用rdb持久化) appendonly no

aof持久化名字: appendfilename "appendonly.aof"

每秒执行一次,宕机则丢失一秒数据 appendfsync everysec

每次修改都会sync,消耗内存 appendfsync always

不执行snyc,操作系统自己同步数据,速度最快 appendfsync no

2.redis持久化两种方式

1.rdb方式(redis database):在指定的时间间隔将内存中的数据写入磁盘。写进快照(snapshot),恢复也是将快照直接读到内存。

redis会创建一个子进程(fork)来进行持久化,先将数据读取到一个临时文件,持久化都结束了,再替换上个版本的持久化文件,整个过程主进程都是不进行i/o操作的,确保了极高的性能,如果要进行大规模数据恢复,且对数据完整性要求不高,rdb方式比aof方式更加高效。rdb在持久化时间间隔可能存在数据丢失。默认的方式就是rdb。

rdb保存的文件是:dump.rdb 文件。dbfilename dump.rdb

1.save XXXX 会触发redis进行持久化,生成dump.rdb 2.执行了flushall 会生成dump.rdb 3.退出redis,也会产生dump.rdb文件

恢复rdb文件:只需要把rdb文件放在启动目录下,redis启动时就会加载这个配置文件。

优点:适合大规模数据恢复,效率高

缺点:时间间隔存在数据丢失,fork子进程会占用一定内容空间。

2.aof方式(append only file):将所有命令都记录下来,恢复的时候再把所有命令都全部执行一遍。

redis重启的话会根据日志文件的内容将指令从前到后全部执行一遍以完成对数据的恢复(大数据情况下恢复数据慢)。

aof保存的文件是:appendonly.aof文件 appendfilename "appendonly.aof"

默认不开启:appendonly no 设置成 yes 开启

每秒执行一次:appendfsync everysec

默认生成:appendonly.aof 文件

如果appendonly.aof 文件出错了,可以使用redis-check-aof 进行修复。

优点:1.每次修改都记录,文件完整性相对更好 2.每秒同步一次,可能丢失一秒数据

缺点:1.文件大小aof远大于rdb,修复速度慢 2.aof运行效率低

aof 默认文件追加,文件会越来越大,如果文件太大,fork一个新的进程进行重写。

如果两种都配置,redis重启后优先使用aof进行恢复,因为数据更加完整。rdb更加适合做备份。

RDB: RDB 持久化机制,是对 redis 中的数据执行周期性的持久化。

AOF: AOF 机制对每条写入命令作为日志,以 append-only 的模式写入一个日志文件中,在 redis 重启的时候,可以通过回放 AOF 日志中的写入指令来重新构建整个数据集。