欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

redis学习总结

程序员文章站 2022-07-02 09:38:20
...

一:redis过期键删除策越
   1:惰性删除:每次get的时候才判断key是否过期,如果过期才会执行删除,这样会导致大量的过期key占用内存。
   2:定期删除:通过设置删除频率和时长(需要根据实际情况,可以压数据,看某个时间范围内过期的key有多少,占用多少内存,大概需要多久才能删除完),在某个时候执行删除操作,并只执行设置的时长时间,这样既降低了CPU消耗时间(不会长时间占用cpu去执行删除过期key的操作),同时也避免了一定的内存浪费(删除一定时长,即使还存在未删除的key,也可以下次删除)
   3: 过期键不会对RDB和AOF有影响(执行save(阻塞主进程),bgsave(直接fork出一个进程处理,主进程继续处理client请求),bgrewriteaof),在主从复制时,如果是从服务器收到get key命令,而key已经过期,那么会返回value(这个地方有可能返回过期的数据,可以设置Key的有效时间),只有当主redis收到get key时,发现Key过期了,会给所有的从redis发送del命令,删除过期key,可以看到,这完全由主redis控制,保证主从的数据一致性。
二:RDB持久化
  2.1 rdb文件用于保存和还原redis服务器数据库中所有的键值对数据
  2.2 save命令强制由主进程写rdb,阻塞client请求
  2.3 bgsave命令fork(克隆内存中个数据)出一个子进程执行写rdb,主进程继续处理请求,但是如果数据很大,fork也会很耗时,可能会导致某个时刻服务不处理请求
  2.4 最后一次持久化的数据可能丢失
三:AOF持久化
    3.1 Redis会记录上次重写时的AOF大小,默认配置是当AOF文件大小是上次rewrite后大小的一倍且文件大于64M时触发
   3.2 RDB的数据不实时,同时使用两者时服务器重启也只会找AOF文件。那要不要只使用AOF呢?建议不要,因为RDB更适合用于备份数据库(AOF在不断变化不好备份),快速重启,而且不会有AOF可能潜在的bug,留着作为一个万一的手段。 
   性能建议:
   因为RDB文件只用作后备用途,建议只在Slave上持久化RDB文件,而且只要15分钟备份一次就够了,只保留save 900 1这条规则。
   如果Enalbe AOF,好处是在最恶劣情况下也只会丢失不超过两秒数据,启动脚本较简单只load自己的AOF文件就可以了。代价一是带来了持续的IO,二是AOF rewrite的最后将rewrite过程中产生的新数据写到新文件造成的阻塞几乎是不可避免的。只要硬盘许可,应该尽量减少AOF rewrite的频率,AOF重写的基础大小默认值64M太小了,可以设到5G以上。默认超过原大小100%大小时重写可以改到适当的数值。
   如果不Enable AOF ,仅靠Master-Slave Replication 实现高可用性也可以。能省掉一大笔IO也减少了rewrite时带来的系统波动。代价是如果Master/Slave同时倒掉,会丢失十几分钟的数据,启动脚本也要比较两个Master/Slave中的RDB文件,载入较新的那个。新浪微博就选用了这种架构.
四:redis服务器处理请求流程
    Client发送请求给server--->server读取命令请求,并分析命令参数--->命令执行器根据参数查找对应命令的实现函数--->实现函数执行命令--->server将命令执行回复返给client
五 主从复制
      从服务器slaveof master ip 即可连上主服务器开始同步,同步分为完全同步和部分重同步,三者根据server运行的run id,复制偏移量,复制积压缓冲区来实现,主从server都会维护一个复制偏移量记录当前服务器数据的偏移位置,复制积压缓冲区是由主server维护的一个FIFO的队列,每次主server像从server发送同步命令的同时会将写命令入队到复制积压缓冲区,server运行的Id在每次重启后都会改变,因为它是存在内存中的一个随机生成的字符串,当slave server收到了master server发送的同步命令时,开始执行同步,如果中途网络掉线,重连的时间内主server还有数据写入,当slave server重连上master后,会将当前slave server记录的偏移量一并发送给master server,如果主从是第一次复制,将开始一次全量同步,如果不是第一次,master在判断slave发送的run id 是否是自己的id后,检查复制缓存区里是否pos+1后还有数据,如果有,表明断线后主server继续处理了写请求,这个时候master就会将pos+1后面的数据部分发送给slave执行数据同步。在主server发送命令给slave的过程中如果出现了网络故障导致一部分命令或者全部命令丢失,从server像主server发送repliy ack的时候,带过去的参数pos,主server检测到pos和自己当前的pos不一样,又会再次在复制积压缓冲区里面找到slave缺失的数据,再次发送给slave,直到master/slave数据完全同步为止。
六 sentinel哨兵线程
      sentinel主要是保证redis的高可用,在master选举的过程中发挥监听和故障转移的作用,  
   主观下线:sentinel会像其监听的master,slave,其他的sentinel发送ping命令,如果在设置的时间范围内未收到有效回复,那么监听的该sentinel就会将被监听的server在其属性中打开SRI_S_DOWN标识表示主观下线,此后该sentinel询问其它的sentinel是否也认为该server已经下线了,如果收到了半数以上的回复,那么就会将其列为客观下线,准备开始故障转移. 
   领头sentinel选举: 当master被标识为客观下线后,监视这个master的各个sentinel会协调选举出一个领头的sentinel执行故障转移,主要规则是先到先得,半数同意。
   每个sentinel都有机会成为领头的,当某一个sentinel(目标)收到来自其它sentinel(源)的请求要将源设置为领头时遵循先到先得,即谁先像目的sentinel发送了要将其自己设置为局部领头的sentinel时,最新收到请求的将成为目标sentinel的领头sentinel,其它的都拒绝,当整个sentinel中超过半数的sentinel都将某个sentinel选举为局部领头的sentinel,那么这个sentinel就会成为最终的领头sentinel(如果在一定时间内,没有选举出领头sentinel,会隔一段时间再进行选举)
七 故障转移
      1:从以下线的master的所有slave里面找一个slave执行salveof no one 将其变为master
   领头的sentinel将会在所有的slave里面选择一个slave为新的master,首先要删除slave里面不是正常在线的(ping,通讯不正常等),然后根据配置的优先级(优先级越高就是master,如果一样,看后面的条件),各个salve维护的自身偏移量(偏移量越大,说明数据越完整,如果一样看后面的条件),如果还没选举出,则根据运行的id排序后选择出最小的为新的master
  2:将其它slave的的master设置为新的master ip     
    执行slaveof masterip masterport
  3:将以下线的master设置为新的master的salve
    执行slaveof masterip masterport
八:集群
    节点通过握手来讲其它节点添加到自己的集群中,集群中的16384个槽分别指派给集群中各个主节点,当有新节点加入时,可以执行重新分片(重新分片不会对集群产生任何的影响),将某个节点所有槽对应的键值对从一个节点移动到另一个节点,当客户端发送了get key给某个server,server需要首先检查这个get命令所处理的键所在的槽是否是自己负责的,如果是,直接返回,如果不是,需要重新定向到负责这个槽的节点。如果在发生分片的过程中,如A-B,如果A收到了请求,如果key对应的槽还由A负责,则A直接返回,如果不由A处理了,节点A会返回一个ASK错误指引client去B处获取。