eureka和nacos注册中心缓存高并发读写比较

eureka和nacos ap模式下为了高并发读写,都在内存中修改,但是分别采用了不同的策略。nacos 使用的是CopyOnWrite思想防止并发冲突。eureka使用的是3级缓存。

注册中心支持大量provider和consumer,所以有高并发的读写。

eureka和nacos注册中心缓存高并发读写比较_第1张图片
引用一个dubbo的图,大体上nacos和eureka也是大致的逻辑。
nacos
provider向注册中心注册,将服务器相关信息写入内存。
consumer拉取,读取注册中心服务信息。

eureka为了增加读写并发,在内存中运用读写分离的思想。
读写分离的弊端就是consumer获取示例数据会慢一些,因为可能有延迟。
但是提高了并发。

nacos中注册的时候,会调用更新list列表:

/**
 * Update instance list.
 *
 * @param ips       instance list
 * @param ephemeral whether these instances are ephemeral
 */
public void updateIps(List<Instance> ips, boolean ephemeral) {
    //注册表实例信息
    //注册的时候,会更新实例信息 
    
    //先复制一下 是否是ephemeral 这个判断是否是临时还是持久,临时是AP,持久是存储到数据库cp模式。
    //赋值了一下 这个一般方法操作内存都是先复制一下,或者复制变量。
    //我感觉c++的写法习惯,害怕指针改了
    Set<Instance> toUpdateInstances = ephemeral ? ephemeralInstances : persistentInstances;
    
    //复制了一份oldmap 注册表实例信息,下面的所有操作都是更新oldmap
    HashMap<String, Instance> oldIpMap = new HashMap<>(toUpdateInstances.size());
    
    for (Instance ip : toUpdateInstances) {
        oldIpMap.put(ip.getDatumKey(), ip);
    }
    //他的更新都是oldmap
  ....
        //注册有很多种情况,
        //如果之前注册了,改了一下配置文件,需要修改实例数据,做一些比对,更新数据。
        
    
    toUpdateInstances = new HashSet<>(ips);
    //最后再赋值回来,这样更新就和读取分离出来了。
    //copy on write思想
    if (ephemeral) {
        ephemeralInstances = toUpdateInstances;
    } else {
        persistentInstances = toUpdateInstances;
    }
}

eureka server注册使用多缓存设计:
Eureka Server 注册表多级缓存设计
1)只读缓存
2)读写缓存
3)实际注册表

eureka和nacos注册中心缓存高并发读写比较_第2张图片
拉取注册表的时候:

  • 首先从ReadOnlyCacheMap里面查询缓存的注册表。
  • 若没有,就找ReadWriteCacheMap里面缓存的注册表。
  • 如果还是没有,就从内存中获取实际的注册表数据。

在注册表发生变更的时候:

  • 会在内存中更新变更的注册表数据,同时过期掉 ReadWriteCacheMap
  • 此过程不会影响ReadOnlyCacheMap提供人家的查询注册表
  • 默认每30s Eureka Server会将ReadWriteCacheMap更新到ReadOnlyCacheMap里面
  • 默认每180s Eureka Server将ReadWriteCacheMap里面数据失效
  • 下次有服务拉取注册表,又会从内存中获取最新的数据了,同时填充各级缓存。

你可能感兴趣的:(java,eureka,缓存,java)