redis中用到这么多的缓存区,有什么作用啊
redis中的缓冲区
- aof持久化:第一步执行写入命令;第二步将写命令写到用户空间的
aof缓冲区
,后续将aof
缓冲区的写命令发送内核空间的page cache。 - aof重写:为了aof重写期间数据保持一致性,客户端写入命令时,不仅需要写入到
aof缓存区
,也需要写入到一个aof重写缓冲区
。在aof重写完成后,子进程通过信号通知父进程,父进程收到信号后会将aof重写缓存区
中的数据追加
到aof文件中。 - 在主从架构的中,主节点往从节点同步数据时,都会先讲写命令同步到主节点的
replication buffer缓冲区
中,然后异步
返回,最后通过长连接将缓存区中的数据发送到从节点,主节点会给每个新连接的从节点分配一个replication buffer缓存区
。 - 在主从架构中,主从节点是通过一个长连接来发送写数据来保持数据一致性的,但是由于网络的不可控性,该连接可能会中断的,当恢复之后从节点可能需要增量同步,也可能需要全量同步。
决定哪种同步方式的因素是replication backup buffer缓存区
,该缓存区是一个环形结构,且有固定大小,整个集群中主节点只会维护一个replication backup buffer缓存区
,且该缓存区内记录着所有消息的offet,该缓存区主要用于记录主节点增量同步从节点的数据,因为该环型缓冲区是有大小的,如果满了话后面的同步的数据会覆盖环内的缓存。
好了,知道了replication bakcup buffer缓冲区
的使用场景后,在来说它是怎么觉得使用增量同步还是全量同步的呢?
当从节点和主节点之间长连接恢复后,从节点会向主节点发送当前读取最新的offset,而主节点收到后会对比该offet和主节点最新写入的offet的差值,如果该差值范围内的所有offset在replication backup buffer缓冲区
上,则将replication backup buffer缓冲区
上对应的offset发送到replication buffer缓存区
上,即增量同步
;否则进行全量同步
。
如果主节点的写入速度大于从节点的读取速度,那么主节点上的replication backup buffer缓冲区
就会被覆盖,如果此时主节点和从节点之间的长连接断开,恢复后将采用全量复制,所以replication backup buffer缓冲区
的大小是很重要的。
在上面的持久化(写入磁盘)或者 主从同步(网络IO)中都可以看到很多缓冲区
的字眼,那么有没有想过一个问题为什么不直接写入到磁盘或者是直接请求io呢?而需要先写到缓冲区呢?
-
降低请求磁盘的频率或者降低请求网络IO的频率
:我们都知道磁盘和网络IO都是非常慢的,那么如果使用缓存区的话,通常可以合并数据
或者合并网络IO
,这样明显可以减少请求磁盘或者请求IO的次数,可以提高性能。 -
异步刷盘
:写入缓冲区中的数据不会立即同步
到磁盘或者请求IO,而是在某个时刻合并成一个更到的数据或者IO后才发生请求。
异步可以提高写入性能,因为不必等待每个写命令或者都同步到磁盘或者响应。这样可以继续处理新的IO或者新的请求,而不受到磁盘或者网络的阻塞。 -
减少磁盘页内碎片化
:将多个命令一次性写入磁盘可以降低磁盘碎片的产生。频繁地小规模写入可能会导致文件碎片化,而一次性写入可以减少这种情况。如果磁盘页大小为4K,写入的数据小于4k时写入占用一个磁盘页,这样就会造成页内碎片化。
PAGE CACHE
上面谈到了一个page cache
,其实它是也是一个缓存区,属于内核空间的缓存,叫做磁盘高速缓存区
,其作用和上面介绍的差不多
-
合并IO
:内核的 I/O 调度算法会缓存尽可能多的 I/O 请求在 PageCache 中,最后「合并」成一个更大的 I/O 请求再发给磁盘,这样做是为了减少磁盘的寻址操作;
磁盘的寻址操作是指在硬盘上找到并读取或写入数据的过程。硬盘是由多个盘片(platters)组成的,每个盘片都被分成许多圆形的轨道(tracks),而每个轨道又被划分为许多扇区(sectors)。磁头(read/write head)可以在盘片的表面上移动,而盘片则以高速旋转。
磁盘寻址操作的主要步骤包括:
寻道(Seek): 磁头从当前位置移动到目标轨道上的正确位置,这个过程称为寻道。寻道操作的时间开销取决于磁头的移动速度。
旋转(Rotational Delay): 等待目标扇区旋转到磁头的正下方,这个过程称为旋转。旋转操作的时间开销取决于磁盘的旋转速度。
传送(Transfer): 一旦目标扇区位于磁头的正下方,就可以进行数据的读取或写入。
合并 I/O 操作有助于减少磁盘的寻址操作,主要原因如下:
减少寻道次数: 将多个小的 I/O 请求合并成一个更大的请求,可以减少寻道次数。由于寻道操作通常是相对较慢的,减少寻道次数可以显著提高磁盘的读写效率。
最小化旋转延迟: 合并 I/O 请求也有助于最小化旋转延迟。如果多个请求都在同一轨道上,它们可以更有效地等待目标扇区旋转到磁头的正下方,减少了旋转延迟。
提高吞吐量: 合并 I/O 请求可以提高磁盘的吞吐量。通过将多个小的请求组合成一个大的请求,可以以更高的效率传送数据,减少传送的时间开销。
总体而言,合并 I/O 操作通过减少寻道次数和最小化旋转延迟,提高了磁盘的读写效率,增加了吞吐量,从而减少了整体的磁盘寻址时间。这对于提高系统性能和优化磁盘 I/O 是非常有益的。
-
预读
:内核也会「预读」后续的 I/O 请求放在 PageCache 中,一样是为了减少对磁盘的操作;
看到这里可能会有疑问,既然page cache
,已经有了合并IO,预读,异步刷盘的特点了,为什么还需要再用户空间在设立一层缓冲区呢?
内核的PAGE CACHE是操作系统用来管理磁盘和内存之间的缓存的,而用户空间的缓冲区则是由应用程序自身维护的一种数据缓存。
-
控制缓存策略: 应用程序可以更加精确地控制在何时将数据写入磁盘。用户空间缓冲区允许应用程序决定何时将数据刷写到磁盘,而不完全依赖于操作系统的异步刷盘机制。
-
自定义缓存逻辑: 应用程序可以实现自己的缓存逻辑,例如实现LRU(Least Recently Used)或其他缓存淘汰策略,以更好地满足应用程序的需求。
-
减少IO压力: 用户空间缓冲区可以允许应用程序将多个小的写操作合并为一个更大的写操作,减少了对磁盘的随机写入,提高了IO的效率。
-
提高应用程序性能: 通过使用用户空间缓冲区,应用程序可以更加主动地管理自己的数据,以适应特定的应用场景和性能需求。
虽然用户空间的缓冲区需要更多的维护和管理,但它提供了更多的灵活性和控制权,使应用程序能够更好地适应特定的性能和需求。在某些情况下,使用用户空间的缓冲区可以提供更好的性能和定制化的缓存管理策略。