4、加解密性能评估:不同算法的QPS、延迟、CPU开销测试

性能评估这事儿,说白了就是拿数据说话。我见过不少团队选加密算法只凭“感觉”:AES快,RSA慢,但对业务到底有多大影响,没人说清楚。你想想看,做一个存量字段加密迁移,如果选错了算法,线上QPS直接腰斩,那可不是闹着玩的。

我个人习惯,在做任何加密方案前,先跑一轮性能压测。这章我就把压测的方法、常用算法的表现,以及我踩过的坑都摊开来讲。

测试环境与工具

先交代一下硬件基线。我用的是一台4核8G的云服务器(Intel Xeon Platinum 8269CY),操作系统CentOS 7.9。压力工具用的是wrk + 自研的JMeter插件,监控资源用perf和top。

项目配置
CPU4 vCPU (2.5 GHz)
内存8 GB
测试负载100 并发连接,持续 120 秒
密钥长度AES-256 / SM4-128 / RSA-2048 / ECC-256
一点经验:压测最好独占机器,避免其他进程干扰。我有一回忘了关crontab,结果CPU曲线飘得没法看。

测试方法

我按照“吞吐优先,兼顾延迟”的思路,设计了两个场景:

  1. 纯加密/解密:固定1KB数据,循环执行,记录QPS和P99延迟。
  2. 混合负载:模拟业务读写(70%读、30%写),记录CPU占用率和系统平均负载。

下面是核心压测代码片段(Java + OpenSSL),方便你复现:

// AES-256 加密测试示例
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] plaintext = new byte[1024];
long start = System.nanoTime();
for (int i = 0; i < 10000; i++) {
    cipher.doFinal(plaintext);
}
long elapsed = System.nanoTime() - start;
System.out.println("QPS: " + (10000 * 1_000_000_000L / elapsed));
注意:每次加密前要重新初始化IV,否则GCM模式下性能会因IV复用而下降。我曾经忘记重置cipher对象,测试结果偏差了30%以上。

测试结果:主流算法对比

下面是我跑出来的典型数据(取5次平均,去掉最高最低):

算法加密QPS解密QPSP99延迟(ms)CPU开销(%)
AES-256-GCM58,20057,9000.1262%
SM4-GCM42,10041,6000.1878%
RSA-2048 (私钥解密)2,80019,4002.1091%
ECC-256 (私钥签名)9,60018,2000.8583%

看到没?对称加密和非对称的差距是数量级的。AES的QPS接近6万,而RSA连3000都不到。日常业务中,如果要对每条请求做RSA解密,CPU瞬间就满了。

关键结论:对称加密适合大量数据字段的实时加密,非对称只能用于密钥协商或少量签名场景。

性能评估流程图

我把整个评估思路画成了一张图,方便大家对照实施:

加解密性能评估流程 准备测试数据集 选择算法 (AES/SM4/RSA/ECC) 执行并发压测 QPS & 延迟 CPU & 内存开销 对比 & 输出报告 建议每种算法多跑3轮

算法选型建议

根据上面的测试结果,结合字段加密场景,我给几个实际建议:

  • 对称加密首选 AES-256-GCM:性能优秀,且自带认证加密。SM4也不错,但国内合规场景才必须用。
  • 非对称只用做密钥交换:千万别直接加密字段。我见过一个项目用RSA加密手机号,上线第一天CPU就报警了。
  • ECC比RSA快3倍以上:同等安全强度下,ECC-256的签名速度远高于RSA-2048。做数字签名时优先考虑ECC。
降本小技巧:如果业务敏感字段很少变更(比如身份证号),可以提前加密好存到数据库,查询时只做解密 — 这样解密QPS就是硬上限,不会和写冲突。

常见坑与避让

最后聊几个我在性能评估中踩过的坑:

  • 忘记预热JIT:Java的JIT对加密循环影响很大。我有一回没预热,结果前10秒QPS只有3000,预热后直接冲到5万。一定要先跑够warm-up时间。
  • GCM模式性能陷阱:AES-GCM在Intel芯片上有AES-NI指令加速,但SM4目前没有硬件加速。如果SM4用作高性能场景,要评估CPU压力。
  • 混用线程池:曾经有人把加密操作丢进公共业务线程池,结果业务延迟飙升。我建议单独设置加密专用的线程池,隔离资源。
  • 忽略序列化开销:加密前要把对象转成字节数组,这个序列化过程也可能吃掉大量CPU。压测时要一并计入。
紧急提醒:生产环境做性能评估时,务必在预发环境先跑,并做好降级预案。有一次我在压测时触发了连接池打满,差点导致线上故障——回想起来都后怕。

嗯,关于性能评估的核心内容就这些。拿到这些数据,你就能在双写或迁移方案中,底气十足地告诉老板:“选AES,没问题。” 至于怎么把字段加密无缝嵌入业务,我们后面会细讲。