惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

月光博客
月光博客
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
N
Netflix TechBlog - Medium
大猫的无限游戏
大猫的无限游戏
爱范儿
爱范儿
Martin Fowler
Martin Fowler
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
The Register - Security
The Register - Security
IT之家
IT之家
博客园_首页
Microsoft Security Blog
Microsoft Security Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 三生石上(FineUI控件)
I
InfoQ
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Jina AI
Jina AI
Apple Machine Learning Research
Apple Machine Learning Research
M
MIT News - Artificial intelligence
博客园 - Franky
C
Check Point Blog
T
The Blog of Author Tim Ferriss
V
Visual Studio Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
T
Tailwind CSS Blog
Recent Announcements
Recent Announcements
云风的 BLOG
云风的 BLOG
美团技术团队
The Cloudflare Blog
Y
Y Combinator Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
MyScale Blog
MyScale Blog
The GitHub Blog
The GitHub Blog
D
DataBreaches.Net
Google DeepMind News
Google DeepMind News
V
V2EX
aimingoo的专栏
aimingoo的专栏
GbyAI
GbyAI
G
Google Developers Blog
S
SegmentFault 最新的问题
Hugging Face - Blog
Hugging Face - Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
U
Unit 42
罗磊的独立博客
量子位
MongoDB | Blog
MongoDB | Blog
Last Week in AI
Last Week in AI
Stack Overflow Blog
Stack Overflow Blog
小众软件
小众软件
D
Docker
人人都是产品经理
人人都是产品经理

任霏博客

