返回

文章详情

Stalwart v1.0:全球最快的邮件服务器

Hacker News2026年10月26日 15:57

2026年10月26日 - 16分钟阅读 五年前的2021年10月3日,第一个提交出现在一个名为mail-parser的小型仓库中。它是一个用Rust编写的电子邮件解析库,仅此而已。在接下来的五年中,它发展成为一个完整的邮件和协作服务器,支持JMAP、IMAP、POP3、SMTP、CalDAV、CardDAV和WebDAV、垃圾邮件过滤、集群以及对半打存储后端的支持。今天,在五年持续开发后,我们自豪地宣布Stalwart v1.0,这是第一个稳定版本。版本1.0并不意味着成为另一个功能版本。它有两个目标。第一个是性能:让服务器的每个部分尽可能快,并用数据证明。第二个是数据本身的稳定性:最终确定数据库模式,以便,从现在开始,升级Stalwart意味着安装一个新版本,没有之前一些版本所需的破坏性迁移。在这个过程中,也有一些新功能加入,包括在PDF和办公文档内的全文搜索。让我们逐步了解一下。在这个版本的大部分工作是在分析器下进行的。几个月来,我们测量了Stalwart的CPU周期、内存和数据库轮询时间,重写了所有突出的部分,并再次进行测量。此次发布包含近200个提交,涉及1300多个文件,其中绝大多数存在的目的是让某些东西更快或者更轻便。邮件服务器在寻找特定字节时花费了意想不到的时间:头行的结束符、MIME边界、quoted-printable主体中的等号、IMAP标签结束的空格。以每次一个字节的方式完成,对于10 MB的消息来说,循环迭代量是非常庞大的。两个技术让CPU可以一次处理多个字节的工作:SIMD(单指令多数据)利用现代处理器的宽向量寄存器(x86-64上的SSE2、SSSE3和AVX2,ARM上的NEON)使用单个指令比较或转换16或32个字节。SWAR(寄存器内的SIMD)用普通的64位整数应用相同的概念:一些精心选择的算术和位操作同时测试一个字的所有八个字节。不需要特殊指令,因此在每个CPU上都能工作。Stalwart现在在所有重要的地方使用这两种技术。最底层的栈有两个库与服务器一起达到1.0:mail-parser 1.0,Stalwart起始的库,已经从头重写。SIMD内核定位MIME边界和头字段,SWAR处理头名称,解析后的消息存储在少量扁平向量中,只有在有人实际读取时,主体才被解码。CPU特定的内核在运行时被选择,并且每一个都经过对照一个普通的标量参考进行模糊测试。与其他解析器相比,它比流行的Rust mailparse crate快3倍,比Dovecot自己的解析器快9倍,比libEtPan!、VMime和GMime在完全解析时快15到31倍。encodify是一个新的编码库,具有用于Base64、Base32和quoted-printable的SIMD内核,这些编码几乎承载了电子邮件中的每个附件和非ASCII头。解码一个MIME封装的Base64附件在AMD EPYC服务器上比标准的Rust base64 crate快22倍,而quoted-printable解码则比quoted_printable crate快9倍。它现在处理服务器中的每个Base64、quoted-printable和IMAP UTF-7转换。在它们之上,协议层也进行了相同的处理。IMAP命令解析器现在是基于表驱动的,扫描整批字节,而不是对每个字符执行状态机。SMTP命令解析器、JMAP后面的JSON解析器、垃圾邮件过滤器标记化器、HTML到文本的转换器、变长整数编码器和日志序列化器都使用SWAR扫描。甚至表达语言,管理员用它来做路由和过滤决策,现在被编译成紧凑的字节码,具有针对常见比较的专用指令,并在回收的内存区域中进行评估。快速解析是浪费的,如果每个请求随后都在数据库上等待,因此我们同样花了很长时间来研究Stalwart如何与存储交互。标识符现在在使用它们的同一写事务内分配,从每个消息交付中消除整个轮询。读-修改-写更新,例如添加关键字或附加到搜索索引,在后端内部作为合并操作运行。存储对象使用专门针对电子邮件、日历和联系人数据训练的字典通过zstd压缩。每个后端也单独进行了调优:RocksDB:每种数据现在都生活在一个为其访问方式配置的列族中,具有用于点查找的布隆过滤器,适用于扫描的较大块,以及为数据变化而调优的压缩。热计数器,例如队列配额,分散到最多256个插槽中,以避免写冲突。

阅读全文 →

赞助内容

NordVPN Next-gen Antivirus

本站免费、广告极少。如果觉得有帮助,可以请我们喝杯咖啡 —— 任何金额都对持续运营有实际帮助。

☕请我喝杯咖啡