您好,欢迎来电子发烧友网! ,新用户?[免费注册]

您的位置:电子发烧友网>源码下载>DSP编程>

C10K到C10M高性能网络的实践分析

大小:0.6 MB 人气: 2017-10-12 需要积分:1
 C10K时代的问题与优化手段
  首先带大家回顾一下当年C10K场景中遇到的问题以及为了解决我们单机下高并发的承载能力所做的改进。在当时的年代,国内互联网的普及程度相对较低,C10K并没有给当时中国的互联网环境带来太大冲击,但是在全球互联网环境下大家开始意识到这个问题。为了解决该问题,首先的研究方向就是IO模型的优化,逐渐解决了C10K的问题。
  epoll、kqueue、iocp就是IO模型优化的一些最佳实践,这几种技术实现分别对应于不同的系统平台。以epoll为例,在它的基础上抽象了一些开发框架和库,为广大软件开发者在软件开发带来了便利,比如libevent、libev等。随着当年在IO模型上的革命,衍生出了很多至今为止我们都在大量使用的优秀开源软件,比如nginx、haproxy、squid等,通过大量的创新、实践和优化,使我们在今天能够很轻易地解决一个大并发压力场景下的技术问题。
  这里简单列了几点,较为常用的优化技术手段。
  CPU亲和性&内存局域性
  目前我们使用的服务器主要是多路、多核心的x86平台。用于运行我们的软件代码,在很多场景的业务需求下,都会涉及一定并发任务,无论是多进程模型还是多线程模型,都要把所有的调度任务交给操作系统,让操作系统帮我们分配硬件资源。我们常用的服务器操作系统都属于分时操作系统,调度模型都尽可能的追求公平,并没有为某一类任务做特别的优化,如果当前系统仅仅运行某一特定任务的时候,默认的调度策略可能会导致一定程度上的性能损失。我运行一个A任务,第一个调度周期在0号核心上运行,第二个调度周期可能就跑到1号核心上去了,这样频繁的调度可能会造成大量的上下文切换,从而影响到一定的性能。
  数据局域性是同样类似的问题。当前x86服务器以NUMA架构为主,这种平台架构下,每个CPU有属于自己的内存,如果当前CPU需要的数据需要到另外一颗CPU管理的内存获取,必然增加一些延时。所以我们尽可能的尝试让我们的任务和数据在始终在相同的CPU核心和相同的内存节点上,Linux提供了sched_set_affinity函数,我们可以在代码中,将我们的任务绑定在指定的CPU核心上。一些Linux发行版也在用户态中提供了numactl和taskset工具,通过它们也很容易让我们的程序运行在指定的节点上。
  RSS、RPS、RFS、XPS
  这些技术都是近些年来为了优化Linux网络方面的性能而添加的特性,RPS、RFS、XPS都是Google贡献给社区,RSS需要硬件的支持,目前主流的网卡都已支持,即俗称的多队列网卡,充分利用多个CPU核心,让数据处理的压力分布到多个CPU核心上去。RPS和RFS在linux2.6.35的版本被加入,一般是成对使用的,在不支持RSS特性的网卡上,用软件来模拟类似的功能,并且将相同的数据流绑定到指定的核心上,尽可能提升网络方面处理的性能。XPS特性在linux2.6.38的版本中被加入,主要针对多队列网卡在发送数据时的优化,当你发送数据包时,可以根据CPU MAP来选择对应的网卡队列,低于指定的kernel版本可能无法使用相关的特性,但是发行版已经backport这些特性。
  IRQ 优化
  关于IRQ的优化,这里主要有两点,第一点是关于中断合并。在比较早期的时候,网卡每收到一个数据包就会触发一个中断,如果小包的数据量特别大的时候,中断被触发的数量也变的十分可怕。大部分的计算资源都被用于处理中断,导致性能下降。后来引入了NAPI和Newernewer NAPI特性,在系统较为繁忙的时候,一次中断触发后,接下来用轮循的方式读取后续的数据包,以降低中断产生的数量,进而也提升了处理的效率。第二点是IRQ亲和性,和我们前面提到了CPU亲和性较为类似,是将不同的网卡队列中断处理绑定到指定的CPU核心上去,适用于拥有RSS特性的网卡。
  这里再说说关于网络卸载的优化,目前主要有TSO、GSO、LRO、GRO这几个特性,先说说TSO,以太网MTU一般为1500,减掉TCP/IP的包头,TCP的MaxSegment Size为1460,通常情况下协议栈会对超过1460的TCP Payload进行分段,保证最后生成的IP包不超过MTU的大小,对于支持TSO/GSO的网卡来说,协议栈就不再需要这样了,可以将更大的TCPPayload发送给网卡驱动,然后由网卡进行封包操作。通过这个手段,将需要在CPU上的计算offload到网卡上,进一步提升整体的性能。GSO为TSO的升级版,不在局限于TCP协议。LRO和TSO的工作路径正好相反,在频繁收到小包时,每次一个小包都要向协议栈传递,对多个TCPPayload包进行合并,然后再传递给协议栈,以此来提升协议栈处理的效率。GRO为LRO的升级版本,解决了LRO存在的一些问题。这些特性都是在一定的场景下才可以发挥其性能效率,在不明确自己的需求的时候,开启这些特性反而可能造成性能下降。
  Kernel 优化
  关于Kernel的网络相关优化我们就不过多的介绍了,主要的内核网络参数的调整在以下两处:net.ipv4.参数和net.core.参数。主要用于调节一些超时控制及缓存等,通过搜索引擎我们能很容易找到关于这些参数调优的文章,但是修改这些参数是否能带来性能的提升,或者会有什么弊端,建议详细的阅读kernel文档,并且多做一些测试来验证。
  更深入的探索和实践
  接下来,我们着重了解如何去更进一步提升我们单机网络吞吐以及网络处理性能的技术和手段。
  计算机硬件做为当前IT发展的重要组成部分。作为软件开发者,我们更应该掌握这部分的内容,学习了解我们的软件如何在操作系统中运行,操作系统又怎样分配我们的硬件资源。
  硬件
  CPU
  CPU是计算机系统中最核心、最关键的部件。在当前的x86服务器领域我们接触到主要还是Intel芯片。索性我们就以IntelXeon 2600系列举例。
  Intel Xeon 2600系列的CPU已经发布了3代,第4代产品2016年Q1也即将面市,图例中均选取了4代产品最高端的型号。图一为该系列CPU的核心数量统计,从第一代的8核心发展到即将上市的22核心,若干年前,这是很可怕的事情。装配该型号CPU的双路服务器,再开启超线程,轻而易举达到80多个核心。就多核处理器的发展历程来讲,核心数量逐年提升,主频基本稳定在一定的范围内,不是说单核主频不再重要,而是说在当前的需求场景下,多核心才是更符合我们需求的处理器。
  C10K到C10M高性能网络的实践分析
  图1
  不仅仅是核心数量,像LLC缓存的容量、内存带宽都有很大的提升,分别达到了55MB和76.8GB/s。

非常好我支持^.^

(0) 0%

不好我反对

(0) 0%

      发表评论

      用户评论
      评价:好评中评差评

      发表评论,获取积分! 请遵守相关规定!