Redis-笔记

Redis 是一个高性能key-value分布式内存数据库基于内存运行并支持持久化的NoSQL数据库

支持的数据结构:String、List、Set、Hash、Sorted Set.


一、Redis的回收策略

(1)volatile-lru:使用LRU算法移除key,只针对设置了过期时间的键;

(2)allkeys-lru:使用LRU算法移除key;

(3)volatile-random:在过期集合中移除随机的key,只针对设置了过期时间的键;

(4)allkeys-random:移除随机的key;

(5)volatile-ttl:移除那些TTL值最小的key,即那些最近要过期的key;

(6)noeviction:不进行移除。针对写操作,只是返回错误信息。

 


二、Reids的持久化方式:RDB和AOF

RDB:

1、介绍:在指定的时间间隔内将内存中的数据集快照写入磁盘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、介绍:以日志的形式来记录每个写操作,将Redis执行过的所有写指令记录下来(读操作不记录),只许追加文件但不可以改写文件,redis启动之初会读取该文件重新构建数据,换言之,redis重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作(appendonly.aof文件)

2、AOF文件的rewrite

1AOF采用文件追加方式,文件会越来越大为避免出现此种情况,新增了重写机制,当AOF文件的大小超过所设定的阈值时,Redis就会启动AOF文件的内容压缩,只保留可以恢复数据的最小指令集,可以使用命令bgrewriteaof,异步执行一个 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、常用命令:

开启事务:MULTI

执行事务:EXEC

放弃事务:DISCARD

监视key:WATCH key:监视一个或者多个key,如果在事务执行之前这些key被其他命令所改动,那么事务将会被打断。WATCH命令可用于提供CAS(check-and-set)功能

取消监视:UNWATCH

2、特性:

(1)单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断从而保证了事务中的所用命令被原子执行。

2不保证原子性:redis同一个事务中如果有一条命令执行失败,其后的命令仍然会被执行,没有回滚

3没有隔离级别的概念:队列中的命令没有提交之前都不会实际的被执行,因为事务提交前任何指令都不会被实际执行,也就不存在”事务内的查询要看到事务里的更新,在事务外查询不能看到”这个让人万分头痛的问题
4当使用Append-Only模式时,Redis会通过调用系统函数write将该事务内的所有写操作在本次调用中全部写入磁盘。然而如果在写入的过程中出现系统崩溃,如电源故障导致的宕机,那么此时也许只有部分数据被写入到磁盘,而另外一部分数据却已经丢失。

 


四、Redis主从复制:

        redis支持主从复制的模式原则:主机数据更新后根据配置和策略,自动同步到备机的master/slaver机制,slave不会将数据同步到masterMaster以写为主,Slave以读为主这样可以有效减少单个机器的并发访问数量

1、配置要点:

1配从库不配主

2从库配置:slaveof 主库IP 主库端口

(3)slave每次与master断开之后,都需要重新连接,除非你配置进redis.conf文件

(4)查看redis的配置信息:info replication

 2、常用三招:

a、一主二从:一个Master两个Slave

(1)切入点问题?slave1、slave2是从头开始复制还是从切入点开始复制?比如从k4进来,那之前的123是否也可以复制答:从头开始复制

(2)从机是否可以写?set可否?答:不可以。

(3)主机shutdown后情况如何?从机是上位还是原地待命答:如果没有配置哨兵模式,则是原地待命。

(4)主机又回来了后,主机新增记录,从机还能否顺利复制?答:能。

(5)其中一台从机down后情况如何?依照原有它能跟上大部队吗?答:需要重新连接。

b、薪火相传:

上一个Slave可以是下一个slave的Master,Slave同样可以接收其他slaves的连接和同步请求,那么该slave作为了链条中下一个的master,可以有效减轻master的写压力

中途变更转向:会清除之前的数据,重新建立拷贝最新的

c、反客为主:

SLAVEOF no one原本的Master挂掉之后,执行此命令,会重新选择一台Master

3、主从复制原理:

(1)slave启动成功连接到master后会发送一个sync命令

