# 推出DPDK开发包的意义

> 来源：梦飞idc云平台 | 原文：https://www.mfisp.com/9321.html | 发布：2022-08-23 | 更新：2022-08-23 | 分类：投稿分享、服务器vps推荐

意义是：**返璞归真**，我们只是在重复着历史的循环。提高IO效率的根本方向只有2个：（1）**让内核足够小；**（2）**让内核足够大**。

 

大背景：随着网络的发展，IO密集型业务的增长，操作系统的内核逐渐从“好用的工具”变成“碍事的管家”，于是行业开始思考独立于内核之外实现更高效率的IO。

 

*以下为方便理解的比喻、简化模型，不是严谨的说明。*

 

思考两个问题：

 
 
1. 如果没有操作系统，如何写一个超简单的Request-Response服务？ 
1. 如果DPDK平台上要跑多个第三方应用，如何公平运行这些应用？如何防止“不靠谱”的恶意应用搞破坏？ 

 

我们先只考虑1，如果没有操作系统的话，我们会怎么写服务器。

 

**STEP 1**：时光退回50年前，假设我们有台单核服务器，上面只跑1个服务，这个服务非常轻量、通信量充分小、计算负载充分低，而且不存在信任与安全的问题。

 

最简单的做法是，当网卡收到请求抛出硬件中断时，CPU（假设DMA还没有发明出来）将网卡缓冲区的IP包数据读出，解析请求，执行请求，再将响应数据写入网卡缓冲区，发送。

 

**STEP 2**：业务开始变复杂，CPU处理请求的时间已经不能忽略不计了，但是硬件中断必须马上响应完，否则有可能丢失请求。

 

为了解决这个问题，我们先写了一个基础框架：让CPU可以交替执行2个程序A和B，如果网卡有数据请求过来，就保存CPU现场立即强制切换到执行A。

 

程序A的功能是：收数据包但不立即处理请求，而是把收到的数据缓存到内存

 

程序B的功能是：从内存里取出缓存的数据包，执行处理请求

 

只要我们的基础框架和程序A的性能不拉跨，基本不用担心丢失请求了。

 

现在开始考虑问题2。

 

**STEP 3**：业务更复杂了，我们需要在这台服务器上跑3个程序A、B、C。A还是上面那个框架，B是我们自研的应用，C是外包给外包商开发的程序，而且这个开发商好像还有点不太靠谱。

 

为了解决这个问题，我们先把内存分成两半，一半只允许程序A使用，另一半再劈两半，分别允许B和C使用。然后再改造一下CPU，让程序B和C只能访问各自段的段内内存，如果想跨段访问，必须调用程序A的接口进行申请，由A来代理访问。

 

由于开发程序B的外包商不太靠谱，我们还要防止程序B“偷听”本来要发给A的请求。于是，我们给IP消息编个号加到头部，发给B的消息是1号，发给C的消息是2号，再规定所有消息只能由程序A接收。程序B和C向程序A申请提取消息时，程序A会核对编号；程序B和C定时向程序A询问是否有发给自己的消息，如果有，就把消息从程序A复制到自己的内存，然后再处理执行。我们管这种带编号的消息起名叫UDP报文。

 

**STEP 4**：通信量越来越大，程序A光从网卡取数据就能把CPU累死，于是我们又制造了一个硬件DMA，协助CPU做枯燥无味的拷贝工作。

 

**STEP 5**：通信量又大了。消息从程序A拷贝到程序B和C的开销已经大到不可忽视。程序B和C都觉得程序A“太碍事了”“管得太宽，手伸得太长”，抗议A“滥权”的呼声越来越高。于是程序A改造了一下，决定“放权”。程序A允许B向A申请一段共享内存，程序A把消息往共享内存里转圈写入，B就可以不从A拷贝数据直接看到内容了；同理，B想发什么数据，直接往共享内存里写入，程序A会转圈处理程序B写入的消息。发明这个机制的人姓U，所以人们把这种机制命名为“uring”。

 

**STEP 6**：通信量更大了，而且还更频繁。而且人们发现，程序A、B、C之间互相通信的开销也非常大。于是程序B和C合计了一下，“A还是太碍事了，咱们把A踢了单干如何？走，去问问网卡同不同意！”

---
本页由 梦飞idc云平台（https://www.mfisp.com）提供。站点导航见 https://www.mfisp.com/llms.txt
