先看问题,代码如下,代码中有两个靠在一起的ES操作(searchService是自己封装的ES操作,调用了ElasticsearchRestTemplate去更新数据库),一个更新table索引下的表名称,一个更新table索引下表负责人。问题:更新表负责人时总是更新不上,而表名称更新正常。
/**
* 同步至 外部数据 es、neo4j
* @param tableNameCnMap 表中文名
* @param managerMap 表负责人
*/
private void updateExternalData(
Map<String, List<Long>> tableNameCnMap, Map<Long, List<Long>> managerMap) {
try {
for (Map.Entry<String, List<Long>> entry : tableNameCnMap.entrySet()) {
//操作es数据库更新表名称,方法底层调用ElasticsearchRestTemplate更新表名称
searchService.batchUpdateField(
entry.getValue(), NAME_ZH_FIELD, entry.getKey(), TABLE_INDEX_COORDINATE);
lineageService.updateNodeProperties(
entry.getValue(), AssetTypeEnum.TABLE, TABLE_NAME_CN_FIELD, entry.getKey());
}
Set<Long> ownerIds = managerMap.keySet();
Map<Long, AssetOwner> assetOwnerMap = searchService.getAssetOwner(ownerIds);
for (Map.Entry<Long, List<Long>> entry : managerMap.entrySet()) {
AssetOwner value = assetOwnerMap.get(entry.getKey());
//操作es数据库更新表负责人,方法底层调用ElasticsearchRestTemplate更新表负责人
searchService.getUpdateOwner(entry.getValue(), value, TABLE_INDEX_COORDINATE);
}
} catch (Exception e) {
log.error("update elastic search field error", e);
}
}
解决方法1:
在两个ES操作直接让线程睡上一段时间;为了防止阻塞主线程,updateExternalData()最好采用异步执行。
/**
* 同步至 外部数据 es、neo4j
* @param tableNameCnMap 表中文名
* @param managerMap 表负责人
*/
private void updateExternalData(
Map<String, List<Long>> tableNameCnMap, Map<Long, List<Long>> managerMap) {
try {
for (Map.Entry<String, List<Long>> entry : tableNameCnMap.entrySet()) {
//操作es数据库,更新表名称
searchService.batchUpdateField(
entry.getValue(), NAME_ZH_FIELD, entry.getKey(), TABLE_INDEX_COORDINATE);
lineageService.updateNodeProperties(
entry.getValue(), AssetTypeEnum.TABLE, TABLE_NAME_CN_FIELD, entry.getKey());
}
Set<Long> ownerIds = managerMap.keySet();
Map<Long, AssetOwner> assetOwnerMap = searchService.getAssetOwner(ownerIds);
Thread.sleep(200);
for (Map.Entry<Long, List<Long>> entry : managerMap.entrySet()) {
AssetOwner value = assetOwnerMap.get(entry.getKey());
//操作es数据库更新表负责人
searchService.getUpdateOwner(entry.getValue(), value, TABLE_INDEX_COORDINATE);
}
} catch (Exception e) {
log.error("update elastic search field error", e);
}
}
解决方法2
之前es操作前设置刷新策略位立即刷新
private void updateExternalData(
Map<String, List<Long>> tableNameCnMap, Map<Long, List<Long>> managerMap) {
try {
//设置刷新策略,该方法代码在下面
searchService.setRefreshPolicy(RefreshPolicy.IMMEDIATE);
for (Map.Entry<String, List<Long>> entry : tableNameCnMap.entrySet()) {
searchService.batchUpdateField(
entry.getValue(), NAME_ZH_FIELD, entry.getKey(), TABLE_INDEX_COORDINATE);
lineageService.updateNodeProperties(
entry.getValue(), AssetTypeEnum.TABLE, TABLE_NAME_CN_FIELD, entry.getKey());
}
Set<Long> ownerIds = managerMap.keySet();
Map<Long, AssetOwner> assetOwnerMap = searchService.getAssetOwner(ownerIds);
for (Map.Entry<Long, List<Long>> entry : managerMap.entrySet()) {
AssetOwner value = assetOwnerMap.get(entry.getKey());
searchService.getUpdateOwner(entry.getValue(), value, TABLE_INDEX_COORDINATE);
}
} catch (Exception e) {
log.error("update elastic search field error", e);
}
@Resource private ElasticsearchRestTemplate esOperations;
public void setRefreshPolicy(RefreshPolicy policy){
esOperations.setRefreshPolicy(policy);
}
RefreshPolicy#IMMEDIATE:
请求向ElasticSearch提交了数据,立即进行数据刷新,然后再结束请求。
优点:实时性高、操作延时短。
缺点:资源消耗高。
RefreshPolicy#WAIT_UNTIL:
请求向ElasticSearch提交了数据,等待数据完成刷新,然后再结束请求。
优点:实时性高、操作延时长。
缺点:资源消耗低。
RefreshPolicy#NONE:
默认策略。
请求向ElasticSearch提交了数据,不关系数据是否已经完成刷新,直接结束请求。
优点:操作延时短、资源消耗低。
缺点:实时性低。