我将关闭服务器:AI彻底掐死了奄奄一息的个人博客 - 博客文章 - 任霏的个人博客网站 Vibe Coding 实现本地模型 Token 自由 IntelliJ IDEA + LM Studio + LM Link + Continue - 博客文章 - 任霏的个人博客网站 1Password涨价后,别急着退订1Password,这个操作能帮你省25% - 博客文章 - 任霏的个人博客网站 我,吃饱了撑的注册了个域名,Cloudflare账号没了,不建议将域名放在Cloudflare - 博客文章 - 任霏的个人博客网站 临时邮箱:保护隐私与免骚扰的新方式 - 博客文章 - 任霏的个人博客网站 价值4100万美元SOL被盗SwissBorg在Solana上遭遇安全事件超200万枚ETH排队退出质押 - 博客文章 - 任霏的个人博客网站 注意 Web3 钱包遭遇 NPM 超大规模供应链攻击投毒事件 - 博客文章 - 任霏的个人博客网站 我受到以太坊ERC-20假代币地址投毒攻击记录一下大家谨防上当受骗 - 博客文章 - 任霏的个人博客网站 在2025年使用显卡 NVIDIA RTX 2080 Ti 挖矿收益记录和分析还能不能挖矿 - 博客文章 - 任霏的个人博客网站 分享我是如何成功戒烟的经验(包含失败的经验) - 博客文章 - 任霏的个人博客网站 在 OpenWRT 中配置 PassWall2 插件的教程记录 - 博客文章 - 任霏的个人博客网站 Office Professional Plus 2019 VL 版下载与 KMS 激活 - 博客文章 - 任霏的个人博客网站 最近几天我的 CDN 流量受到来自电信[山东烟台]、[江苏扬州]两地家庭宽带的攻击 - 博客文章 - 任霏的个人博客网站 自建AI服务器使用PVE配置显卡直通虚拟机安装驱动、CUDA和cuDNN运行LLM大模型进行AI炼丹 - 博客文章 - 任霏的个人博客网站 各代英特尔Intel芯片组主板适配兼容的CPU和DDR内存数据统计 - 博客文章 - 任霏的个人博客网站 GitLab Global 国际站将在60天内删除中国大陆、香港、澳门地区的账号 - 博客文章 - 任霏的个人博客网站 Github Copilot Free 开放免费版所有人均可使用 OpenAI GPT-4o、Anthropic Claude 3.5 AI 代码生成服务 - 博客文章 - 任霏的个人博客网站 Cloudflare 更新了订阅协议明确禁止优选IP和搭建梯子的行为 - 博客文章 - 任霏的个人博客网站 Linux(systemd)手动离线安装二进制(binary)MairaDB数据库指定版本 - 博客文章 - 任霏的个人博客网站 流程引擎 Flowable/Activiti 无法启动报错:liquibase - Waiting for changelog lock.... - 博客文章 - 任霏的个人博客网站 Spring Boot 全局异常捕获 ControllerAdvice 无法捕获 过滤器(Filter)和拦截器(Interceptor)中的异常 - 博客文章 - 任霏的个人博客网站 Freenom 收回了全部免费域名(.tk/.cf/.gq/.ga/.ml) - 博客文章 - 任霏的个人博客网站 Alibaba Druid 数据库连接池 takeLast() AQS 死锁导致程序无响应 - 博客文章 - 任霏的个人博客网站 你的网站加入 HSTS preload 预加载列表了吗 - 博客文章 - 任霏的个人博客网站 我的博客网站接入使用 Cloudflare 的架构分享 - 博客文章 - 任霏的个人博客网站 在 Ubuntu 上的 Nginx 高并发配置实践 - 博客文章 - 任霏的个人博客网站 技术分析黑客敲诈勒索站长的新手法百度对此也无能为力 - 博客文章 - 任霏的个人博客网站 百度站长平台快速收录权限和sitemap提交权限被全部收回 - 博客文章 - 任霏的个人博客网站 极狐 GitLab 免费时代结束不升级付费账号将禁止登陆 - 博客文章 - 任霏的个人博客网站 免费.ml域名10年委托合同到期被马里共和国收回域名经营权 - 博客文章 - 任霏的个人博客网站 从极狐Gitlab看各种中间件技术选型 - 博客文章 - 任霏的个人博客网站 时隔十年首次收到 Google AdSense 的付款 - 博客文章 - 任霏的个人博客网站 ga域名被加蓬共和国从Freenom公司手中收回域名经营权 - 博客文章 - 任霏的个人博客网站 Freenom 被 Meta(Facebook) 起诉导致暂停 .tk/.ga/.ml/.cf/.gq 等新域名注册 - 博客文章 - 任霏的个人博客网站 生花妙笔信手来 – 基于 Amazon SageMaker 使用 Grounded-SAM 加速电商广告素材生成 [1] - 博客文章 - 任霏的个人博客网站 github.renfei.net 不再完整代理 Github 页面改为代理指定文件 - 博客文章 - 任霏的个人博客网站 优雅的源代码管理(三):本地优雅的使用 Git Rebase 变基 - 博客文章 - 任霏的个人博客网站 优雅的源代码管理(二):Git 的工作原理 - 博客文章 - 任霏的个人博客网站 优雅的源代码管理(一):版本控制系统 VCS(Version Control System)与软件配置管理 SCM(Software Configuration Management) - 博客文章 - 任霏的个人博客网站 ChatGPT 开发商 OpenAI 买下极品域名 AI.com - 博客文章 - 任霏的个人博客网站 火爆的 AI 人工智能 ChatGPT 国内注册教程、使用方式和收费标准 - 博客文章 - 任霏的个人博客网站 解决 SpringCloud 中 bootstrap.yml 不识别 @activatedProperties@ 参数 - 博客文章 - 任霏的个人博客网站 Cron表达式书写教程搞定Linux、Spring、Quartz的定时任务 - 博客文章 - 任霏的个人博客网站 阿里云香港可用区C发生史诗级故障 - 博客文章 - 任霏的个人博客网站 国产统信UOS服务器操作系统V20提供免费使用授权 - 博客文章 - 任霏的个人博客网站 开源站长推送工具效果评测推荐(百度/必应/谷歌) - 博客文章 - 任霏的个人博客网站 获取公网IP服务「ip.renfei.net」升级增加地理定位数据字段公示 - 博客文章 - 任霏的个人博客网站 腾讯微信成为 GitHub 秘钥扫描合作伙伴 - 博客文章 - 任霏的个人博客网站 免费设置亚马逊远程桌面 - 博客文章 - 任霏的个人博客网站 我关站了-个人备案核查要求关闭论坛系统 - 博客文章 - 任霏的个人博客网站 Linux 中 chmod 644、755、777权限的含义和使用方法 - 博客文章 - 任霏的个人博客网站 Spring Boot 3.0 发布啦但是我还是暂时放弃升级了 - 博客文章 - 任霏的个人博客网站 过时老旧电脑安装 Windows11 跳过 Win11 TPM、RAM、Secure Boot 最低系统要求限制检查 - 博客文章 - 任霏的个人博客网站 IT资讯网站 cnBeta.com 网站被关停域名已经被 clientHold - 博客文章 - 任霏的个人博客网站 当你 git push 时,极狐GitLab上发生了什么? - 博客文章 - 任霏的个人博客网站 昨晚接口又被日了,接口被疯狂调用的背后是人是鬼?是道德的沦丧还是人性的扭曲? - 博客文章 - 任霏的个人博客网站 Mac破解软件站MacWk下线破产了,我想分享Mac破解软件却不太敢 - 博客文章 - 任霏的个人博客网站 我和极狐GitLab的故事回顾 - 博客文章 - 任霏的个人博客网站 极狐 GitLab 可以集成石墨文档作为Wiki管理了 - 博客文章 - 任霏的个人博客网站 关于基于极狐 GitLab 的知识库探索思路 - 博客文章 - 任霏的个人博客网站 在极狐 Gitlab 流水线配置里设置镜像拉取策略 - 博客文章 - 任霏的个人博客网站 极狐 GitLab Markdown 可排序、可过滤的数据表格实现 - 博客文章 - 任霏的个人博客网站 极狐 GitLab Issue 统计的思路分享 - 博客文章 - 任霏的个人博客网站 把极狐 GitLab Runner 搬回家运行,指定专属 Runner - 博客文章 - 任霏的个人博客网站 给极狐 GitLab SaaS 安装百度统计代码统计仓库访问量 - 博客文章 - 任霏的个人博客网站 关于我在极狐GitLab造机器人这件事儿我觉得很酷 - 博客文章 - 任霏的个人博客网站 如何参与极狐GitLab开源项目成为贡献者 - 博客文章 - 任霏的个人博客网站 关于 Cloudflare R2 Storage 的使用体验测评和我的观点 - 博客文章 - 任霏的个人博客网站 西部数据(WD40NMZW) 4TB Elements(2060-800041-003)移动硬盘拆解记录 - 博客文章 - 任霏的个人博客网站 获取公网IP服务「ip.renfei.net」升级,支持根据请求头 Accept 响应不同格式数据 - 博客文章 - 任霏的个人博客网站 我站再次受到扫描攻击的公告 - 博客文章 - 任霏的个人博客网站 我站近期遭受到恶意不友好访问攻击公告 - 博客文章 - 任霏的个人博客网站 讨论下Java中的volatile和JMM(Java Memory Model)Java内存模型 - 博客文章 - 任霏的个人博客网站 Java中说的CAS(compare and swap)是个啥 - 博客文章 - 任霏的个人博客网站 大佬们在说的AQS,到底啥是个AQS(AbstractQueuedSynchronizer)同步队列 - 博客文章 - 任霏的个人博客网站 草根站长利用极狐GitLab作为图床外链 JIHULAB 101 - 博客文章 - 任霏的个人博客网站 极狐GitLab上的Building风云 - 之API如此多娇 JIHULAB 101 - 博客文章 - 任霏的个人博客网站 极狐GitLab上的Building风云 - 之Security风云再起 JIHULAB 101 - 博客文章 - 任霏的个人博客网站 极狐GitLab上的Building风云 - 之Docker风云必胜 JIHULAB 101 - 博客文章 - 任霏的个人博客网站 极狐GitLab上的Building风云 - 之Java Maven雄霸天下 JIHULAB 101 - 博客文章 - 任霏的个人博客网站 正确使用 Optional 优雅的解决 null 空指针 NPE 异常 - 博客文章 - 任霏的个人博客网站 世界排名网站Alexa将于2022年5月1日停止服务 - 博客文章 - 任霏的个人博客网站 免费IP数据库IP2Location的Java版客户端与BIN文件下载 - 博客文章 - 任霏的个人博客网站 人大金仓 KingbaseES V8 R3 安装包、驱动包和 License 下载地址 - 博客文章 - 任霏的个人博客网站 极狐(GitLab)SaaS平台内测试用报告 - 博客文章 - 任霏的个人博客网站 软件设计开发经验分享:文字应当使用透明度而不是固定色值 - 博客文章 - 任霏的个人博客网站 国内版 Gitlab.cn(极狐)正在为期一个月的内测阶段中 - 博客文章 - 任霏的个人博客网站 谷歌 Google Indexing 推送接口教程的更新 - 博客文章 - 任霏的个人博客网站 在苹果 MacOS 上基于 Docker 容器运行人大金仓(Kingbase)V8 R3 数据库的教程 - 博客文章 - 任霏的个人博客网站 软路由 OpenWRT(LEDE)x86_64 安装刷机教程 - 博客文章 - 任霏的个人博客网站 软路由 OpenWRT(LEDE)编译教程:使用 Github 的 Actions Workflows 免费云上编译教程 - 博客文章 - 任霏的个人博客网站 软路由 OpenWRT(LEDE)自己编译教程记录 - 博客文章 - 任霏的个人博客网站 Java中高级高并发与多线程系列(六):经典的生产者-消费者模型 - 博客文章 - 任霏的个人博客网站 Redis 未授权访问漏洞分析 cleanfda 脚本复现漏洞挖矿 - 博客文章 - 任霏的个人博客网站 记录一次 Redis 6379 被黑攻击 被设置主从同步和挖矿门罗币 - 博客文章 - 任霏的个人博客网站 Java中高级高并发与多线程系列(五):线程的 synchronized 同步与死锁 - 博客文章 - 任霏的个人博客网站 我要吐槽一下码云 Gitee 引用第三方图片失败和 issues 处理机制 - 博客文章 - 任霏的个人博客网站 站长推送工具发布并已开源,支持百度/必应/谷歌搜索引擎的主动推送 - 博客文章 - 任霏的个人博客网站 Java中高级高并发与多线程系列(四):线程运行状态的切换与操作 - 博客文章 - 任霏的个人博客网站 Java中高级高并发与多线程系列(三):FutureTask 类与 Callable 接口 - 博客文章 - 任霏的个人博客网站
千万级并发实现的秘密:内核不是解决方案,而是问题所在!
任霏 · 2013-05-19 · via 任霏博客

