canal增量同步与代码全量同步es全表缺失id问题,以及_id设置
背景/问题描述:
代码启动时候使用springboot启动将表数据全量同步,然后使用canal增量同步。
1.canal的配置:
/usr/local/canal-adapter/conf/es6:
dataSourceKey: XXX
outerAdapterKey: es-XXX
destination: XXX
groupId: XX
esMapping:
_index: XX
_type: doc
_id: id
upsert: true
# pk: id
sql: " select id, goods_code as goodsCode....from goods "
#etlCondition: "where id<='{0}'" #etl的条件参数,可以将之前没能同步的数据同步,数据量大的话可以用logstash
commitBatch: 3000
2.代码批量同步:
public <T> void batchSave(String esIndex, String esType, List<T> list) throws IOException, NoSuchFieldException, IllegalAccessException {
if (null == list || list.size() == 0) {
return;
}
BulkRequest request = new BulkRequest();
//设置超时时间
request.timeout("XX");
for (T dto : list) {
Map map = BeanUtil.entityToMap(dto);
Object id = map.get("id");
request.add(new IndexRequest(esIndex, esType, id.toString()).source(JSON.toJSONString(dto), XContentType.JSON));
}
try {
BulkResponse responses = client.bulk(request);
if (responses.hasFailures()) {
logger.error("索引:{}..同步结果存在错误:{}", esIndex, responses.hasFailures());
} else {
logger.info("索引:{}..同步完成", esIndex);
}
} catch (IOException e) {
logger.error("索引:{}..存储es异常:{}", esIndex, e.toString());
}
}
导致结果:
使用java程序同步的数据有id,增量同步的数据不存储id:
分析:
1.如果修改java程序不传递id:去掉选中代码
每次项目启动后随机给的id会导致es中数据多出一份故不可取。
2.下canal时候不使用id作为_id
同样会出现和1一样的问题。也就是es同步时候无法识别id进行增量同步。
解决:
保持程序同步不变,修改配置即可,取两次一次用于_id用于es增量同步识别,一个用于业务body返回使用。
仅仅个人使用