Redis持久化,一种是快照,一种是aof日志,快照是全量备份,是内存数据的二进制序列化,在存储上紧凑,而日志是连续的增量备份,是内存数据修改的指令记录文本,时间越长,日志变得越大,需要使用bgwriteaof对aof日志重写(原理是开辟子进程对内存遍历,转换一些列Redis的操作指令,序列号到一个新的aof日志文件中。序列化完成后再将操作期间产生的增量aof日志追加到新的aof日志文件中,追加完成立即替换旧的aof日志文件),给aof日志瘦身。快照要去Redis进行io操作,可IO操作不能使用多路复用api,意味着Redis一边服务线上请求,一边进行文件IO,这样拖累服务器性能,使用操作系统多进程cow(copy on write)机制实现持久化。aof日志进行写操作时是将内容写到内核为文件描述符分配的一个内存缓存里面,然后内核会异步将脏数据写到文件中,这时突然宕机,没来得及刷到磁盘中,可以用glibc提供的fsync函数强制将内存日志刷到磁盘,可以配置,一般1s执行一次。使用方法两者都用,在Redis4版本中叫混合持久化,aof只重放快照丢失的那部分数据,这样很快,接近aof重放慢的问题,也能弥补快照丢失大量数据的缺点。
Redis中管道不是服务器特性,而是客户端通过改变读写的顺序,一次性发送多条指令,然后服务器端一次性发送多个结果,这样节省了网络流量。
在Redis中假如一个事务中有一条指令失败,另一条指令可以成功,所以Redis事务不具备原子性,具有隔离性,不被其他事务打断。
Redis中乐观锁叫watch机制(假如值被别的事务改了,则另一个事务在执行exec指令的时候返回NULL),,悲观锁叫set dd jj expires 5 nx;注意:Redis禁止在multi和exec之间执行watch指令,而必须在multi之前盯住关键变量,否则报错。
Redis使用jemalloc库来管理内存,也可以切换到tcmalloc库,但是jemalloc性能更好,可以使用info memory指令查看mem_allocator使用哪个。
主从同步的方法有增量同步,就是把主节点上的修改指令记录到本地buffer(它是定长的环形数组,如果满了,从头开始覆盖之前的内容),然后异步到从节点,从节点一边执行指令达到跟主节点一样的状态,一边反馈自己同步到哪里。还有一种叫快照同步,使用bgsave指令,非常耗费资源,先快照到磁盘,然后再将磁盘文件全部传送到从节点,从节点收到文件后立即全量加载,加载之前要将当前内存的数据清空,加载完成后通知主节点继续增量同步。在整个快照同步过程中,主节点的复制buffer,还在不停移动,如果快照同步时间过长,或复制buffer太小,都会导致同步期间的增量指令在复制buffer中被冲掉,这样导致从节点不断请求同步数据,陷入快照同步死循环,所以设置内存的复制buffer(client-output-buffer-limit和repl-backlog-size)大小很关键。还有一种无限同步是tps较高,对主节点进行大量的写操作,导致client-output-buffer-limit达到设置限制或超时,主从节点长连接强制断开,但是从节点再次请求同步数据,就会导致反复全量同步。解决上面出现的问题:1,增加从节点,2,无盘复制,主节点直径发送socket套接字到从节点,3,wait指令,把同步改异步,主要同步完成才会进行后面的服务,不然一直阻塞着,会影响可用性。