摘要: C10K问题让我们意识到:当并发连接达到10K时,选择不同的解决方案,笔记本性能可能会超过16核服务器。对于C10K问题,我们或绕过,或克服;然而随着并发逐渐增多,在这个后10K的时代里,你是否有想过如何去克服C10M。

既然我们已经解决了 C10K并发连接问题,应该如何提高水平支持千万级并发连接?你可能会说不可能。不,现在系统已经在用你可能不熟悉甚至激进的方式支持千万级别的并发连接。 要知道它是如何做到的,我们首先要了解Errata Security的CEO Robert Graham,以及他在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-cores, 256gigs RAM的X86服务器在Newegg网站上的报价是5000美元。该服务器可以处理1万个以上的并发连接,如果它们不能,那是因为你选择了错误的软件,而不是底层硬件的问题。这个硬件可以很容易地扩展到1千万个并发连接。

10M的并发连接挑战意味着什么:

  1. 1千万的并发连接数
  2. 100万个连接/秒——每个连接以这个速率持续约10秒
  3. 10GB/秒的连接——快速连接到互联网。
  4. 1千万个数据包/秒——据估计目前的服务器每秒处理50K的数据包,以后会更多。过去服务器每秒可以处理100K的中断,并且每一个数据包都产生中断。
  5. 10微秒的延迟——可扩展服务器也许可以处理这个规模,但延迟可能会飙升。
  6. 10微秒的抖动——限制最大延迟
  7. 并发10核技术——软件应支持更多核的服务器。通常情况下,软件能轻松扩展到四核。服务器可以扩展到更多核,因此需要重写软件,以支持更多核的服务器。

