非阻塞IO
非阻塞IO在套接字对象上提供了Non_Blocking选项,当选项打开时,读写方法不会阻塞,能读多少读多少,能写多少写多少,取决于内核为套接字分配的缓冲区内部的数据字节数。
事件轮询(多路复用)
现代操作系统多路复用使用epoll(linux)和kqueue(macosx),因为select系统调用性能在描述符特别多时会变得非常差。
快照原理
Redis使用COW机制来实现快照持久化,调用fork产生一个子进程,负责快照持久化,父进程继续处理读写请求。这个时候就需要操作系统的COW机制来进行数据段页面的分离,当父进程对其中一个页面修改时,会将被共享的页面复制一份出来,然后对这个复制的页面修改,子进程的页面没有变化。
随着父进程修改的数据持续进行,越来越多的共享页面被分离出来,内存会持续增长,但是不会超过原来数据内存的2倍。
AOF只记录对内存修改的指令记录。
通常主节点是不会进行持久化操作的,持久化操作是在从节点进行,从节点是备份节点,没有来自客户端请求的压力。
管道PipeLine
Pipeline本质上是客户端提供的,不是Redis服务器直接提供的技术。
内存回收机制
Redis并不总是将空闲内存立即返还给操作系统。
如果Redis内存10G,删除了1G的key后,观察内存发现并没有变化太大,原因是OS是以页为单位回收内存的,如果页上面有key还在使用就不会被回收,如果执行了flushdb,然后再观察内存,发现确实被回收了,之前使用的页面都被完全清除。
Redis会重新使用那些尚未回收的空闲内存。
主从增量同步
Redis同步的是指令流,Master会将那些对自己状态产生修改的指令记录在本地的内存buffer,然后异步将这些指令同步到Slave,Slave一边同步指令流,一边向Master返回当前同步的偏移量。
当Slave刚刚加入进来,必须先执行一次快照同步,然后再进行增量同步。
由于增量同步的内存buffer是有限的,因此要配置合适的buffer size,防止复制的死循环。
槽位迁移感知
客户端保存了槽位和节点的映射关系表,需要及时更新,才能正常将某指令发到正确的节点中。
过期策略
Redis会将每个设置过期时间的key放在独立的Hash中,以后会定时遍历这个Hash来删除到期的key,除了定期删除外,还会使用惰性策略删除过期的key,所谓惰性策略就是当客户端在访问这个key的时候,Redis会对这个key进行检查,如果过期了就删除。
从节点的过期策略
从节点是不会进行过期扫描的,Slave对过期的处理是被动的。Master在检测到某key过期后悔在AOF文件中增加一条del指令,同步到所有的Slave,Slave通过执行del指令删除过期的key。