本文介绍全加密功能在不同场景中对系统性能的影响,有助于您评估和选择加密方案。

测试环境

配置项 ECS实例(测试客户端部署在ECS实例上) RDS PostgreSQL实例 说明
地域及可用区 华东2(上海)可用区L 华东2(上海)可用区L 本测试在同一地域及可用区
网络类型 专有网络VPC 专有网络VPC 本测试在同一VPC
CPU和内存 16核 32GB 32核 64GB 不涉及
实例规格族 计算型 c7 安全增强型 RDS需要选择安全增强型规格
实例规格 ecs.c7.4xlarge pg.x2t.4xlarge.2c 不涉及
存储类型 ESSD云盘 ESSD云盘 PL1 不涉及
实例/镜像版本 Alibaba Cloud Linux 3.2104 64位
  • 大版本:RDS PostgreSQL 13
  • 小版本:20210930
不涉及
说明 测试使用的EncDB SDK客户端为C++版本,该客户端将在后续版本发布。C++版本客户端与已发布的Java版本客户端功能相同,Java版本客户端下载,请参见配置步骤(安全增强型实例)

测试工具(sysbench)

sysbench是一个跨平台且支持多线程的模块化基准开源测试工具,用于评估系统在运行高负载的数据库时相关核心参数的性能表现。sysbench的更多信息及使用方法,请参见sysbench文档

测试指标

每秒执行事务数TPS(Transactions Per Second):数据库每秒执行的事务数,以COMMIT成功次数为准。

测试表结构

SysBench的默认表结构如下:
CREATE TABLE test1(
  id INTEGER NOT NULL,
  k INTEGER DEFAULT '0' NOT NULL,
  c CHAR(120) DEFAULT '' NOT NULL,
  pad CHAR(60) DEFAULT '' NOT NULL,
  PRIMARY KEY (id)
);
CREATE INDEX k_1 on test1(k);

测试步骤

本测试对表中的列进行加密,分析全加密PostgreSQL实例在不同场景下的性能。

  1. ECS实例安装PostgreSQL客户端。请参见官方文档
  2. 打开PostgreSQL命令行工具连接RDS PostgreSQL数据库。
    psql -h <数据库连接地址> -U <用户名> -p <端口号> -d postgres
    说明
  3. 创建测试数据库。
    CREATE DATABASE testdb;
    \c testdb
  4. 创建加密表,根据不同场景对列进行加密。
    场景 说明 SQL示例
    主键不加密,其他列加密 常见业务场景中,id为自增字段并与业务无关,因此此场景不加密id列,将其他列作为敏感信息进行加密。
    CREATE TABLE test1(
      id INTEGER NOT NULL,
      k enc_int4 DEFAULT '\xa509008855508aade16ec573d21e6aca47ab5e490d7044e748161a6635a5d939c5bbbee4' NOT NULL,
      c enc_text DEFAULT '\x9d39006e340b9cffb37a989ca544e69e6e9c0bdb0b6500a91dcc433dc5df0496' NOT NULL,
      pad enc_text DEFAULT '\x9d39006e340b9cffb37a989ca544e69e6e9c0bdb0b6500a91dcc433dc5df0496' NOT NULL,
      PRIMARY KEY (id)
    );
    CREATE INDEX k_1 on test1(k);
    加密所有列 此场景对主键列也进行加密。
    CREATE TABLE test1(
      id enc_int4 NOT NULL,
      k enc_int4 DEFAULT '\xa509008855508aade16ec573d21e6aca47ab5e490d7044e748161a6635a5d939c5bbbee4' NOT NULL,
      c enc_text DEFAULT '\x9d39006e340b9cffb37a989ca544e69e6e9c0bdb0b6500a91dcc433dc5df0496' NOT NULL,
      pad enc_text DEFAULT '\x9d39006e340b9cffb37a989ca544e69e6e9c0bdb0b6500a91dcc433dc5df0496' NOT NULL,
      PRIMARY KEY (id)
    );
    CREATE INDEX k_1 on test1(k);
  5. 退出数据库,使用sysbench工具加载测试数据。
    说明 本测试中,使用SysBench加载32个表,其中每个表包含一百万行记录。
    sysbench --db-driver=pgsql \
      --pgsql-host=[database server host] \
      --pgsql-port=[database server port] \
      --pgsql-user=[database user name] \
      --pgsql-password=[database user password] \
      --pgsql-db=testdb \
      --auto_inc=false \
      --table_size=1000000 \
      --tables=32 \
      --threads=32 \
      --time=600 \
      --pg_use_encrypt=[true or false] \
      oltp_common prepare
  6. 执行自定义测试脚本。
    sysbench --db-driver=pgsql \
      --pgsql-host=[database server host] \
      --pgsql-port=[database server port] \
      --pgsql-user=[database user name] \
      --pgsql-password=[database user password] \
      --pgsql-db=testdb \
      --table_size=1000000 \
      --tables=32 \
      --threads=XXX \
      --time=600 \
      --report-interval=1 \
      --pg_use_encrypt=[true or false] \
      [lua script name] run
  7. 清理数据。
    sysbench --db-driver=pgsql \
      --pgsql-host=[database server host] \
      --pgsql-port=[database server port] \
      --pgsql-user=[database user name] \
      --pgsql-password=[database user password] \
      --pgsql-db=testdb \
      --tables=32 \
      oltp_common cleanup

测试场景1:主键不加密,其他列加密

说明
  • 本次测试的每个结果均为运行10次测试的TPS平均值,其中每次测试执行10分钟。
  • 性能测试结果包含了在客户端对返回的加密字段进行解密的性能损耗。

