高性能服务器技术简介

从C10K问题到C10M问题

C10K问题是指单台服务器如何支持10K个并发连接。因为早期的网络服务器一般采用阻塞式I/O模型,使用多进程或多线程的方式来实现大量网络请求的并发处理,对系统资源的消耗较高,所以普通服务器难以支持大量并发连接。对此的解决方案是使用kqueue/epoll等I/O复用模型或IOCP/aio等异步I/O模型,在单个线程中处理多个并发请求,降低对资源的消耗,提高系统性能。典型的基于epoll的服务器有nginx、memcache、redis等。

随着半导体技术的发展,硬件设备和接口的速度有了极大的提高,可以承担更高的负载。另一方面,互联网应用越来越普及,服务器也需要处理更大量的数据,因此有了C10M问题,也就是如何让单台服务器支持千万级别的并发连接。

性能瓶颈

系统中断

操作系统一般使用中断方式来访问I/O设备,linux每收到一个报文,会触发一次硬件中断请求。由于中断处理函数需要消耗一定的CPU时间,服务器每秒钟能处理中断请求次数是有限的。一般服务器每秒钟大概能处理100K次中断请求,所以能接受和处理的报文数也难以超过这个范围。系统中断的开销是C10M问题的最主要影响因素。

这种方式对传统的慢速设备来说是比较匹配的,但访问高速设备时中断调用的成本就会变得很高,使得硬件设备的性能不能充分发挥。

系统调用和内核态的切换

现代操作系统一般都会区分用户态和内核态,应用程序需要使用一种特殊的中断指令从用户态进入内核态,以访问网络、硬盘等I/O设备。这个状态切换也是一种耗时操作,每次接收或发送报文都需要对应的一次系统调用和一次到多次的上下文切换,这也限制了服务器的性能。

内存拷贝

由于有用户态和内核态的隔离,在两者之间传递数据时需要进行内存拷贝,存在一定的开销。在高频的报文传输和处理过程中,这个开销也会变大,需要进行优化,尽量避免内存拷贝。

多核

随着CPU的单核性能逐渐接近瓶颈,服务器的整体性能越来依赖于多核和并行方面的优化。

早期linux的同步粒度很粗,例如使用一个全局的大内核锁(BKL-Big Kernel Lock),多核的并发性能很受影响,所以后来就逐步细化锁的粒度,对不同的数据用不同的锁,以提高系统的并发能力。

还有CPU的亲和性和NUMA内存架构等问题,对。linux内核中的各种数据结构,也由全局范围定义变成每个CPU核心定义一份。例如各种进程调度算法中,准备就绪队列都是每个CPU一个。

其它因素

还有内存分页大小、各种锁的使用等方面的因素。

解决方案

高速I/O场景下,最主要的瓶颈就是系统中断和系统调用、内核态切换等因素。这些都是操作系统相关的因素,所以说,对于C10M问题,操作系统不是解决方案,而是问题所在。

对于系统中断导致的的性能问题,可以通过轮询方式来解决。在低速I/O场景下,轮询会浪费CPU,中断方式更加高效。但在I/O非常频繁的时候,中断更慢,成本也更高,轮询反而更加快速高效。所以可以在I/O频繁的时候先采用轮询方式,如果轮询时没有结果,再切换到中断模式,这样既能实现高效的收发大量报文,又能在低速场景下降低CPU的负载。

至于系统调用和内核态切换方面的问题,一般有两种方法解决,一种是尽可能把操作放在内核中,像NFS/LVS等服务器,为了追求高性能,就采用了这种方案。不过内核代码开发和调试的难度更高,出错后影响更大,对一般的应用和服务器开发不太适合。另一种是采取内核旁路(Kernel Bypass)的方法,尽可能把操作移到用户空间中,绕开操作系统的屏障,高效的实现数据传输。

下面列举的几种新技术,从不同的角度提出了各自的解决方案。

DPDK(Data Plane Development Kit)

DPDK是Intel等公司开发的用于网络报文相关的开发工具包,可以在用户空间高效进行报文处理。以前主要是用于交换机、路由器、网关等应用场景,现在也用于更上层的应用。

DPDK的主要原理是通过Linux的UIO(Userspace I/O)技术,将网卡设备的访问和控制由内核外包给应用程序来实施。同时利用Linux的PM

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值