C10M问题

C10M性能问题


一、引言

随着互联网的高速发展,内容量的提升以及对内容智能的需求、云产业的快速突起,作为互联网的计算基石服务器的形态以及使用成为了炙手可热的话题,全球各家大型互联网公司都持续的在服务器平台上有非常大的动作,譬如facebook的OCP等,而整个服务器的生态链也得到了促进和发展。随着服务器硬件性能的提升和网络硬件的开放,传统PC机的处理性能甚者可以和网络设备相媲美。另一方面SDN技术的发展,基础架构网络逐渐偏向基于通用计算平台或模块化计算平台的架构融合,来支持多样化的网络功能,传统的PC机器在分布式计算平台上的优势更为明显。在这些针对海量数据处理或海量用户的服务场景,高性能编程显得尤为重要。

本文讲述了从C10K到C10M过程中编程模式的改变;接着介绍了Intel DPDK开发套件如何突破操作系统限制,给开发高性能网络服务的程序员带来的福音;之后总结高性能程序设计的一些其它的优化方法;最后分享我们利用DPDK技术来实现的高性能网关设备和服务程序案例。


二、C10K到C10M

前10年中,网络程序性能优化的目标主要是为了解决C10K问题,其研究主要集中在如何管理数万个客户端并发连接,各种I/O框架下如何进行性能优化,以及操作系统参数的一些优化。

当前,解决C10K问题的服务器已经非常多。Nginx和Lighttpd两款非常优秀的基于事件驱动的web服务框架,Tornado和Django则是基于python开发的非阻塞的web框架;Yaws和Cowboy则是用Erlang开发轻量级web框架。这些软件使得C10K已经不再是问题了。

今天,C10M成为新的研究主题了。也许你会感到奇怪,千万级并发不是网络设备的性能吗?那是设备厂商该做的事情吧,答案在以前是,但如今不是。在互联网设备厂商相对封闭软件体系架构中,我们很少关注设备内部的配置。但是当你去拆开一款交换机之后就会发现,里面很可能就是我们PC机使用的x86芯片,即使不是x86,那也是标准的RISC处理器。也就是说现在的互联网硬件设备实际上很少是硬件组成——大部分都是软件来实现的。所以千万并发应该是我们软件开发人员应该去研究的问题!腾讯自研的Bobcat就是一个基于x86平台的自研设备,性能可达千万级别。


2.1异步模式的弊端

我们知道,在解决C10K问题的时候,需要将软件设计为异步模式,使用epoll来高效的处理网络读写事件。但在面对C10M问题中,这样设计是反而比较糟糕,为什么这么说呢?

一方面在基于多线程的服务器设计框架中,在没有请求到来的时候,线程将会休眠,当数据到来时,将由操作系统唤醒对应的线程,也就是说内核需要负责线程间频繁的上下文切换,我们是在依靠操作系统调度系统来服务网络包的调度。

另一方面在以Ngnix为代表的服务器场景,看上去仅使用一个线程监听Epoll事件来避免上下文切换,但我们仍将繁重的事件通知工作交由操作系统来处理。

最后要说的是,网卡驱动收包本身也是一个异步的过程,一般是当十几个或者更多的数据包到达之后通过软中断例程一次性将数据包递交到内核,而中断性能本身就不高。相比老的suse内核,tlinux系统也只不过让多队列网卡把中断分散在不同CPU核心上来提高收发包性能,要是能避免中断就更好了。

在千万级并发场景下,我们的目标是要回到最原始的方式,使用轮询方式来完成一切操作,这样才能提升性能。


2.2数据包的可扩展性

Unix诞生之初就是为电话电报控制而设计的,它的控制平面和数据转发平面没有分离,不适合处理大规模网络数据包。如果能让应用程序直接接管网络数据包处理、内存管理以及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都无法达到。


2.3多核的可扩展性

