千万级并发实现的秘密:内核不是解决方案,而是问题所在!
既然我们已经解决了 C10K并发连接问题,应该如何提高水平支持千万级并发连接?你可能会说不可能。不,现在系统已经在用你可能不熟悉甚至激进的方式支持千万级别的并发连接。
要知道它是如何做到的,我们首先要了解Errata Security的CEO Errata Security,以及他在Shmoocon 2013大会上的无稽之谈 C10M Defending The Internet At Scale。
Robert用一种我以前从未听说的方式来很巧妙地解释了这个问题。他首先介绍了一点有关Unix的历史,Unix的设计初衷并不是一般的服务器操作系统,而是电话网络的控制系统。由于是实际传送数据的电话网络,所以在控制层和数据层之间有明确的界限。问题是我们现在根本不应该使用Unix服务器作为数据层的一部分。正如设计只运行一个应用程序的服务器内核,肯定和设计多用户的服务器内核是不同的。
也就是他所说的关键要理解内核不是解决办法,内核是问题所在。
这意味着:
不要让内核执行所有繁重的任务。将数据包处理,内存管理,处理器调度等任务从内核转移到应用程序高效地完成。让Linux只处理控制层,数据层完全交给应用程序来处理。
最终就是要设计这样一个系统,该系统可以处理千万级别的并发连接,它在200个时钟周期内处理数据包,在14万个时钟周期内处理应用程序逻辑。由于一次主存储器访问就要花费300个时钟周期,所以这是最大限度的减少代码和缓存丢失的关键。
面向数据层的系统可以每秒处理1千万个数据包,面向控制层的系统,每秒只能处理1百万个数据包。
这似乎很极端,请记住一句老话:可扩展性是专业化的。为了做好一些事情,你不能把性能问题外包给操作系统来解决,你必须自己做。
现在,让我们学习Robert如何创建一个能够处理千万级别并发连接的系统。
C10K问题最近十年
十年前,工程师处理C10K可扩展性问题时,尽量避免服务器处理超过1万个的并发连接。通过改进操作系统内核以及用事件驱动服务器(如Nginx和Node)代替线程服务器(Apache),这个问题已经被解决。人们用十年的时间从Apache转移到可扩展服务器,在近几年,可扩展服务器的采用率增长得更快了。
Apache的问题
Apache的问题在于服务器的性能会随着连接数的增多而变差
关键点:性能和可扩展性并不是一回事。当人们谈论规模时,他们往往是在谈论性能,但是规模和性能是不同的,比如Apache。
持续几秒的短期连接,比如快速事务,如果每秒处理1000个事务,只有约1000个并发连接到服务器。
事务延长到10秒,要维持每秒1000个事务,必须打开1万个并发连接。这种情况下:尽管你不顾DoS攻击,Apache也会性能陡降;同时大量的下载操作也会使Apache崩溃。
如果每秒处理的连接从5千增加到1万,你会怎么做?比方说,你升级硬件并且提高处理器速度到原来的2倍。发生了什么?你得到两倍的性能,但你没有得到两倍的处理规模。每秒处理的连接可能只达到了6000。你继续提高速度,情况也没有改善。甚至16倍的性能时,仍然不能处理1万个并发连接。所以说性能和可扩展性是不一样的。
问题在于Apache会创建一个CGI进程,然后关闭,这个步骤并没有扩展。
为什么呢?内核使用的O(N^2)算法使服务器无法处理1万个并发连接。
内核中的两个基本问题:
连接数=线程数/进程数。当一个数据包进来,内核会遍历其所有进程以决定由哪个进程来处理这个数据包。
连接数=选择数/轮询次数(单线程)。同样的可扩展性问题,每个包都要走一遭列表上所有的socket。
解决方法:改进内核使其在常数时间内查找。
使线程切换时间与线程数量无关。
使用一个新的可扩展epoll()/IOCompletionPort常数时间去做socket查询。
因为线程调度并没有得到扩展,所以服务器大规模对socket使用epoll方法,这样就导致需要使用异步编程模式,而这些编程模式正是Nginx和Node类型服务器具有的;所以当从Apache迁移到Nginx和Node类型服务器时,即使在一个配置较低的服务器上增加连接数,性能也不会突降;所以在10K连接时,一台笔记本电脑的速度甚至超过了16核的服务器。
C10M问题未来十年
不远的将来,服务器将要处理数百万的并发连接。IPv6协议下,每个服务器的潜在连接数都是数以百万级的,所以处理规模需要升级。
如IDS / IPS这类应用程序需要支持这种规模,因为它们连接到一个服务器骨干网。其他例子:DNS根服务器,TOR节点,互联网Nmap,视频流,银行,Carrier NAT,VoIP PBX,负载均衡器,网页缓存,防火墙,电子邮件接收,垃圾邮件过滤。
通常人们将互联网规模问题归根于应用程序而不是服务器,因为他们卖的是硬件+软件。你买设备,并将其应用到你的数据中心。这些设备可能包含一块Intel主板或网络处理器以及用来加密和检测数据包的专用芯片等。
截至2013年2月,40Gpbs,32芯,256G RAM 的X86处理器在Newegg网站上的报价是5000美元。该服务器可以处理1万个以上的并发连接,如果它们不能,那是因为你选择了错误的软件,而不是底层硬件的问题。这个硬件可以很容易地扩展到1千万个并发连接。
10M的并发连接挑战意味着什么:
我们所学的是Unix而不是网络编程
很多程序员通过W. Richard Stevens所著的《Unix网络编程》学习网络编程技术。问题是,这本书是关于Unix的,而不只是网络编程。它告诉你,让Unix做所有繁重的工作,你只需要在Unix的上层写一个小服务器。但内核规模不够,解决的办法是尽可能将业务移动到内核之外,并且自己处理所有繁重的业务。
这方面有影响的一个例子是Apache每个连接线程的模型。这意味着线程调度程序根据将要到来的数据确定接下来调用哪一个read()函数,也就是把线程调度系统当作数据包调度系统来用。(我真的很喜欢这一点,从来没有想过这样的说法)。
Nginx宣称,它不把线程调度当作数据包调度程序,而是自己进行数据包调度。使用select找到socket,我们知道数据来了,就可以立即读取并处理数据,数据也不会堵塞。
经验:让Unix处理网络堆栈,但之后的业务由你来处理。
怎样编写规模较大的软件?
如何改变你的软件,使其规模化?许多只提升硬件性能去支撑项目扩展的经验都是错误的,我们需要知道性能的实际情况。
要达到到更高的水平,需要解决的问题如下:
实现数据包可扩展编写自己的个性化驱动来绕过堆栈
数据包的问题是它们需经Unix内核的处理。网络堆栈复杂缓慢,数据包最好直接到达应用程序,而非经过操作系统处理之后。
做到这一点的方法是编写自己的驱动程序。所有驱动程序将数据包直接发送到应用程序,而不是通过堆栈。你可以找到这种驱动程序:PF_RING,NETMAP,Intel DPDK(数据层开发套件)。Intel不是开源的,但有很多相关的技术支持。
速度有多快?Intel的基准是在一个相当轻量级的服务器上,每秒处理8000万个数据包(每个数据包200个时钟周期)。这也是通过用户模式。将数据包向上传递,使用用户模式,处理完毕后再返回。Linux每秒处理的数据包个数不超过百万个,将UDP数据包提高到用户模式,再次出去。客户驱动程序和Linux的性能比是80:1。
对于每秒1000万个数据包的目标,如果200个时钟周期被用来获取数据包,将留下1400个时钟周期实现类似DNS / IDS的功能。
通过PF_RING得到的是原始数据包,所以你必须做你的TCP堆栈。人们所做的是用户模式栈。Intel有现成的可扩展TCP堆栈
多核的可扩展性
多核可扩展性不同于多线程可扩展性。我们都熟知这个理念:处理器的速度并没有变快,我们只是靠增加数量来达到目的。
大多数的代码都未实现4核以上的并行。当我们添加更多内核时,下降的不仅仅是性能等级,处理速度可能也会变得越来越慢,这是软件的问题。我们希望软件的提高速度同内核的增加接近线性正相关。
多线程编程不同于多核编程
多线程
每个CPU内核中不止一个线程
用锁来协调线程(通过系统调用)
每个线程有不同的任务
多核
每个CPU内核中只有一个线程
当两个线程/内核访问同一个数据时,不能停下来互相等待
同一个任务的不同线程
要解决的问题是怎样将一个应用程序分布到多个内核中去
Unix中的锁在内核实现。4内核使用锁的情况是大多数软件开始等待其他线程解锁。因此,增加内核所获得的收益远远低于等待中的性能损耗。
我们需要这样一个架构,它更像高速公路而不是红绿灯控制的十字路口,无需等待,每个人都以自己的节奏行进,尽可能节省开销。
解决方案:
在每个核心中保存数据结构,然后聚合的对数据进行读取。
原子性。CPU支持可以通过C语言调用的指令,保证原子性,避免冲突发生。开销很大,所以不要处处使用。
无锁的数据结构。线程无需等待即可访问,在不同的架构下都是复杂的工作,请不要自己做。
线程模型,即流水线与工作线程模型。这不只是同步的问题,而是你的线程如何架构。
处理器关联。告诉操作系统优先使用前两个内核,然后设置线程运行在哪一个内核上,你也可以通过中断到达这个目的。所以,CPU由你来控制而不是Linux。
内存的可扩展性
如果你有20G的RAM,假设每次连接占用2K的内存,如果你还有20M的三级缓存,缓存中会没有数据。数据转移到主存中处理花费300个时钟周期,此时CPU没有做任何事情。
每个数据包要有1400个时钟周期(DNS / IDS的功能)和200个时钟周期(获取数据包)的开销,每个数据包我们只有4个高速缓存缺失,这是一个问题。
联合定位数据
不要通过指针在满内存乱放数据。每次你跟踪一个指针,都会是一个高速缓存缺失:[hash pointer] -> [Task Control Block] -> [Socket] -> [App],这是四个高速缓存缺失。
保持所有的数据在一个内存块:[TCB |socket| APP]。给所有块预分配内存,将高速缓存缺失从4减少到1。
分页
32GB的数据需占用64MB的分页表,不适合都存储在高速缓存。所以存在两个高速缓存缺失分页表和它所指向的数据。这是开发可扩展的软件不能忽略的细节。
解决方案:压缩数据,使用有很多内存访问的高速缓存架构,而不是二叉搜索树
NUMA架构加倍了主存访问时间。内存可能不在本地socket,而是另一个socket上。
内存池
启动时立即预先分配所有的内存
在对象,线程和socket的基础上进行分配。
超线程
每个网络处理器最多可以运行4个线程,英特尔只能运行2个。
在适当的情况下,我们还需要掩盖延时,比如内存访问中一个线程在等待另一个全速的线程。
大内存页
减小页表规模。从一开始就预留内存,让你的应用程序管理内存。
总结
网卡
问题:通过内核工作效率不高
解决方案:使用自己的驱动程序并管理它们,使适配器远离操作系统。
CPU
问题:使用传统的内核方法来协调你的应用程序是行不通的。
解决方案:Linux管理前两个CPU,你的应用程序管理其余的CPU。中断只发生在你允许的CPU上。
内存
问题:内存需要特别关注,以求高效。
解决方案:在系统启动时就分配大部分内存给你管理的大内存页
控制层交给Linux,应用程序管理数据。应用程序与内核之间没有交互,没有线程调度,没有系统调用,没有中断,什么都没有。
然而,你有的是在Linux上运行的代码,你可以正常调试,这不是某种怪异的硬件系统,需要特定的工程师。你需要定制的硬件在数据层提升性能,但是必须是在你熟悉的编程和开发环境上进行。
数据分析咨询请扫描二维码
若不方便扫码,搜微信号:CDAshujufenxi
数据分析在当今信息时代发挥着重要作用。单因素方差分析(One-Way ANOVA)是一种关键的统计方法,用于比较三个或更多独立样本组 ...
2025-04-25CDA持证人简介: 居瑜 ,CDA一级持证人国企财务经理,13年财务管理运营经验,在数据分析就业和实践经验方面有着丰富的积累和经 ...
2025-04-25在当今数字化时代,数据分析师的重要性与日俱增。但许多人在踏上这条职业道路时,往往充满疑惑: 如何成为一名数据分析师?成为 ...
2025-04-24以下的文章内容来源于刘静老师的专栏,如果您想阅读专栏《刘静:10大业务分析模型突破业务瓶颈》,点击下方链接 https://edu.cda ...
2025-04-23大咖简介: 刘凯,CDA大咖汇特邀讲师,DAMA中国分会理事,香港金管局特聘数据管理专家,拥有丰富的行业经验。本文将从数据要素 ...
2025-04-22CDA持证人简介 刘伟,美国 NAU 大学计算机信息技术硕士, CDA数据分析师三级持证人,现任职于江苏宝应农商银行数据治理岗。 学 ...
2025-04-21持证人简介:贺渲雯 ,CDA 数据分析师一级持证人,互联网行业数据分析师 今天我将为大家带来一个关于用户私域用户质量数据分析 ...
2025-04-18一、CDA持证人介绍 在数字化浪潮席卷商业领域的当下,数据分析已成为企业发展的关键驱动力。为助力大家深入了解数据分析在电商行 ...
2025-04-17CDA持证人简介:居瑜 ,CDA一级持证人,国企财务经理,13年财务管理运营经验,在数据分析实践方面积累了丰富的行业经验。 一、 ...
2025-04-16持证人简介: CDA持证人刘凌峰,CDA L1持证人,微软认证讲师(MCT)金山办公最有价值专家(KVP),工信部高级项目管理师,拥有 ...
2025-04-15持证人简介:CDA持证人黄葛英,ICF国际教练联盟认证教练,前字节跳动销售主管,拥有丰富的行业经验。在实际生活中,我们可能会 ...
2025-04-14在 Python 编程学习与实践中,Anaconda 是一款极为重要的工具。它作为一个开源的 Python 发行版本,集成了众多常用的科学计算库 ...
2025-04-14随着大数据时代的深入发展,数据运营成为企业不可或缺的岗位之一。这个职位的核心是通过收集、整理和分析数据,帮助企业做出科 ...
2025-04-11持证人简介:CDA持证人黄葛英,ICF国际教练联盟认证教练,前字节跳动销售主管,拥有丰富的行业经验。 本次分享我将以教培行业为 ...
2025-04-11近日《2025中国城市长租市场发展蓝皮书》(下称《蓝皮书》)正式发布。《蓝皮书》指出,当前我国城市住房正经历从“增量扩张”向 ...
2025-04-10在数字化时代的浪潮中,数据已经成为企业决策和运营的核心。每一位客户,每一次交易,都承载着丰富的信息和价值。 如何在海量客 ...
2025-04-09数据是数字化的基础。随着工业4.0的推进,企业生产运作过程中的在线数据变得更加丰富;而互联网、新零售等C端应用的丰富多彩,产 ...
2025-04-094月7日,美国关税政策对全球金融市场的冲击仍在肆虐,周一亚市早盘,美股股指、原油期货、加密货币、贵金属等资产齐齐重挫,市场 ...
2025-04-08背景 3月26日,科技圈迎来一则重磅消息,苹果公司宣布向浙江大学捐赠 3000 万元人民币,用于支持编程教育。 这一举措并非偶然, ...
2025-04-07在当今数据驱动的时代,数据分析能力备受青睐,数据分析能力频繁出现在岗位需求的描述中,不分岗位的任职要求中,会特意标出“熟 ...
2025-04-03