Nacos源码分析二十一、数据一致性同步-AP

本文深入探讨了Nacos中DistroConsistencyServiceImpl如何实现AP最终一致性。通过分析onPut和distroProtocol.sync方法,揭示了数据同步的过程。当实例添加时,触发put方法,notifier的任务会将变更事件放入队列,Service监听并更新信息,通过UDP广播给客户端。同时,DistroDelayTaskProcessor处理同步任务,通过DistroController的onSyncDatum和distroProtocol.onReceive确保集群间的数据一致性。
摘要由CSDN通过智能技术生成

先讨论DistroConsistencyServiceImpl AP最终一致性的实现。

我们知道当添加实例时会调用到put方法:

@Override
public void put(String key, Record value) throws NacosException {
    onPut(key, value);
    // 一致性协议的同步数据。这里同步数据是异步任务执行的,也就是说先返回客户端put成功再同步,弱一致性。 AP模型
    distroProtocol.sync(new DistroKey(key, KeyBuilder.INSTANCE_LIST_KEY_PREFIX), ApplyAction.CHANGE,
            globalConfig.getTaskDispatchPeriod() / 2);
}

onPut是本机节点的Notifier通知change事件。 distroProtocol.sync是最终一致性的数据同步。

onPut

public void onPut(String key, Record value) {
    
    if (KeyBuilder.matchEphemeralInstanceListKey(key)) {
        //创建临时数据
        Datum<Instances> datum = new Datum<>();
        datum.value = (Instances) value;
        datum.key = key;
        datum.timestamp.incrementAndGet();
        //放进一个map里
        dataStore.put(key, datum);
    }

    //没有监听器就返回
    if (!listeners.containsKey(key)) {
        return;
    }

    //有监听立即通知服务有改变
    notifier.addTask(key, ApplyAction.CHANGE);
}

主要就是最后一行notifier.addTask(key, ApplyAction.CHANGE); 就是往tasks队列中添加数据:

public void addTask(String datumKey, ApplyAction action) {

    // 如果services包含key,并且类型是change,则直接返回
    if (services.containsKey(datumKey) && action == ApplyAction.CHANGE) {
        return;
    }
    if (action == ApplyAction.CHANGE) {
        // 如果是change,services添加一个空数据
        services.put(datumKey, StringUtils.EMPTY);
    }
    // 数据对 加入队列中
    tasks.offer(Pair.with(datumKey, action));
}

我们之前分析到,notifier中有一个无限循环的任务,会从tasks中一直take数据,当取到新的任务时,则会发起通知:

@Override
public void run() {
    Loggers.DISTRO.info("distro notifier started");

    // 无限循环
    for (; ; ) {
        try {
            // 消费队列
            Pair<String, ApplyAction> pair = tasks.take();
            handle(pair);
        } catch (Throwable e) {
            Loggers.DISTRO.error("[NACOS-DISTRO] Error while handling notifying task", e);
        }
    }
}

private void handle(Pair<String, ApplyAction> pair) {
    try {
        String datumKey = pair.getValue0();
        ApplyActi
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值