一、持久化
1、由于数据都是放在内存操作的,那么假如我重启的话,数据就没了
2.我需要一个持久化(数据由内存放到磁盘),重启的时候,可以从磁盘去加载数据,保证redis高可用
3.RDB:快照 Redis DataBase(默认的) 在某个时间断,我会把当前内存的所有的数据进行落盘,生成一个磁盘文件
4 地址跟文件名的配置: dbfile dump.rdb //磁盘文件  dir./
5.什么时候会去出发RDB快照
a.自动触发 1.配置触发  
save 900 1 900s 检查一次,如果有一个key被修改,就会触发
save 300 10 300s 检查一次,如果有10个key被修改,就会触发
save 60 1000 60s 检查一次,如果有1000个key被修改,就会触发
2.shutdown服务正常关闭
3.flushall 清空数据的指令 备份一个空的RDB文件
b.手动触发
1.save 保存 阻塞我的主线程 阻塞其他指令 保证数据一致性
2.bgsave 新起子进程去做 可能不是最新的数据 不会阻塞其他指令
a.怎么备份:1.新起子进程 会把redis数据写到一个临时文件
          2.替换旧的RDB文件
b.优劣势:
优势:快
1.备份、恢复快 非常紧凑的文件
2.主线程指令操作不需要跟磁盘进行任何交换
不足:
1.安全性很低 可能会有数据丢失
2.cpu不是特别友好
6.AOF:Append Only File 追加文件
1.默认是关闭的,那么假如开启了的话 默认会用AOF进行恢复 apppendonly no
2.假如每次指令都需要追加的话,每次都需要跟磁盘进行IO?mysql的redolog 3种方式0 1 2
appendfsync always 就是需要跟磁盘交互 安全最高 但是最慢
appendfsync  everysec 1s异步同步 可能会丢失1s的数据 性能适中
appendfsync  no  不管了,操作系统 linux 30s 性能最快,安全性最低
追加 越来越来! 加载数据的数据的时候很慢很慢
重写机制:什么是重写?大文件变小  incr id 100000 直接用内存的数据保存最新的
是不是只要拿到当前内存里面最新的数据以RDB的形式保存就可以了,后续追加的继续追加
RDB+AOF: aof-use-rdb-preamble yes
a.什么时候重写?
auto-aof-rewrite-percentage 100下次重写必须是上次重写后大小的2倍
auto-aof-rewrite-min-size 64mb 文件就必须打到64M
b.假如说现在aof文件 64M  ---重写后大小是40M ----80M
重写逻辑:
1.新起子进程,临时文件写入新的aof(内存的数据生成一个新的aof)
2.新的指令能进来,这些指令会先放到内存,还会追加到老的aof文件
3.重写完了后,会把内存的新的指令给到我新的aof,替换我老的aop文件
c.AOF的优劣势
优势:
1.安全性非常高
2.可读性高
3.如果失败能修复
劣势:
1.恢复很慢,但是4.0之后,跟RDB一较高下
2.并发量比较高占用内存
3.重写的时候,新的指令需要2次磁盘IO  
在工作中:RDB跟AOF同时开启
二Redis集群
1.主从
a.为什么要有主从?
 1.基于主从故障恢复(不能自动)主库 从数据备份
 2.负载 主写从读 减少主库的压力
 3.高可用 sentinel 基于主从去实现
