> 文章列表 > Java知识点学习(第17天)

Java知识点学习(第17天)

Java知识点学习(第17天)

什么是RDB和AOF?

RDB:Redis DataBase,在指定的时间间隔内将内存中的数据集快照写入磁盘,实际操作过程是fork一个子进程,先将数据集写入临时文件,写入成功之后,再替换之前的文件,用二进制压缩存储。

优点:

  1. 整个Redis数据库将只包含一个文件dump.rdb,方便持久化。
  2. 容灾性好,方便备份。
  3. 性能最大化,fork子进程来完成写操作,让主进程继续处理命令,所以是IO最大化。使用单独子进程来进行持久化,主进程不会进行任何IO操作,保证了redis的高性能。
  4. 相当于数据集大时,比AOF的启动效率更好。

缺点:

  1. 数据安全性低。RDB是间隔一段时间进行持久化,如果持久化之间redis发送故障,会发生数据的丢失。所以这种方式更加适合数据要求不严谨的时候。
  2. 由于RDB是通过fork子进程来协助完成数据持久化工作的,因此,如果当数据集较大时,可能会导致服务器停止服务几百毫秒,甚至秒钟。

AOF:Append Only File,以日志的形式记录服务器所处理的每一个写、删除操作,查询操作都不会记录,以文本的形式进行记录,可与i看到详细的操作记录。

优点:

  1. 数据安全:Redis中提供了3种同步策略,即每秒同步、没修改同步和不同步。事实上,每秒同步也是异步完成的,其效率也是非常高的,所差的是一旦系统出现宕机现象,那么这一秒钟内修改的数据将会丢失。而每修改同步,我们可以将其视为同步持久化,即每次发生的数据变化都会立即记录到磁盘中。
  2. 通过append模式写文件,即使中途服务器宕机也不会破坏已经存在的内容,可以通过redis-check-aof工具解决数据一致性问题。
  3. AOF机制的rewrite模式。定期对AOF文件进行重写,以达到压缩的目的。

缺点:

  1. AOF文件比RDB文件大,且恢复速度慢。
  2. 数据集大的时候,比rdb启动效率低。
  3. 运行效率没有RDB高。

Redis的过期键的删除策略

Redis是key-value数据库,我们可以设置Redis中缓存的key的过期时间。Redis的过期策略就是指当Redis中缓存的key过期了,Redis如何处理。

  • 惰性过期:只有当访问一个key时,才会判断key是否过期,过期则清除,该策略可以最大化的节省CPU资源,对内存非常不友好。极端情况下可能出现大量的过期key没有再次被访问,从而不会被清除,占用大量内存。
  • 定期过期:每隔一定的时间,会扫描一定数量的数据库的expires字典中一定数量的key,并清除其中已经过期的key。该策略是前两者的一个折中方案。通过调整定时扫描的时间间隔和每次扫描的限定耗时,可以在不同情况下使得CPU和内存资源达到最优的平衡效果。

(expires字典会保存所有设置了过期时间的key的过期时间数据,其中,key是指向键空间中的某个键的指针,value是该键的毫秒精度的UNIX时间戳表示的过期时间。键空间是指该Redis集群中保存的所有键。)Redis中同时使用了惰性过期和定期过期两者过期策略。

简述Redis事务实现

  1. 事务开始
    MULTI命令的执行,标识着一个事务的开始。MULTI命令会将客户端状态的flags属性中打开REDIS
    _MULTI标识来完成的。
  2. 命令入队
    当一个客户端切换到事务状态之后,服务器会根据这个客户端发送来的命令来执行不同的操作。如果客户端发送的命令为MULTI、EXEC、WATCH、DISCARD中的一个,立即执行这个命令,否则将命令放入一个事务队列里面,然后向客户端返回QUEUED回复
  • 如果客户端发送的命令为MULTI、EXEC、WATCH、DISCARD中的一个,那么服务器立即执行这个命令。
  • 如果客户端发送的是这四个命令以外的其他命令,那么服务器并不会立即执行这个命令。首先检查此命令的格式是否正确,如果不正确,服务器会在客户端状态的flags属性关闭REDIS
    _MULTI标识,并且返回错误信息给客户端。如果正确,将这个命令放入一个事务队列里面,然后向客户端返回QUEUED回复。事务队列是按照FIFO的方式保存入队的命令。
  1. 事务执行
    客户端发送EXEC命令,服务器执行EXEC命令逻辑。
  • 如果客户端状态的flags属性不包含REDIS_MULTI标识,或者包含REDIS_DIRTY_CAS或者REDIS_DIRTY_EXEC标识,那么就直接取消事务的执行。
  • 否则客户端处于事务状态(flags有REDIS_MULTI标识),服务器会遍历客户端的事务队列,然后执行事务队列中的所有命令,最后将返回结果全部返回给客户端。

redis不支持事务回滚机制,但它会检查每一个事务中的命令是否错误。
redis事务不支持检查那些程序员自己的逻辑错误,例如对String类型的数据库键值对对HashMap类型的操作。

  • WATCH命令是一个乐观锁,可以为Redis事务提供check-and-set(CAS)行为。可以监控一个或多个键,一旦其中有一个键被修改(或者删除),之后的事务就不会执行。监控一直持续到EXEC命令。
  • MULTI命令用于开启一个事务,它总是返回OK,MULTI执行之后,客户端可以继续向服务区发送任意多条命令,这些命令不会立即被执行,而是被放在一个队列中,当EXEC命令被调用时,所有队列中的命令才会被执行。
  • EXEC:执行所有事务块内的命令。返回事务块内所有命令的返回值,按命令执行的先后顺序排列。当操作被打断时,返回空值。
  • 通过调用DISCARD,客户端可以清空事务队列,并放弃执行事务,并且客户端会从事务状态中退出。
  • UNWATCH命令可以取消watch对所有key的监控。