什么是零拷贝技术?

零拷贝技术,虽然平时接触到的比较少,但是确实大厂面试的热门,这里整理记录一下,虽不能完全领悟其原理,但至少要混个脸熟。

当应用程序访问数据时,操作系统首先会去检查,要访问的数据是否缓存在内核缓冲区,如果缓存了,操作系统将内核缓冲区的内容拷贝到用户空间缓冲区中去。如果不是,操作系统则首先将磁盘上的数据拷贝的操作系统的内核缓冲区,然后再把内核缓冲区上的内容拷贝到用户缓冲区中,紧接着把用户缓冲区的内容拷贝到网络堆栈相关的内核缓冲区中,最后socket再把内核缓冲区的内容发送到网卡上,这样总共有4次数据拷贝,有点懵的同学,可以看下图,就能非常直观的看拷贝过程

t5Cx56.jpg

如果传输数据库很大,会占用大量的cpu资源。那有没有办法减少数据拷贝呢,有,零拷贝技术就是来解决这个性能问题的。

在谈零拷贝技术之前,必须得先说说DMA(Direct Memory Access),直接内存访问,DMA是允许外设组件将I/O数据直接传送到主存储器中并且传输不需要CPU的参与,来释放CPU时间分片资源。

在linux系统中,用户空间与内核空间之间的数据传输是没有类似DMA这种可以不需要CPU参与的传输工具,所以用户空间与内核空间之间的数据传输是需要CPU全程参与。所有需要通过零拷贝技术来减少和避免不必要的CPU数据拷贝过程。

在上图中,第一步通过DMA技术将磁盘文件中的内容拷贝到内核空间缓冲区中,因为使用了DMA技术,此过程中是不需要CPU参与的。

第二步,将内核缓冲区的数据拷贝到用户空间缓冲区,这一步,全程需要CPU参与的,那这一步能不能优化呢,不拷贝数据呢,可以的,如果让用户空间和内核空间共享数据,就可以达到这个优化目的,为此linux引入了mmap技术,mmap可以实现用户空间和内核空间数据共享,而避免减少一次内核空间到用户空间数据拷贝动作,在数据量很大的时候,效率提升尤其明显。其效果如下图所示

t5CvUx.jpg

但是在图二中,还是有cpu copy动作,就是将内核缓冲区数据拷贝到内核socket缓冲区,那这一步能否优化呢,在Linux 2.4版本开始,操作系统底层提供了scatter/gather这种DMA的方式来从内核空间缓冲区中将数据直接读取到协议引擎中,而无需将内核空间缓冲区中的数据再拷贝一份到内核空间socket相关联的缓冲区中。

通过mmap,scatter/gather实现了数据零拷贝全过程,全程无需CPU参与。

Go Modules和GOPROXY简介

随着Go 1.13发布,GOPROXY默认值proxy.golang.org在中国大陆不能被访问。
七牛云顺势推出goproxy.cn,以利于中国开发者更好使用Go Modules,它是非盈利性的项目,首先感谢七牛云。
Windows下使用教程:

Vim使用技巧记录

命令行

在正常模式下键入 : 进入命令行模式。 在键入 : 后,你的光标会立即跳到屏幕下方的命令行。 这个模式有很多功能,包括打开,保存,关闭文件,以及 退出 Vim。

Go语言基础数据类型所占内存大小

基础知识

  • bit(位):计算机中数据的最小单位,二进制数中的一个数位,0或者1
  • Byte(字节):计算机中数据的基本单位,每8位(bit)组成一个字节

golang

类型 大小
int8 1字节
int16 2字节
int32 4字节
int64 8字节
int 4字节(32位)/8字节(64位)
float32 4字节
float64 8字节
string 1字节(英文)/2~4字节(中文,取决于字符编码类型)
bool 1字节