zoukankan      html  css  js  c++  java
  • [DPDK] 转发 DPDK分析

    前半部分,对于背景和需求的分析,写的相当好啊!

    原文地址:https://www.jianshu.com/p/0ff8cb4deaef

    背景分析

    前10年中,网络程序性能优化的目标主要是为了解决C10K问题,其研究主要集中在如何管理数万个客户端并发连接,各种I/O框架下如何进行性能优化,以及操作系统参数的一些优化。当前,解决C10K问题的服务器已经非常多。Nginx和Lighttpd两款非常优秀的基于事件驱动的web服务框架,Tornado和Django则是基于python开发的非阻塞的web框架这些软件使得C10K已经不再是问题了。

    • 从整体上看
      为了满足日益增长的需求主要采用分布式集群来分担负荷,应对大量的用户请求.
     
    集群
    • 从结构上来看一个节点的服务器框架包含

    • 网络模块

    • 事件驱动模块

    • 隔离,多核业务分发模块

    • 业务层

    • 在单个节点上,核的使用来看,主要包括

    • 单线程服务器
      优点是无竞争,缺点是没有充分利用系统资源

    • 多进程模型
      隔离性好,利用了系统更多的资源,缺点是进程间资源共享难

    • 多线程模型
      充分利用系用资源,竞争需要小心处理

    需求分析

    综合分析

    • 在应对网络密集型的巨大数据量时,一般选择是横向扩展节点,但是节点的增多会变相的增加设备成本和技术风险,且当集群节点到一定的量后,节点之间的交互成本本身就会成为瓶颈。
    • 在特定场合下,譬如嵌入式设备上的后台服务,服务器不可能搭建集群。

    因此提升服务器本身性能同样重要。

    具体分析

    传统服务器可能有下面的潜在问题

    • 异步模式的弊端
      一般我们使用epoll来高效的处理网络读写事件。在基于多线程的服务器设计框架中,在没有请求到来的时候,线程将会休眠,当数据到来时,将由操作系统唤醒对应的线程,也就是说内核需要负责线程间频繁的上下文切换,我们是在依靠操作系统调度系统来服务网络包的调度。在网络负载很大的场景下只会造成核满转且不断相互切换,进一步增加负荷.那么就需要回到最原始的方式,使用轮询方式来完成一切操作,来提升性能。

    • 协议栈的扩展性
      Linix诞生之初就是为电话电报控制而设计的,它的控制平面和数据转发平面没有分离,不适合处理大规模网络数据包。并且为了全面的支持用户空间的各个功能,协议栈中嵌入了大量用于对接的接口,如果能让应用程序直接接管网络数据包处理、内存管理以及CPU调度,那么性能可以得到一个质的提升。为了达到这个目标,第一个要解决的问题就是绕过Linux内核协议栈,因为Linux内核协议栈性能并不是很优秀,如果让每一个数据包都经过Linux协议栈来处理,那将会非常的慢。像Wind River和6 Wind Gate等公司自研的内核协议栈宣称比Linux UDP/TCP协议栈性能至少提高500%以上,因此能不用Linux协议栈就不用。
      不用协议栈的话当然就需要自己写驱动了,应用程序直接使用驱动的接口来收发报文。PF_RING,Netmap和intelDPDK等可以帮助你完成这些工作,并不需要我们自己去花费太多时间。
      Intel官方测试文档给出了一个性能测试数据,在1S Sandbridge-EP 8*2.0GHz cores服务器上进行性能测试,不用内核协议栈在用户态下吞吐量可高达80Mpps(每个包处理消耗大约200 cpu clocks),相比之下,使用Linux内核协议栈性能连1Mpps都无法达到。

    • 多核的可扩展性
      多核的可扩展性对性能提升也是非常重要的,因为服务器中CPU频率提升越来越慢,纳米级工艺改进已经是非常困难的事情了,但可以做的是让服务器拥有更多的CPU和核心,像国家超级计算中心的天河二号使用了超过3w颗Xeon E5来提高性能。在程序设计过程中,即使在多核环境下也很快会碰到瓶颈,单纯的增加了处理器个数并不能线性提升程序性能,反而会使整体性能越来越低。一是因为编写代码的质量问题,没有充分利用多核的并行性,二是服务器软件和硬件本身的一些特性成为新的瓶颈,像总线竞争、存储体公用等诸多影响性能平行扩展的因素。那么,我们怎样才能让程序能在多个CPU核心上平行扩展:尽量让每个核维护独立数据结构;使用原子操作来避免冲突;使用无锁数据结构避免线程间相互等待;设置CPU亲缘性,将操作系统和应用进程绑定到特定的内核上,避免CPU资源竞争;在NUMA架构下尽量避免远端内存访问

    • 内存的可扩展性
      内存的访问速度永远也赶不上cache和cpu的频率,为了能让性能平行扩展,最好是少访问。
      从内存消耗来看,如果每个用户连接占用2K的内存,10M个用户将消耗20G内存,而操作系统的三级cache连20M都达不到,这么多并发连接的情况下必然导致cache失效,从而频繁的访问内存来获取数据。而一次内存访问大约需要300 cpuclocks,这期间CPU几乎被空闲。因此减少访存次数来避免cachemisses是我们设计的目标。
      指针不要随意指向任意内存地址,因为这样每一次指针的间接访问可能会导致多次cache misses,最好将需要访问的数据放到一起,方便一次性加载到cache中使用。
      按照4K页来计算,32G的数据需要占用64M的页表,使得页表甚至无法放到cache中,这样每次数据访问可能需要两次访问到内存,因此建议使用2M甚至1G的大页表来解决这个问题。

    解决方案

    • 控制层留给Linux做,其它数据层全部由应用程序来处理。
      减少系统调度、系统调用、系统中断,上下文切换等
    • 摒弃Linux内核协议栈,将数据包传输到用户空间定制协议栈
    • 使用多核编程技术替代多线程,将OS绑在指定核上运行
    • 针对SMP系统,使CPU尽量使用所在NUMA系统节点的内存,减少内存刷写
    • 使用大页面,减少访问
    • 采用无锁技术解竞争

    而DPDK恰好为我们提供了解决问题的脚手架。

  • 相关阅读:
    vue nextTick使用
    Vue slot插槽内容分发
    vue 项目设置实现通过本地手机访问
    vue router mode模式在webpack 打包上线问题
    html设置 hight100%问题
    更新模块通知栏显看不到当前进度,以及更新下载中可以清理通知问题,华为强制更新退出软件后台下载不显示通知问题
    ScrollView下嵌套GridView或ListView默认不在顶部的解决方法
    文件说明注释
    EditText双光标问题
    原 android重启应用(应用重新启动自身)
  • 原文地址:https://www.cnblogs.com/hugetong/p/8328101.html
Copyright © 2011-2022 走看看