category
type
status
date
slug
summary
tags
password
Property
Apr 3, 2023 12:23 PM
icon
February 21
March 3
March 4
  • 零拷贝技术(适用于小文件传输):
    • note:
      • 真正的零拷贝技术:两次上下文切换和两次数据拷贝
      SG-DMA:必须是网卡支持The Scatter-Gather Direct Memory Access技术才可使用。
      SG-DMA:必须是网卡支持The Scatter-Gather Direct Memory Access技术才可使用。
      • 没有SG-DMA的文件传输技术(两次上下文切换和三次数据拷贝):
      notion image
      • DMA拷贝技术:用户进程调用read系统调用后,CPU发出IO请求到DMA中,DMA再发生IO请求到磁盘中,磁盘将数据读取读取到磁盘缓冲区中,读取完毕后通知DMA控制器,DMA控制器将数据从磁盘缓冲区读取到内核缓冲区,读取完毕后通知CPU将内核缓冲区中的数据拷贝到用户缓冲区中。最后read系统调用返回:
        • notion image
      • 传统的文件传输存在四次用户态和内核态之间的上下文交换(因为发生了reade和write两次系统调用)以及四次数据拷贝:
        • notion image
      • 采用mmap+write优化后: 由于mmap系统调用会直接把内核缓冲区的数据映射到用户空间,以避免操作系统内核和用户空间之间的数据拷贝。但是仍然存在4次上下文切换,但是数据拷贝次数变为3次
        • notion image
      大文件传输:
      • 内核缓冲区主要是指:PageCache,其主要优点是缓存最近被访问的数据和预读功能。
      • 在传输大文件时使用PageCache会存在以下问题:
        • PageCahe由于长时间被大文件占据,其他【热点】小文件就无法充分使用到PageCache于是导致磁盘的读写性能下降
        • PageCache中的大文件数据,由于没有享受到缓存带来的好处,白白浪费了DMA多拷贝到PageCache一次。
      • 在高并发场景下,针对大文件的传输,应该采用异步I/O+直接I/O来代替零拷贝技术:
        • notion image
      • 实用例子:
        • 在 nginx 中,我们可以用如下配置,来根据文件的大小来使用不同的方式:
          当文件大小大于 directio 值后,使用「异步 I/O + 直接 I/O」,否则使用「零拷贝技术」
  • Redis大Key对持久化的影响
    • note:
      • AOF写回策略中配置Always策略,马上调用fsync()函数将数据写入磁盘,如果此时是大key则写入时间会比较长,从而造成redis主线程的阻塞。 而Everysec策略是会创建一个异步的任务来执行fsync()函数,所以大key持久化过程不会影响redis主线程。 而No策略永不会执行fsync()函数,由操作系统确定写入磁盘时机,所以大key的持久化也不会影响redis主线程。
        • notion image
      • 在RDB策略下,随着越来越多的大key存在,redis占用的内存会越来越大,对应的页表就会越大。在通过fork()创建子进程时复制页表就会很耗时,从而影响redis的主线程。 修改大key时,会触发写时复制,会把对应物理内存复制一份,由于大key占用的物理内存比较大,所以在复制物理内存这一过程中会很耗时,从而影响redis的主线程。
      • Linux开启内存大页是会影响redis性能的,内存大页支持2M大小的内存页分配,而常规的内存页分配是按照4KB的粒度来进行的。 如果开启内存大页,在RDB过程中如果客户端只请求修改100B的数据,在发生写时复制后,redis也要拷贝2M的大页,每次写时复制引起的复制内存单位放大了512倍,拖慢了写操作的执行时间,使redis的性能大打折扣。 关闭内存大页的方法:
    March 7
    March 27
    April 2
    • Twikoo
    • Giscus