测试数据

  • 点查询性能
    比例 SQL模板
    100%
    说明 比例指一条事务中执行SQL模板中定义的SQL所占的比例。
    SELECT c FROM test1 WHERE id=?;
    场景1点查询
    表 1. TPS(千)性能对比
    并发线程数 未开启全加密功能扩展 开启全加密功能扩展 性能损失
    8 38.206 34.343 10.1%
    16 74.678 66.832 10.5%
    24 108.804 97.491 10.4%
    32 140.966 126.981 9.9%
  • 范围查询性能
    比例 SQL模板
    100%
    SELECT SUM(k) FROM test1 WHERE id BETWEEN ? AND ?;
    说明 范围查询的长度默认为100。
    场景1范围查询
    表 2. TPS(千)性能对比
    并发线程数 未开启全加密功能扩展 开启全加密功能扩展 性能损失
    8 11.380 9.741 14.4%
    16 22.173 19.059 14.0%
    24 32.234 27.392 15.0%
    32 41.688 35.062 15.9%
  • 写性能
    比例 SQL模板
    25%
    UPDATE test1 SET k=k+1 WHERE id=?;
    25%
    UPDATE test1 SET c=? WHERE id=?;
    25%
    DELETE FROM test1 WHERE id=?;
    25%
    INSERT INTO test1 (id, k, c, pad) VALUES (?, ?, ?, ?);
    场景1写性能
    表 3. TPS(千)性能对比
    并发线程数 未开启全加密功能扩展 开启全加密功能扩展 性能损失
    8 6.239 4.156 33.4%
    16 12.032 7.976 33.7%
    24 17.552 11.300 35.6%
    32 22.776 14.439 36.6%

测试结论

非密文主键查询场景下,开启全加密功能扩展后,性能损失较小。

测试场景2:加密所有列

说明
  • 本次测试的每个结果均为运行10次测试的TPS平均值,其中每次测试执行10分钟。
  • 性能测试结果包含了在客户端对返回的加密字段进行解密的性能损耗。

测试数据

  • 点查询性能
    比例 SQL模板
    100%
    SELECT c FROM test1 WHERE id=?;
    场景2点查询
    表 4. TPS(千)性能对比
    并发线程数 未开启全加密功能扩展 开启全加密功能扩展 性能损失
    8 38.206 18.246 52.2%
    16 74.678 35.529 52.4%
    24 108.804 50.340 53.7%
    32 140.966 64.615 54.2%
  • 范围查询性能
    比例 SQL模板
    100%
    SELECT SUM(k) FROM test1 WHERE id BETWEEN ? AND ?;
    说明 范围查询的长度默认为100。
    场景2范围查询
    表 5. TPS(千)性能对比
    并发线程数 未开启全加密功能扩展 开启全加密功能扩展 性能损失
    8 11.380 2.827 75.2%
    16 22.173 5.524 75.1%
    24 32.234 7.339 77.2%
    32 41.688 9.119 78.1%
  • 写性能
    比例 SQL模板
    25%
    UPDATE test1 SET k=k+1 WHERE id=?;
    25%
    UPDATE test1 SET c=? WHERE id=?;
    25%
    DELETE FROM test1 WHERE id=?;
    25%
    INSERT INTO test1 (id, k, c, pad) VALUES (?, ?, ?, ?);
    场景2写性能
    表 6. TPS(千)性能对比
    并发线程数 未开启全加密功能扩展 开启全加密功能扩展 性能损失
    8 6.239 3.571 42.8%
    16 12.032 6.860 43.0%
    24 17.552 9.339 46.8%
    32 22.776 11.259 50.6%

测试结论

加密所有列相比于不加密主键列的查询结果,除了客户端的解密开销外,由于加密列的索引查询需要调用Intel SGX相关指令的频率更高,总代价更大,性能损失较大。

测试场景3:非主键列查询

说明
  • 本次测试的每个结果均为运行10次测试的TPS平均值,其中每次测试执行10分钟。
  • 性能测试结果包含了在客户端对返回的加密字段进行解密的性能损耗。

测试数据

比例 SQL模板
100%
SELECT c FROM test1 WHERE k=?;
非主键查询
表 7. TPS(千)性能对比
并发线程数 未开启全加密功能扩展(无索引) 未开启全加密功能扩展(有索引) 开启全加密功能扩展(无索引) 开启全加密功能扩展(有索引)
8 0.235 24.805 0.00254 6.079
16 0.246 47.733 0.00232 11.718
24 0.252 68.513 0.00255 15.711
32 0.256 87.411 0.00263 19.436

测试结论

对加密列的查询在使用索引前后的性能差距达到了上千倍,而明文数据上的差距则是上百倍,这是因为没有索引的密文列上除了顺序扫描表带来的开销外,还有加解密的开销,因此在加密列上的查询性能差距会更大。因此,有效使用索引能极大幅度提升查询性能。

测试场景4:加密列算子操作

说明
  • 本次测试的每个结果均为运行10次测试的TPS平均值,其中每次测试执行10分钟。
  • 性能测试结果包含了在客户端对返回的加密字段进行解密的性能损耗。

测试数据

比例 SQL模板
100%
SELECT c FROM test1 WHERE id BETWEEN ? AND ? ORDER BY c;
针对加密列的算子操作性能
表 8. TPS(千)性能对比
并发线程数 开启全加密功能扩展(无ORDER BY) 开启全加密功能扩展(有ORDER BY)
8 3.569 0.936
16 4.755 1.821
24 5.081 2.428
32 5.155 2.996

测试结论

开启全加密功能扩展后,对密文列进行计算量大的查询(如排序ORDERY BY),会有较多性能损耗。

全加密功能扩展使用建议

建议开启全加密功能扩展后,只对关键的敏感数据列加密。