Nacos简析:distro协议

Posted 钢笔和椅子

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Nacos简析:distro协议相关的知识,希望对你有一定的参考价值。

一. CAP理论

  • 一致性

  • 可用性

  • 分区容错性

为什么只能三选二及在分布式场景下P一定不能被放弃?

https://blog.csdn.net/qq_28107929/article/details/106104277


  CAP文氏图 

二. CP的劣势,AP的优势

没有纯粹的CP和AP,保证了CP再尽量靠近A,保证了AP再尽量靠近C。

以RAFT为代表的“强一致性”协议(选主,复制)带来了什么劣势

保障一致性需要做的事情

  • 强一致性--->写请求来时日志复制-->主从区分-->选主服务不可用-->投票选主需要一定数量的节点-->可靠性偏低

  • 强一致性-->读请求来时请求转发-->主节点压力山大-->性能受限

如果抛弃强一致性我们可以获得什么

  • 或许无需选主

  • 主节点读写压力分摊

  • 不强制要求节点数量即可提供服务

对于服务中心来说,可用,可靠,高性能是第一,反之如果是金融,电商场景,数据一致性则更重要!


三. Distro简介

实现一个AP协议可以参考的对象很少,在nacos-distro出来之前,AP协议代表有以下

  • eureka实现的AP协议(去中心化)

  • redis-cluster高可用模式(主从复制是异步的)


nacos作为AP派注册中心的粉丝,很多实现上都借鉴了eureka,而Distro作为nacos-ap协议(同时也通过jraft实现raft用作cp,配置中心)的实现,当前仅仅也体现在nacos中开源出来,并没有单独剥离,因此只能说是注册中心的AP协议而非纯粹AP的框架,和etcd的etcd-raft定位很大不同。

Nacos简析(一):distro协议

distro在nacos中位置


四.Distro部分机制走读

distro部分组件


1. 为什么需要转发,转发到那里,如何转发?

  • 每个nacos-server类似分片的数据库,只负责部分实例信息的维护。

  • 每个nacos-server类似分片的数据库,只负责部分实例信息的维护。

 private int distroHash(String responsibleTag) { return Math.abs(responsibleTag.hashCode() % Integer.MAX_VALUE); }  
  • @CanDistro拦截,调用distroMapper的mapsrv决定转发至哪台nasoc-server,用http形式去转发获取结果。

    简单的distromapper

2.数据初始化,增量同步的基本流程

     private void load() throws Exception { while (memberManager.allMembersWithoutSelf().isEmpty()) { Loggers.DISTRO.info("[DISTRO-INIT] waiting server list init..."); TimeUnit.SECONDS.sleep(1); } while (distroComponentHolder.getDataStorageTypes().isEmpty()) { Loggers.DISTRO.info("[DISTRO-INIT] waiting distro data storage register..."); TimeUnit.SECONDS.sleep(1); } for (String each : distroComponentHolder.getDataStorageTypes()) { if (!loadCompletedMap.containsKey(each) || !loadCompletedMap.get(each)) { loadCompletedMap.put(each, loadAllDataSnapshotFromRemote(each)); } } }  private boolean loadAllDataSnapshotFromRemote(String resourceType) { DistroTransportAgent transportAgent = distroComponentHolder.findTransportAgent(resourceType); DistroDataProcessor dataProcessor = distroComponentHolder.findDataProcessor(resourceType); if (null == transportAgent || null == dataProcessor) { Loggers.DISTRO.warn("[DISTRO-INIT] Can't find component for type {}, transportAgent: {}, dataProcessor: {}", resourceType, transportAgent, dataProcessor); return false; } for (Member each : memberManager.allMembersWithoutSelf()) { try { Loggers.DISTRO.info("[DISTRO-INIT] load snapshot {} from {}", resourceType, each.getAddress()); DistroData distroData = transportAgent.getDatumSnapshot(each.getAddress()); boolean result = dataProcessor.processSnapshot(distroData); Loggers.DISTRO .info("[DISTRO-INIT] load snapshot {} from {} result: {}", resourceType, each.getAddress(), result); if (result) { return true; } } catch (Exception e) { Loggers.DISTRO.error("[DISTRO-INIT] load snapshot {} from {} failed.", resourceType, each.getAddress(), e); } } return false; }  
  • 增量同步通常在dataStore被PUT更新之后(注册实例的最后一步就会调用PUT)再主动触发,因为是异步复制,因此这里只是生成一个延迟的任务,塞入DistroTaskEngine的队列中就马上返回


     public void put(String key, Record value) throws NacosException { onPut(key, value); //... distroProtocol.sync(new DistroKey(key, KeyBuilder.INSTANCE_LIST_KEY_PREFIX), DataOperation.CHANGE, globalConfig.getTaskDispatchPeriod() / 2); } public void sync(DistroKey distroKey, DataOperation action, long delay) { for (Member each : memberManager.allMembersWithoutSelf()) { DistroKey distroKeyWithTarget = new DistroKey(distroKey.getResourceKey(), distroKey.getResourceType(), each.getAddress()); DistroDelayTask distroDelayTask = new DistroDelayTask(distroKeyWithTarget, action, delay); distroTaskEngineHolder.getDelayTaskExecuteEngine().addTask(distroKeyWithTarget, distroDelayTask); //... } } } 
  • dataStore的结构长什么样子,同步的数据又长什么样,从全量的快照数据到内存数据中经历了那些操作?

  • dataStore基于concurrentHashMap存放,其结构较为简单为String--->Datum(Key+Record泛型)

    同步的数据开始为[]byte,在Serializer中找到实现Record的class,如instance,通过jackson进行数据转化成期望对象,当前默认nacos-server之间同步的全为instance的数据,获取到数据之后,Distro中需要触发对应listeners。

    如instance,在dataStore中存放的key为Instance_LIST_PREFIX+namespaceid+serviceName,value为[]instance



以上是关于Nacos简析:distro协议的主要内容,如果未能解决你的问题,请参考以下文章

Nacos7# Distro协议增量同步

Nacos6# Distro协议全量同步与校验

nacos的一致性协议distro介绍

Nacos一致性协议 CP/AP/JRaft/Distro协议

nacos的一致性协议distro介绍

微服务Nacos ⼀致性协议