(2)Master接到命令启动后台的存盘进程,同时收集所有接收到的用于修改数据集命令,在后台进程执行完毕之后,master将传送整个数据文件到slave,以完成一次完全同步

(3)全量复制:而slave服务在接收到数据库文件数据后,将其存盘并加载到内存中。

(4)增量复制:Master继续将新的所有收集到的修改命令依次传给slave,完成同步

(5)但是只要是重新连接master,一次完全同步(全量复制)将被自动执行

4、哨兵模式(sentinel)

反客为主的自动版,能够后台监控主机是否故障,如果故障了根据投票数自动将从库转换为主库 

配置步骤:

(1)在自定义的/myredis目录下新建sentinel.conf文件,名字绝不能错

(2)配置哨兵,在配置文件中写: sentinel monitor 被监控数据库名字(自己起名字) 127.0.0.1 6379 1

上面最后一个数字1,表示主机挂掉后salve投票看让谁接替成为主机,得票数多少后成为主机。

(3)启动哨兵:redis-sentinel /myredis/sentinel.conf

问题:如果之前的master重启回来,会不会双master冲突?答:原本的master变成slave

5、主从复制的缺点:由于所有的写操作都是先在Master上操作,然后同步更新到Slave上,所以从Master同步到Slave机器有一定的延迟,当系统很繁忙的时候,延迟问题会更加严重,Slave机器数量的增加也会使这个问题更加严重。

 


 五、面试的一些问题:

1、redis常见性能问题和解决方案:

(1) Master最好不要做任何持久化工作:如RDB内存快照和AOF日志文件.Master写内存快照,save命令调度rdbSave函数,会阻塞主线程的工作,当快照比较大时对性能影响是非常大的,会间断性暂停服务,所以Master最好不要写内存快照。

(2) Master AOF持久化,如果不重写AOF文件,这个持久化方式对性能的影响是最小的,但是AOF文件会不断增大,AOF文件过大会影响Master重启的恢复速度。Master最好不要做任何持久化工作,包括内存快照和AOF日志文件,特别是不要启用内存快照做持久化,如果数据比较关键,某个Slave开启AOF备份数据,策略为每秒同步一次。

(3) 为了主从复制的速度和连接的稳定性,Master和Slave最好在同一个局域网内

(4) 尽量避免在压力很大的主库上增加从库

(5) 主从复制不要用图状结构,用单向链表结构更为稳定,即:Master <- Slave1 <- Slave2 <- Slave3...

这样的结构方便解决单点故障问题,实现Slave对Master的替换。如果Master挂了,可以立刻启用Slave1做Master,其他不变。

2、Redis是单进程单线程的

        redis利用队列技术将并发访问变为串行访问,消除了传统数据库串行控制的开销。

3、redis的并发竞争问题如何解决?

        Redis为单进程单线程模式,采用队列模式将并发访问变为串行访问。Redis本身没有锁的概念,Redis对于多个客户端连接并不存在竞争,但是在Jedis客户端对Redis进行并发访问时会发生连接超时、数据转换错误、阻塞、客户端关闭连接等问题,这些问题均是由于客户端连接混乱造成。对此有2种解决方法:

(1)客户端角度为保证每个客户端间正常有序与Redis进行通信,对连接进行池化,同时对客户端读写Redis操作采用内部锁synchronized。

(2)服务器角度,利用setnx实现锁。SET if Not eXists)

4、redis 最适合的场景

(1)会话缓存(Session Cache)

最常用的一种使用Redis的情景是会话缓存(session cache)。用Redis缓存会话比其他存储(如Memcached)的优势在于:Redis提供持久化。

(2)全页缓存(FPC)

(3)队列

Reids在内存存储引擎领域的一大优点是提供 list 和 set 操作,这使得Redis能作为一个很好的消息队列平台来使用。

(4)排行榜/计数器

Redis在内存中对数字进行递增或递减的操作实现的非常好。集合(Set)和有序集合(Sorted Set)也使得我们在执行这些操作的时候变的非常简单

(5)发布/订阅Publish, Subscribe

 

 

猜你喜欢

转载自blog.csdn.net/a745233700/article/details/80931516