概述
现在越来越多的技术架构下会组合使用MaxCompute和TableStore,用MaxCompute作大数据分析,计算的结果会导出到TableStore提供在线访问。MaxCompute提供海量数据计算的能力,而TableStore提供海量数据高并发低延迟读写的能力。
将 MaxCompute内数据导出至TableStore,目前可选的几种主要途径包括:
自己编写工具:使用MaxCompute SDK通过Tunnel读取表数据,再通过TableStore SDK再写入数据。
DataX:自己在服务器上托管执行DataX任务。
使用数据集成服务:其系统底层也是DataX,额外提供了服务化以及分布式的能力。
其中第二种是我们最常推荐给用户做临时的数据导出使用的,如果没有需要对数据做特殊处理的需求,我们一般不推荐第一种途径。
DataX在阿里集团内部已经应用了很多年,经历了多次双十一的考验,是一个稳定、易用、高效的工具。随着MaxCompute上结果数据越来越庞大,数据导出的速率越来越被看重,海量的数据需要在基线内完成导出。本篇文章,主要会介绍几种优化手段,以提高使用DataX来进行MaxCompute向TableStore数据导出的吞吐量。
优化过程
我们会以实际的场景,来演示如何通过一步步的优化,提升数据导出的速度。在数据导出的整个链路上,主要有三个环节,一是MaxCompute数据通道的读,二是DataX的数据交换,三是TableStore的在线写,这三个环节任意一个成为瓶颈,都会影响导出的速度。
MaxCompute数据通道的读的性能比较高,一般不会成为瓶颈,本文主要是针对后两个环节来优化。优化的核心指导方针就是:1. 提高并发,2. 降低写入延迟。接下来列举的几种优化手段,也是围绕这两点,来不断进行优化。
实验选择使用TableStore的测试环境,在MaxCompute上,我们会创建一张表并准备1亿行数据。TableStore的测试环境规模以及DataX Job宿主机的规格都较小,所以整个实验最终达到的速率是比较小的,主要为了演示速率如何提升。而在真实的TableStore生产环境上,规模足够的情况下,我们帮助过应用优化到每秒上百M甚至上G的速度,优化手段相同。
数据准备
首先在MaxCompute内创建如下表:
md5 string,
userid string,
name string,
comments string,
attr0 string,
attr1 string,
attr2 string,
attr3 string,
create_time string,
udpate_time string
);
其次在表内倒入1亿行数据,每行数据约200个字节,其中userid列采用随机值,计算出的md5值取4个字节作为md5列,数据样例如下:
测试数据导入使用的是MaxCompute Tunnel,速度还是比较可观的。
数据准备完毕后,在TableStore上创建一张表,使用md5和userid作为主键列:
TableMeta tableMeta = new TableMeta("DataTable");
tableMeta.addPrimaryKeyColumn("md5", PrimaryKeyType.STRING);
tableMeta.addPrimaryKeyColumn("userid", PrimaryKeyType.STRING);
CapacityUnit capacityUnit = new CapacityUnit(0, 0);
CreateTableRequest request = new CreateTableRequest();
request.setTableMeta(tableMeta);
request.setReservedThroughput(capacityUnit);
ots.createTable(request);
表和数据均准备完毕后,使用如下DataX Job配置类进行一次数据导出:
"job": {
"setting": {
"speed": {
"channel": "1"
}
},
"content": [
{
"reader": {
"name": "odpsreader",
"parameter": {
"accessId": "accessid",
"accessKey": "accesskey",
"project": "aliyun_ots_dev",
"table": "data_for_ots",
"partition": [],
"column": ["md5","userid","name","comments","attr0","attr1","attr2","attr3","create_time","udpate_time"],
"packageAuthorizedProject": "",
"splitMode": "record",
"odpsServer": "****",
"tunnelServer": "****"
}
},
"writer": {
"name": "otswriter",
"parameter": {
"endpoint":"http://data-import-test.cn-hangzhou.ots.aliyuncs.com",
"accessId":"accessid",
"accessKey":"accesskey",
"instanceName":"data-import-test",
"table":"DataTable",
"primaryKey":[
{"name":"md5", "type":"string"},
{"name":"userid", "type":"string"}
],
"column":[
{"name":"name","type":"string"},
{"name":"comments","typ