概述
用户态协议栈
每一个客户端给服务器发送数据时,都会先经过服务器的网卡,通过网卡解析之后,然后网卡有一块数据,能够把解析后的数据存储起来。
接着,再把网卡存储的数据拷贝到内核协议栈,
最后,再从内核协议栈拷贝到应用程序。
从上可以得知,每种服务器接收来自客户端,都会经过两次拷贝。
Q:动动我们的小脑瓜子,想想有没有什么方法,能够减少这些数据的拷贝呢?有没有能够实现零拷贝的方式。
A:要解决拷贝的问题,要想个方法,把内核的协议栈做到应用程序上面,跟应用程序结合到一起。内核协议栈不接收数据,网卡的数据直接到应用程序上面。这样才能实现零拷贝的方式。
使用netmap可以做到。它的底层使用mmap,把网卡存储解析后数据的区域 映射到 应用程序中。 netmap 就是这么实现的。
值得一提的,如PF_RING, libcap, 这些抓包工具,它抓取的是原生的socket (raw_socket), 也就是从 以太网 里面 抓的最原始的数据。 这并不代表着,这就是网卡解析后的数据,所以不适合 用来实现 零拷贝。
和netmap功能类似,还有一个叫DPDK的开源框架。它在纯软件层面上,解决了网卡数据映射的问题。它比netmap更适合在实际的开发中使用。因为DPDK 这个开源框架。它有专业的商业团队的维护,而且有内存管理,也就是能对,网卡内存的管理。当客户端发送的数据特别多的时候,比如传输给网卡的数据有大几G时,使用DPDK,内存管理的问题就更容易解决。
C10K时什么?
C10K 就是 一万并发量的意思。
在没有epoll的情况下,要实现C10K, 能有哪些解决方案呢?
1、poll/select
2、多线程、多进程
理论上select 只能接收1024个客户端连接。而且需要频繁的把所有的fd集合拷贝到内核中。
连接数量少。而多进程、多线程占用内存大,而且不能创建太多。
epoll为什么选择红黑树作为底层实现?
hash/数组 空间扩展很麻烦。要么扩展大。要么不够
B+树 范围索引的
B树 查找、添加、删除比较复杂,比红黑树
B树还有存储空间的浪费, 而且增删改查 速度 不如红黑树
linux2.6之后,引入了epoll。
epoll解决了linux 早期设计的缺陷,是一个patch.
epoll不仅增加了并发量,而且还可以对单个socket的事件进行处理,如epoll_ctl()。这些都是select做不到的。
C10M
C10M 意味着什么?
千万并发量
单机的服务器能否做到C10M呢?
我们可以从六个方向来分析一下。
内存、CPU、磁盘、网卡(提升带宽),应用程序能解决的, 操作系统
内存
假设一个链接,有4K的sendbuffer, 4k的recvbuffer。 总共有8k的数据左右。
那么1千万的连接,那么就至少需要有80G的内存
CPU
单核每秒能够处理50K的数据。
那么1千万的连接,那么需要200核的CPU。
用户态协议栈
上面是硬件层面上需要的,而我们在程序能够解决的是。 使用用户态协议栈,让数据绕开内核,直接到应用程序上面来。这样就能够减少数据从网卡到应用的两次拷贝的开销。
用户态协议栈来代替 之前的内核的协议栈。
网卡存储的数据,可以通过netmap来抓取出来。它的底层原理,使用mmap来实现的。
netmap、NIC、物理网卡的关系
NIC network interface card 网络的接口卡
网卡 物理的网卡
eth0 网络适配器 它对应了一块网卡
NIC是linux下的一个子系统, NIC是一个类,eth0 是一个对象。
NIC子系统 是对 网卡抽象 出来的 一层封装。
netmap 是在NIC子系统里面, 对这个模块,增加一些功能,比如mmap. 在NIC里面,实现了mmap.
netmap分为两块:
1、内核模块 实现了NIC的子系统,加了mmap的功能
2、应用接口模块
最后
以上就是傲娇便当为你收集整理的用户态协议栈基础知识用户态协议栈C10Mnetmap、NIC、物理网卡的关系的全部内容,希望文章能够帮你解决用户态协议栈基础知识用户态协议栈C10Mnetmap、NIC、物理网卡的关系所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复