我们所学的是Unix而不是网络编程

  • 很多程序员通过W. Richard Stevens所著的《Unix网络编程》学习网络编程技术。问题是,这本书是关于Unix的,而不只是网络编程。它告诉你,让Unix做所有繁重的工作,你只需要在Unix的上层写一个小服务器。但内核规模不够,解决的办法是尽可能将业务移动到内核之外,并且自己处理所有繁重的业务。

  • 这方面有影响的一个例子是Apache每个连接线程的模型。这意味着线程调度程序根据将要到来的数据确定接下来调用哪一个read()函数,也就是把线程调度系统当作数据包调度系统来用。(我真的很喜欢这一点,从来没有想过这样的说法)。

  • Nginx宣称,它不把线程调度当作数据包调度程序,而是自己进行数据包调度。使用select找到socket,我们知道数据来了,就可以立即读取并处理数据,数据也不会堵塞。

  • 经验:让Unix处理网络堆栈,但之后的业务由你来处理。

怎样编写规模较大的软件? 如何改变你的软件,使其规模化?许多只提升硬件性能去支撑项目扩展的经验都是错误的,我们需要知道性能的实际情况。 要达到到更高的水平,需要解决的问题如下:

  1. 数据包的可扩展性
  2. 多核的可扩展性
  3. 内存的可扩展性

实现数据包可扩展——编写自己的个性化驱动来绕过堆栈

  • 数据包的问题是它们需经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上运行的代码,你可以正常调试,这不是某种怪异的硬件系统,需要特定的工程师。你需要定制的硬件在数据层提升性能,但是必须是在你熟悉的编程和开发环境上进行。 原文连接:The Secret To 10 Million Concurrent Connections -The Kernel Is The Problem, Not The Solution (文/周小璐,审校/仲浩)