多核的可扩展性对性能提升也是非常重要的,因为服务器中CPU频率提升越来越慢,纳米级工艺改进已经是非常困难的事情了,但可以做的是让服务器拥有更多的CPU和核心,像国家超级计算中心的天河二号使用了超过3w颗Xeon E5来提高性能。在程序设计过程中,即使在多核环境下也很快会碰到瓶颈,单纯的增加了处理器个数并不能线性提升程序性能,反而会使整体性能越来越低。

  • 一是因为编写代码的质量问题,没有充分利用多核的并行性,

  • 二是服务器软件和硬件本身的一些特性成为新的瓶颈,像总线竞争、存储体公用等诸多影响性能平行扩展的因素。

那么,我们怎样才能让程序能在多个CPU核心上平行扩展:尽量让每个核维护独立数据结构;使用原子操作来避免冲突;使用无锁数据结构避免线程间相互等待;设置CPU亲缘性,将操作系统和应用进程绑定到特定的内核上,避免CPU资源竞争;在NUMA架构下尽量避免远端内存访问。当然自己来实现无锁结构时要非常小心,避免出现ABA问题和不同CPU架构下的内存模型的差异。


2.4内存的可扩展性

内存的访问速度永远也赶不上cache和cpu的频率,为了能让性能平行扩展,最好是少访问。

从内存消耗来看,如果每个用户连接占用2K的内存,10M个用户将消耗20G内存,而操作系统的三级cache连20M都达不到,这么多并发连接的情况下必然导致cache失效,从而频繁的访问内存来获取数据。而一次内存访问大约需要300 cpuclocks,这期间CPU几乎被空闲。因此减少访存次数来避免cachemisses是我们设计的目标。

指针不要随意指向任意内存地址,因为这样每一次指针的间接访问可能会导致多次cache misses,最好将需要访问的数据放到一起,方便一次性加载到cache中使用。

按照4K页来计算,32G的数据需要占用64M的页表,使得页表甚至无法放到cache中,这样每次数据访问可能需要两次访问到内存,因此建议使用2M甚至1G的大页表来解决这个问题。


2.5总结

C10M的思想就是将控制层留给Linux做,其它数据层全部由应用程序来处理。

  • 减少系统调度、系统调用、系统中断,上下文切换等

  • 摒弃Linux内核协议栈,可以使用PF_RING,Netmap,intelDPDK来自己实现驱动;

  • 使用多核编程技术替代多线程,将OS绑在指定核上运行;

  • 使用大页面,减少访问;

  • 采用无锁技术解竞争


三、Intel® DPDK技术引入

Intel® DPDK全称Intel Data Plane Development Kit,是intel提供的数据平面开发工具集,为Intel architecture(IA)处理器架构下用户空间高效的数据包处理提供库函数和驱动的支持,它不同于Linux系统以通用性设计为目的,而是专注于网络应用中数据包的高性能处理。目前已经验证可以运行在大多数Linux操作系统上,包括FreeBSD 9.2、Fedora release18、Ubuntu 12.04 LTS、RedHat Enterprise Linux 6.3和Suse EnterpriseLinux 11 SP2等。DPDK使用了BSDLicense,极大的方便了企业在其基础上来实现自己的协议栈或者应用。


需要强调的是,DPDK应用程序是运行在用户空间上利用自身提供的数据平面库来收发数据包,绕过了Linux内核协议栈对数据包处理过程。Linux内核将DPDK应用程序看作是一个普通的用户态进程,包括它的编译、连接和加载方式和普通程序没有什么两样。DPDK程序启动后只能有一个主线程,然后创建一些子线程并绑定到指定CPU核心上运行。


3.1DPDK的组成

DPDK核心组件由一系列库函数和驱动组成,为高性能数据包处理提供基础操作。内核态模块主要实现轮询模式的网卡驱动和接口,并提供PCI设备的初始化工作;用户态模块则提供大量给用户直接调用的函数。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值