使用spark自带的写入MySQL的api,如下
dataframe.write.mode(SaveMode.Append).jdbc(url, table_name, prop)
我设置的是10s一个批次,一个批次的数据量大概有16000条,已经做好全部优化,但是还是有几十秒的延迟,造成kafka数据堆积,导致ads实时性并不太好。
后来使用ADB Client写入ads,速度贼快,效果很好!!
阿里云分析型数据库MySQL版
maven中添加依赖
<dependency>
<groupId>com.alibaba.cloud.analyticdb</groupId>
<artifactId>adbclient</artifactId>
<version>1.0.2</version>
</dependency>
使用demo如下,根据服务器自行配置
public class AdbClientUsage {
public void demo() {
DatabaseConfig databaseConfig = new DatabaseConfig();
// Should set your database real host or url
databaseConfig.setHost("100.100.100.100");
// Should set your database real port
databaseConfig.setPort(8888);
// 如果是阿里云上的ADB库,请填accessId
databaseConfig.setUser("your db username");
// 如果是阿里云上的ADB库,请填accessKey
databaseConfig.setPassword("your db password");
databaseConfig.setDatabase("your db name");
// 设置需要写入的表名列表
List<String> tables = new ArrayList<String>();
tables.add("your table name");
tables.add("your table name 2");
// 一旦new Client实例之后,table配置是不可修改的
databaseConfig.setTable(tables);
// 设置需要写入的表字段
List<String> columns = new ArrayList<String>();
columns.add("column1");
columns.add("column2");
// 如果是所有字段,字段列表使用 columns.add("*") 即可
databaseConfig.setColumns("your table name", columns);
databaseConfig.setColumns("your table name 2", Collections.singletonList("*"));
// 如果出现insert失败,是否跳过
// NOTE: ignore insert error may cause data not successfully insert be lost
databaseConfig.setIgnoreInsertError(false);
// If the value of column is empty, set null
databaseConfig.setEmptyAsNull(true);
// 使用insert ignore into方式进行插入
databaseConfig.setInsertIgnore(true);
// commit时,写入ADB出现异常时重试的3次
databaseConfig.setRetryTimes(3);
// 重试间隔的时间为1s,单位是ms
databaseConfig.setRetryIntervalTime(1000);
// Initialize AdbClient,初始化实例之后,databaseConfig的配置信息不能再修改
AdbClient adbClient = new AdbClient(databaseConfig);
// 数据需要攒批,多次add,再commit,具体攒批数量见"注意事项"
for (int i = 0; i < 10; i++) {
// Add row(s) to buffer. One instance for one record
Row row = new Row(columns.size());
// Set column
// the column index must be same as the sequence of columns
// the column value can be any type, internally it will be formatted according to column type
row.setColumn(0, i); // Number value
row.setColumn(1, "string value"); // String value
// 如果sql长度满了会在addRow或者addMap的时候会进行一次自动提交
// 如果提交失败会返回AdbClientException异常,错误码为COMMIT_ERROR_DATA_LIST
adbClient.addRow("your table name", row);
}
Row row = new Row();
row.setColumn(0, 10); // Number value
row.setColumn(1, "2018-01-01 08:00:00"); // Date/Timestamp/Time value
adbClient.addRow("your table name 2", row);
// Update column. Row实例可复用
row.updateColumn(0, 11);
row.updateColumn(1, "2018-01-02 08:00:00");
adbClient.addRow("your table name 2", row);
// Add map(s) to buffer
Map<String, String> rowMap = new HashMap<String, String>();
rowMap.put("column1", "124");
rowMap.put("column2", "string value");
// 这边需要攒批的,最好多次add之后在进行commit
adbClient.addMap("your table name", rowMap);
// Commit buffer to ADS
// Buffer is cleaned after successfully commit to ADS
try {
adbClient.commit();
} catch (Exception e) {
// TODO: Handle exception here
} finally {
adbClient.stop();
}
}
}
在spark streaming中使用这种写入方式,速度有几十倍的提升,不过在集群中跑的时候可能会出现NoFoundClass这种异常,需要在spark中添加依赖包:
adbclient-1.0.2.jar
druid-1.1.12.jar