b.主从之间数据怎么保证一致性?(主的数据怎么同步到从的)
 1.相互之间肯定会建立连接,并且还能保存各自的端口,地址等等信息。
 2.假如我的slave第一次跟主建立连接,发送数据同步指令(master_repid,offset)serverCorn
 3.master就收到了,master_repid跟自己的repid是不是一样,第一次传的是个空的,master就认为是第一次来同步数据
 4.全量同步:(master_repid=repid)
     a.master bgsave生成RDB文件,并且把rdb文件给到slave,同时会把我的repid/offset给到slave
     b.生成RDB期间,会有新的指令 把这些新的指令放到一个内存
     c.replication_buff 根据slave来的  client-output-buffer-limit replica 256mb 64mb 60 超过直接断开
     d.重写完了后,会把replication_buff同步给slave
 5.增量同步:之前有同步过,只不过中间网络断开了会(master_repid=repid & offset在我的积压缓存都有的时候)
     a.发送数据同步指令(master_repid,offset)serverCorn
     b.master拿到了,发现master_repid=repid,这个时候,会去找到你这个slave还有哪些没有同步
     c.offset上次同步的偏移量,就能够知道它有哪些数据没有同步
     d.会去一个内存区间,积压缓存(replication_backlog_buffer),必须有slave,所有的指令会写入积压缓存
       #repl_backlog_size 1mb 如果超过,数据覆盖
     e.判断积压缓存里面是否有你同步到的数据,如果没有,触发全量,如果有,直接同步过去
  6.指令同步:master的指令,都会异步同步给slave
     a.如果发生主从切换,肯定会有数据丢失的场景
     b.主同步给从是异步的,所有存在没有同步成功,主挂了,从是没有主的最新的数据
2.sentinel哨兵
 a.主从不会自动故障转移
 b.作用:监控跟通知
 c.自动故障转移 配置提供
 d.怎么做自动故障转移的?
   1.发现故障:
      a.当某个sentinel跟master ping不通的时候,发现在一定时间内收不到master的回应了
        这个sentinel1认为这个master挂掉了(可能没挂) 标记为一个SDOWN(主观下线)
      b.sdown,不会故障转移,询问其他的sentinel跟master ping 如果超过过半的sentinel的挂了,那么标记
      ODown(客观下线),Objectively Down
   2.故障转移
      a.状态为ODown必须由一个sentinel去触发
      b.选举一个sentinel去触发
        1.如果配置的quornum 小于等于一半,那么必须超过半数的sentinel的授权
        2.quornum 如果超过一半,那么必须quornum的数量
      c.选哪个slave成为master

    3.脑裂问题:
      a.会导致数据丢失,2个master 都能写数据,那么当网络恢复以后,一个master的写数据会消失
        min-replicas-to-write 1 必须有多少个从 一定程度上解决脑裂带来的数据一致性问题 异步去写的
        min-replicas-max-lag 10 小于等于10s
    4.脑裂跟多少台机
        奇数跟偶数
        3台 只能挂1台 选举的话过半 超过一半
        4台 只能挂1 过半2 2台没有超过一半
3.cluster 
a.没有分片的功能 最少三主三从
b.我希望做到高可用(自动故障转移)的同时,我能做负载(不同的key到不同的机器)
  1.高可用、主从切换 master slave
  2.数据分片 hash槽  key的hash值 & 3=0-3的值 能够把key放到不同的四个位置
  3.如果要扩容的时候,所有的数据都得迁移
  
  hash槽(虚拟槽) 16384个虚拟的节点 真实的节点跟虚拟建立关系
  假如 master1 slave1
       master2 slave2
       master3 slave3
  key 的chash& 16383=0-16383的值 所有的key都会有这么一个虚拟槽
       master1 0-5000
       master2 5001-10000
       master3 10001-16383
  假如 set huihui 18
  huihui & 16383= 1000 数据放入master1--->slave1
  james & 16383= 15555 数据放入master3--->slave3
  mic & 16383= 9999 数据放入master2--->slave2
  并且 key跟虚拟槽的关系是不变的,变的是槽跟真实节点的关系(配置)
  所有的虚拟槽必须有真实节点对应上,如果对应不上,有些数据不能放,集群不可用
  主从数据同步都是异步的
  相关的数据放到一个节点?
  order:{}
  
  冷热分离
c.为什么虚拟槽的大小是16384?
  集群的带下跟集群通信的速度来考虑的