本文主要介绍 Tunnel 增量性能的测试,主要包括测试环境、测试工具、测试方案、测试指标、测试结果概述以及测试细则等。

测试环境

  • 表格存储实例
    • 实例类型:高性能实例
    • 实例地域:华东1
    • 实例地址:私网地址,避免网络的不确定性因素对测试造成的干扰
  • 测试机器配置
    • 类型:阿里云 ECS
    • 区域:华东1
    • 型号:共享通用型 (mn4) ecs.mn4.4xlarge
    • 配置:
      • CPU:16核
      • 内存:64GB
      • 网卡:Red Hat、Inc Virtio network device
      • 操作系统:CentOS 7u2

测试工具

  • 压力器

    压力器使用表格存储内部使用的压力测试工具进行数据的批量并发写入,底层基于表格存储Java SDK的BatchWrite操作完成。

  • 预分区工具

    使用表格存储内部使用的压力测试工具,配置好表名和分区数等信息,进行表格的自动创建和预分区。

  • 速率统计器

    增量的实时消费速率统计基于Tunnel Java SDK完成,在传入的Callback中加入下图中类似的速率统计逻辑,进行速率和消费总行数的实时统计。

    示例

    private static final Gson GSON = new Gson();
        private static final int CAL_INTERVAL_MILLIS = 5000;
        static class PerfProcessor implements IChannelProcessor {
            private static final AtomicLong counter = new AtomicLong(0);
            private static final AtomicLong latestTs = new AtomicLong(0);
            private static final AtomicLong allCount = new AtomicLong(0);
    
            @Override
            public void process(ProcessRecordsInput input) {
                counter.addAndGet(input.getRecords().size());
                allCount.addAndGet(input.getRecords().size());
                if (System.currentTimeMillis() - latestTs.get() > CAL_INTERVAL_MILLIS) {
                    synchronized (PerfProcessor.class) {
                        if (System.currentTimeMillis() - latestTs.get() > CAL_INTERVAL_MILLIS) {
                            long seconds = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis() - latestTs.get());
                            PerfElement element = new PerfElement(System.currentTimeMillis(), counter.get() / seconds, allCount.get());
                            System.out.println(GSON.toJson(element));
                            counter.set(0);
                            latestTs.set(System.currentTimeMillis());
                        }
                    }
                }
            }
    
            @Override
            public void shutdown() {
                System.out.println("Mock shutdown");
            }
        }

测试方案

使用Tunnel进行数据同步时,在单Channel间是串行同步(串行是为了保障用户数据的有序性),不同Channel间是相互并行的。在增量场景下,Channel数和表的分区数是相等的。由于Tunnel的整体性能和表的分区数有很大的关联性,所以在本次的性能测试中,将主要考虑不同分区数(Channel 数)对于Tunnel增量的同步速率的影响。

  • 测试场景

    我们将主要测试以下场景:

    • 单机同步单分区
    • 单机同步4个分区
    • 单机同步8个分区
    • 单机同步32分区
    • 单机同步64分区
    • 2台机器同步64分区
    • 2台机器同步128分区
    说明 上述测试场景不是产品能力的极限测试,对表格存储服务端的整体压力较小。
  • 测试步骤
    1. 创建数据表并进行预分区(不同分区数的测试都会有单独的一张表)。
    2. 创建增量通道。
    3. 使用压力器进行增量数据的写入。
    4. 使用速率统计器进行QPS的实时统计,同时观察程序占用的系统资源(CPU、内存等)。
    5. 通过监控获得增量数据同步消耗的总网络带宽。
  • 测试数据说明

    如下图所示,样例数据由4个主键和1~2个属性列组成,单行的大小在220字节左右。第一主键(分区键)会使用 4-Byte-Hash 的方式产生,这样可以确保压测数据比较均匀的写入到每个分区上。



测试指标

本次测试主要包含以下几项指标:

  • QPS(row):每秒同步的数据行数。
  • Avg Latency(ms/1000行):同步1000行数据所需的时间,单位为毫秒。
  • CPU(核):数据同步消耗的单核 CPU 总数。
  • Mem(GB):数据同步消耗的物理总内存。
  • 带宽(MBps):数据同步消耗的总网络带宽。
说明 本次性能测试不是产品能力的极限能力,是从实际使用角度出发进行的性能测试。

测试结果

