开发者社区 问答 正文

nacos DataSyncer存在并发问题

文件路径nacos/naming/src/main/java/com/alibaba/nacos/naming/consistency/ephemeral/distro/DataSyncer.java

submit方法中,第120行的代码片段1

Map<String, Datum> datumMap = dataStore.batchGet(keys);

这里面从dataStore取出了keys对应的数据,并在接下来132行将其序列化后,发送到其他naming节点。 132行代码

boolean success = NamingProxy.syncData(data, task.getTargetServer());

但是在发送成功前(执行121至132行间的逻辑时),taskMap中的keys依旧存在,发送成功后才会从taskMap移除,这里存在并发问题。 我们先看88行至105行的代码逻辑

if (task.getRetryCount() == 0) {
    Iterator<String> iterator = task.getKeys().iterator();
    while (iterator.hasNext()) {
        String key = iterator.next();
        if (StringUtils.isNotBlank(taskMap.putIfAbsent(buildKey(key, task.getTargetServer()), key))) {
            // associated key already exist:
            if (Loggers.DISTRO.isDebugEnabled()) {
                Loggers.DISTRO.debug("sync already in process, key: {}", key);
            }
            iterator.remove();
        }
    }
}
if (task.getKeys().isEmpty()) {
    // all keys are removed:
    return;
}

当其他线程执行到88行至105行间的代码时,如果相同的key存在于taskMap中,这个key将不会再执行后续的流程,会导致第一个线程执行132行同步到其他节点的数据是旧的

展开
收起
一人吃饱,全家不饿 2021-02-01 23:02:47 1134 分享 版权
来自: 阿里开源
1 条回答
写回答
取消 提交回答
  • 这里在很极限的情况下的确可能存在问题,但是这个Distro本身就是AP协议,还有对账机制可以修复遗漏的同步信息,详见/checksum接口。

    2021-02-01 23:02:57
    赞同 展开评论
问答分类:
问答标签:
问答地址: