Redis处理客户端请求进行数据读写是由一个主线程完成的,也就是常说的Redis是单线程的,天然不存在并发问题,但并不是说Redis就只有一个进程,其在某 些时候还会开启后台子进程,如AOF日志重写, RDB异步持久化(bgsave)。
基于内存操作:Redis速度快的直接原因是因为其是基于内存的,绝大多操作都是在内存中之直接进行的,速度极快,可以用一个线程处理众多客户端请求而不会出现性能瓶颈,而且还可以避免并发问题,不存在线程切换带来的额外性能消耗。
底层数据结构优化:Redis还对底层数据结构做了许多优化 比如String有三种编码方式在不同的情况下采用不同的编码方式减少内存空间申请次数,避免出现内存碎片,如渐进式rehash在扩容时不会阻塞。
I/O多路复用: 采用I/O多路复用机制,一个线程同时监听多个Socket连接,达到一个线 程处理多个连接的效果。
Redis的绝大多数操作都在内存中直接完成,其性能瓶颈不在CPU更多是在网络I/O的限制,核心命令的执行一个线程足以,如果在此处引入多线程反而会因为线程上下文切换,以及并发问题导致性能降低。
随着网络硬件性能提升,Redis的性能瓶颈出现在了网络I/O处理上,为了提高网络I/O并 行度,Redis6.0对于网络I/O采用多线程处理,解决网络I/O方面的性能瓶颈
Redis基于内存数据都是存储在内存中,重启或宕机后数据会被清空,Redis通过AOF日志与RDB快照将数据持久化在磁盘中,重启时从磁盘中读取恢复原有数据
RDB快照: 数据快照,直接将内存中的数据记录到磁盘中
save:主进程执行RDB,阻塞所有命令
bgsave:子进程异步RDB,不影响主进程
RDB默认触发机制: 900秒内 至少一个key被修改 执行bgsave异步持久化
*RDB是全量快照 每次执行都把所有数据记录到磁盘中,RDB操作本身消耗的系统资 源较多,执行频率不能过高,否则会造成Reids性能降低,所以数据丢失的可能性高 于AOF
RDB执行流程: 执行bgsave命令 fork一个子进程进行异步RDB持久化,子进程创建时会赋值父进程的页表,即父子进程的虚拟内存由相同的页表指向相同的物理内存实现了内存共享,即在进行RDB时无需先进行内存拷贝,fork的耗时大大降低,此时再由子进程读取内存数据并写入到新的RDB文件中替换旧文件,实现异步持久化。
copy-on-write:异步持久化意味着子进程进行RDB持久化时候,父进程任然可以进行数据修改,可能会出现读写冲突,甚至是出现脏数据,采用copy-on-write方案(写时复制)解决,首先会将数据标记为read-only只读模式,当主进程发起数据更新请求时不会直接操作原数据,而是将数据拷贝一份,页表的映射关系也会同步改变映射为拷贝后的副本数据,主进程的读写操作都会变更到副本数据上,极端情况下,若RDB异步持久化过程中,父进程不断接收到数据更新请求,那么会导致大量数据都创建副本,对内存的占用会翻倍.
RDB优缺点:备份之间间隔长数据丢失可能性大,RDB操作本身对系统资源占用高;文件体积小,直接存储数据重启速度快
AOF日志: 每执行一条写操作命令,就把该命令以追加的方式写入到一个文件里
always: 同步刷盘,每次写操作命令执行后立即记录到AOF文件中,可靠性高,数据几乎不会丢失 性能较低,影响后续操作
everysec: 每秒刷盘,命令先存放在AOF缓冲区中,每隔1秒将缓冲区数据写入到AOF文件中,最多丢失1秒数据,性能适中,可靠性较高
no: 先将命令写入AOF缓冲区中,由操作系统决定磁盘写入时机,性能最高,可靠性差,可能丢失大量数据
AOF重写机制: 随着时间的增长 AOF文件的体积越来越大,且会重复记录对一个key的多次操作,会记录中途多余的无效命令
bgrewriteaof: 开启一个子进程进行AOF文件重写,不阻塞主进程,主进程可以正常处理请求,父子进程共享同一份物理内存,子进程对内存是只读的,重新读取Redis中的所有数据,逐一把数据键值转换成命令记录到AOF日志中但是重写过程中,主进程依然可以正常处理命令,与RDB类似采用写时复制方案,Redis设置了AOF重写缓冲区,在AOF重写期间,Reids执行一个数据 修改的命令后会将该命令同时写入AOF缓冲区与AOF重写缓冲区,当子进程的AOF 重写完成后再将AOF重写缓冲区的数据追加到AOF日志中
AOF日志优缺点: 文件体积相对大 Redis重启时重新执行命令重启速度慢;数据丢失 可能性更低 AOF本身消耗的系统资源更低(重写时消耗资源多)
Redis混合持久化 Redis4.0采用混合持久化保证重启速度同时,减低数据丢失风险
为什么要有混合持久化? RDB持久化重启速度快,但执行频率不好把握,过高影响 Redis自身性能,执行频率过低数据丢失风险大;AOF持久化数据丢风险低,重启速度慢
混合持久化: 混合持久化发生在AOF重写过程中,AOF重写时fork出的子进程首先会将与父进程共享的内存数据以RDB方式写入到AOF文件中,然后父进程执行的数据更新命令会记录在AOF重写缓冲区中,再将重写缓冲区中的内容追加到追加到AOF文件中,也就是说开启混合持久化,AOF文件中前半段是RDB格式的数据后半段是AOF格式的增量数据;既可以提升重启速度也降低了数据丢失的风险