相关阅读:
一、Redis的回收策略:
Redis是基于内存的数据库,当存放在内存中的数据量超过一定的阈值的时候,就会触发Redis对某些数据进行淘汰回收,常见的回收策略有:
(1)allkeys-lru:使用最近最少使用LRU算法移除key;
(2)volatile-lru:使用LRU最近最少使用算法移除key,只针对设置了过期时间的键;
(3)allkeys-random:移除随机的key;
(4)volatile-random:在过期集合中移除随机的key,只针对设置了过期时间的键;
(5)volatile-ttl:移除那些存活时间TTL值最小的key,即那些最近要过期的key;
(6)noeviction:不进行移除。针对写操作,只是返回错误信息。
二、Reids的持久化方式:RDB和AOF
第一种持久化方式:RDB
1、什么是RDB:
在指定的时间间隔内将内存中的数据集快照写入磁盘(dump.rdb文件),即Snapshot快照,它恢复时是将快照文件从磁盘直接读到内存里。
2、默认持久化设置:
save 900 1 #在900秒(15分钟)之后,如果至少有1个key发生变化,则dump内存快照。
save 300 10 #在300秒(5分钟)之后,如果至少有10个key发生变化,则dump内存快照。
save 60 10000 #在60秒(1分钟)之后,如果至少有10000个key发生变化,则dump内存快照。
是1分钟内改了1万次,或5分钟内改了10次,或15分钟内改了1次。
3、持久化原理:
Redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入到一个临时文件中,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件。整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能。
fork的作用是复制一个与当前进程一样的进程。新进程的所有数据(变量、环境变量、程序计数器等)数值都和原进程一致,但是是一个全新的进程,并作为原进程的子进程。
4、优势:
(1)如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。
(2)相比于AOF机制,如果数据集很大,RDB的启动效率会更高。
5、劣势:
(1)在一定间隔时间做一次备份,所以如果redis意外down掉的话,就会丢失最后一次快照后的所有修改。
(2)fork的时候,内存中的数据被克隆了一份,大致2倍的膨胀性需要考虑。
第二种持久化方式:AOF:
1、什么是AOF:
以日志的形式来记录每个写操作,将Redis执行过的所有写指令记录下来(读操作不记录),只许追加文件但不可以改写文件,redis启动之初会读取该文件重新构建数据,换言之,redis重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作。(appendonly.aof文件)
2、AOF文件的rewrite机制:
(1)因为AOF采用文件追加方式,文件会越来越大,为避免出现此种情况,新增了重写机制,当AOF文件的大小超过所设定的阈值时,Redis就会启动AOF文件的内容压缩,只保留可以恢复数据的最小指令集,可以使用命令bg rewriteaof,异步执行一个 AOF(AppendOnly File) 文件重写操作。
(2)重写原理:AOF文件持续增长而过大时,会fork出一条新进程来将文件重写(也是先写临时文件最后再rename),遍历新进程的内存中数据,每条记录有一条的Set语句。重写aof文件的操作,并没有读取旧的aof文件,而是将整个内存中的数据库内容用命令的方式重写了一个新的aof文件,这点和快照有点类似。
(3)触发时机:Redis会记录上次重写时的AOF大小,默认配置是当AOF文件大小是上次rewrite后大小的一倍且文件大于64M时触发。
3、AOF持久化配置:
(1)每修改同步:appendfsync always 同步持久化,每次发生数据变更会被立即记录到磁盘,性能较差但数据完整性比较好。
(2)每秒同步:appendfsync everysec 异步操作,每秒记录,如果一秒内宕机,有数据丢失。
(3)不同步:appendfsync no 从不同步
4、劣势:
(1)相同数据集的数据而言aof文件要远大于rdb文件,恢复速度慢于rdb。
(2)aof运行效率要慢于rdb,每秒同步策略效率较好,不同步效率和rdb相同。
注:同时开启两种持久化方式,在这种情况下,当redis重启的时候会优先载入AOF文件来恢复原始的数据,因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整。
三、Redis事务:
可以一次执行多个命令,本质是一组命令的集合。一个事务中的所有命令都会序列化,按顺序地串行化执行而不会被其它命令插入,不许加塞。即一个队列中,一次性、顺序性、排他性的执行一系列命令。
1、常用命令:
(1)开启事务:MULTI。MULTI执行之后,客户端可以继续向服务器发送任意多条命令,这些命令不会立即被执行,而是被放到一个缓存队列中,当EXEC命令被调用时,所有队列中的命令才会被执行。
(2)执行事务:EXEC。
(3)放弃事务:DISCARD。开启事务之后,可以通过调用DISCARD,清空事务队列,并放弃执行事务。
(4)监视key:WATCH。作为WATCH命令的参数的键会受到Redis的监控,Redis能够检测到它们的变化。如果在事务执行之前这些key被其他命令所改动,那么整个事务将会被打断。WATCH命令可用于提供CAS(check-and-set)功能。
(5)取消监视:UNWATCH。
2、Redis事务的特性:
(1)单独的隔离操作:事务中的所有命令都会被序列化,按顺序地执行。事务在执行的过程中,其他客户端发送来的命令请求不会插入到事务执行命令序列中。
(2)没有隔离级别的概念:事务队列中的命令没有提交之前都不会实际的被执行,因为事务提交前任何指令都不会被实际执行,也就不存在”事务内的查询会看到事务里的更新,在事务外查询不能看到”这个让人万分头痛的问题。
(3)当使用Append-Only模式时,Redis会通过调用系统函数write将该事务内的所有写操作在本次调用中全部写入磁盘。然而如果在写入的过程中出现系统崩溃,如电源故障导致的宕机,那么此时也许只有部分数据被写入到磁盘,而另外一部分数据却已经丢失。
(4)非原子性,不支持回滚:执行EXEC命令的时候,Redis同一个事务中如果有一条命令执行失败,其后的命令仍然会被执行,没有回滚。在 EXEC 命令只保证批量操作的一次性批量执行过程。官方文档的解释是:
- Redis 操作失败的原因只可能是语法错误或者错误的数据库类型操作,这些都是在开发层面能发现的问题不会进入到生产环境,因此不需要回滚。
- Redis 内部设计推崇简单和高性能,因此不需要回滚能力。
并且,Redis 的应用场景明显不是为了数据存储的高可靠而设计的,而是为了数据访问的高性能而设计,设计者为了简单性和高性能而部分放弃了原子性。
四、Redis主从复制:
Redis支持主从复制的模式。原则:主机数据更新后根据配置和策略,自动同步到备机的master/slaver机制,slave不会将数据同步到master,Master以写为主,Slave以读为主。这样可以有效减少单个机器的并发访问数量。
1、配置要点:
(1)配从库不配主。
(2)从库配置:slaveof 主库IP 主库端口:
(3)slave每次与master断开之后,都需要重新连接,除非你配置进redis.conf文件。
(4)查看redis的配置信息:info replication
2、主从复制原理:
(1)slave启动成功连接到master后会发送一个sync命令;
(2)Master接到slave的sync命令后,启动后台的存盘进程,同时收集所有接收到的用于修改数据集命令,在后台进程执行完毕之后,master将传送整个数据文件到slave,以完成一次完全同步。
(3)全量复制:slave服务在接收到主机数据库文件数据后,将其存盘并加载到内存中。
(4)增量复制:Master继续将新的所有收集到的修改命令依次传给slave,完成同步。
(5)但是只要是重新连接master,一次完全同步(全量复制)将被自动执行。
3、常用三招:
a、一主二从:一个Master两个Slave
b、薪火相传:
上一个Slave可以是下一个slave的Master,Slave同样可以接收其他slaves的连接和同步请求,那么该slave作为了链条中下一个的master,可以有效减轻master的写压力。但是,如果中途变更转向,则会清除之前的数据,重新建立拷贝最新的主机数据。
c、反客为主:SLAVEOF no one。原本的Master挂掉之后,执行此命令,会重新选择一台Master。
4、哨兵模式(sentinel):
反客为主的自动版,能够后台监控主机是否故障,如果故障了根据投票数自动将从库转换为主库。
如果之前的master重启回来,不会造成双master冲突,因为原本的master会变成slave。
5、主从复制的缺点:由于所有的写操作都是先在Master上操作,然后同步更新到Slave上,所以从Master同步到Slave机器有一定的延迟,当系统很繁忙的时候,延迟问题会更加严重,Slave机器数量的增加也会使这个问题更加严重。