该部分主要概述各个场景下的指标测试结果,测试的细节可以参见测试细则部分。

  • QPS和延迟

    下图展示的是各个场景下每秒同步的数据行数和同步1000行数据所需的时间。从图中我们看出QPS的增长和分区数的增加呈线性关系。

    在本次测试中,单机同步64分区场景下,将千兆的网卡成功打爆(参见测试细则部分),导致只有57W的QPS。两台机器对64分区进行同步后,平均QPS成功达到了78W行左右,约等于单机-32分区场景下(42W)的两倍速率。而在最后的两台机器-128分区场景下,Tunnel增量同步的QPS也成功达到了100W行。



  • 系统资源消耗

    下图展示的是各个场景下CPU和内存的消耗情况,CPU基本上和分区数呈线性关系。

    在单机-单分区场景下,消耗的 CPU 为0.25个单核 CPU。2台机器-128个分区的场景下,当同步 QPS 达到100W行时,消耗的 CPU 也仅为10.2个单核 CPU。从内存消耗方面看。在分区数较少时,CPU 和分区数呈线性关系,而在分区数增加较多(32个和64个)时,单机内存消耗基本维持在5.3GB左右。



  • 网络总带宽消耗

    下图展示的是增量同步消耗的总带宽,从图中我们可以看出带宽和Channel数的线性关系(略单机-16分区场景)。

    在单机-64分区场景下,我们可以看到带宽总消耗为125MBps,已经成功把千兆网卡打爆,而在换成2台机器-64分区进行数据消费后,我们发现64分区真正的吞吐量为169MBps,和单机-32分区的86MBps的两倍近乎相等。而在两台机器-128分区的100W QPS场景中,总吞吐量也达到了220MBps。



测试细则

  • 单机单 Channel:1.9W QPS
    • 测试时间:2019/1/30 17:40
    • QPS:稳定速率19000行/秒左右;峰值速率:21800行
    • Latency:50ms/1000行左右

    • CPU占用:单核25%左右
    • 内存占用:总物理内存0.4%左右,即0.256GB左右(测试机器内存为64GB)
    • 网络带宽消耗:4000KB/s左右

  • 单机4分区:7W QPS


    • 测试时间:2019/1/30 20:00
    • QPS:稳定速率70000行/秒左右,峰值速度72400行/秒
    • Latency:14.28ms/1000行左右

    • CPU占用:单核70%左右
    • 内存占用:物理内存1.9%左右,即1.1GB左右。(测试机器内存为64GB)
    • 网络带宽消耗:13MBps 左右

  • 单机8分区:13W QPS


    • 测试时间:2019/1/30 20:20
    • QPS:稳定速率130000行/秒,峰值速率141644行/秒
    • Latency:7.69ms/1000行左右

    • CPU占用:单核120%左右
    • 内存占用:物理总内存4.1%左右,即2.62GB左右(测试机器内存为64GB)
    • 消耗网络带宽:27MBps 左右

  • 单机32分区:42W QPS


    • 测试时间:2019/1/31 15:50
    • QPS:稳定速率42W/s, 峰值速率447600行/s
    • Latency:2.38ms/1000行

    • CPU占用:单核450%左右
    • 内存占用:8.2%左右,即5.25GB 左右(物理内存 64GB)
    • 增量数据消耗网络带宽:86MBps 左右

  • 单机64分区(千兆网卡被打满): 57W QPS


    • 测试时间:2019/1/31 22:10
    • QPS:稳定速率57W行/s左右,峰值速率581400行/s
    • Latency:1.75ms/1000行左右

    • CPU占用:单核640%左右
    • 内存占用:8.4%左右,即5.376GB左右
    • 增量数据消耗网络带宽:125MBps 左右(达到千兆网卡的速率极限)

  • 2台机器共同消费64分区:78W QPS


    • 测试时间:2018/1/31 22:30
    • QPS:每台稳定速率在39W行/s左右,总的稳定速率在78W行/s左右
    • Latency:1.28ms/1000行

    • CPU占用:每台单核420%左右,共单核840%
    • 内存占用:每台8.2%左右,共16.4%(10.5GB)
    • 增量数据消耗总网络带宽:169MBps 左右(和单机64分区对比,可以看出单机的网络已经成为瓶颈)

  • 2台机器共同消费128分区(两台千兆机器的网卡近乎被打满):100W QPS


    • 测试时间:2018/1/31 23:20
    • QPS:每台稳定速率在50W行/s左右,总的稳定速率在100W行/s左右
    • Latency:1ms/1000行 左右

    • CPU占用:每台单核560%左右,两台共计单核1020%
    • 内存占用:每台8.2%左右,共16.4%(10.5GB)
    • 增量数据消耗总网络带宽:220MBps 左右

总结

通过这次对于增量性能的实际测试,我们发现了单分区(或分区数较少)的速率主要取决于服务器端的读盘等延迟,本身机器资源的消耗很小。而随着分区数增长,Tunnel增量的整体吞吐也进行了线性的增长直至达到系统的瓶颈(本文中是网络带宽)。最后,在单机资源被打满的情况下,我们也可以通过添加新的机器资源进一步的提升系统整体的吞吐量,有效的验证了Tunnel具备良好的水平扩展性。