dremio datastore简单说明二

以前也介绍过dremio 的datastore,目前软件版主要是基于rocksdb 的kv,对于创建会基于一个的集群角色使用不同的
dremio 实际包含了好几类的KVStoreProvider

参考KVStoreProvider实现子类

可以看到包含了local,remote,trace,noop,timed,Idempotent,Custom,尽管很多,实际上使用的还是local,noop,remote 使用的也是local
只是是通过fabric 的rpc 请求的local,其他trace,timed,Idempotent,都是一个包装,Custom 是可以自己指定位置

内部创建处理

  • 服务注册

DACDaemonModule 处理的,使用了KVStoreProviderHelper

registry.bind(
    KVStoreProvider.class,
    KVStoreProviderHelper.newKVStoreProvider(
        dacConfig,
        bootstrap,
        registry.provider(FabricService.class),
        masterEndpoint,
        bootstrapRegistry.lookup(Tracer.class)));
  • KVStoreProviderHelper 的处理

以前也简单介绍过,一些说明下

private static KVStoreProvider internalKVStoreProvider(
      DACConfig dacConfig,
      BootStrapContext bootstrap,
      Provider<FabricService> fabricService,
      Provider<NodeEndpoint> endPoint) {
    DremioConfig dremioConfig = dacConfig.getConfig();
    Map<String, Object> config = new HashMap<>();
    String thisNode = dremioConfig.getThisNode();
 
    // instantiate NoopKVStoreProvider on all non-coordinator nodes.
    boolean isCoordinator = dremioConfig.getBoolean(DremioConfig.ENABLE_COORDINATOR_BOOL);
   // 非协调节点直接使用NoopKVStoreProvider,实际上就是执行节点
    if (!isCoordinator) {
      return new NoopKVStoreProvider(
          bootstrap.getClasspathScan(), fabricService, endPoint, bootstrap.getAllocator(), config);
    }
 
    // Configure the default KVStore
    String datastoreType = System.getProperty(KVSTORE_TYPE_PROPERTY_NAME, DEFAULT_DB);
    config.put(DremioConfig.DEBUG_USE_MEMORY_STRORAGE_BOOL, dacConfig.inMemoryStorage);
    config.put(LocalKVStoreProvider.CONFIG_DISABLEOCC, "false");
    config.put(LocalKVStoreProvider.CONFIG_VALIDATEOCC, "true");
    config.put(LocalKVStoreProvider.CONFIG_TIMED, "true");
    config.put(
        LocalKVStoreProvider.CONFIG_BASEDIRECTORY,
        dremioConfig.getString(DremioConfig.DB_PATH_STRING));
    config.put(
        LocalKVStoreProvider.CONFIG_HOSTNAME,
        System.getProperty(KVSTORE_HOSTNAME_PROPERTY_NAME, thisNode));
    config.put(RemoteKVStoreProvider.HOSTNAME, thisNode);
    config.put(
        DremioConfig.REMOTE_DATASTORE_RPC_TIMEOUT_SECS,
        dremioConfig.getLong(DremioConfig.REMOTE_DATASTORE_RPC_TIMEOUT_SECS));
 
    // find the appropriate KVStoreProvider from path
    // first check for the default behavior (if services.datastore.type is set to "default")
    // if services.datastore.type is set, check ClassPath for associated KVStoreProvider type
    Class<? extends KVStoreProvider> cls = null;
    switch (datastoreType) {
     // 注意case 的处理,尽管有DEFAULT_DB,但是TEST_CLUSTER_DB 还是会处理的,此处就会判断集群的角色
      case DEFAULT_DB:
        config.put(LocalKVStoreProvider.CONFIG_HOSTNAME, thisNode);
        // fall through to TEST_CLUSTER_DB
      case TEST_CLUSTER_DB:
        boolean isMasterless = dremioConfig.isMasterlessEnabled();
        boolean isMaster =
            (!isMasterless && dremioConfig.getBoolean(DremioConfig.ENABLE_MASTER_BOOL));
        boolean needsLocalKVStore =
            (isMasterless && thisNode.equals(config.get(LocalKVStoreProvider.CONFIG_HOSTNAME)));
       // 此处会结合是协调节点,如果不是master 情况的处理,对于dremio 来说就是scale 协调节点,使用RemoteKVStoreProvider
        cls =
            (isMaster || needsLocalKVStore)
                ? LocalKVStoreProvider.class
                : RemoteKVStoreProvider.class;
        break;
 
      default:
        final ScanResult results = ClassPathScanner.fromPrescan(dremioConfig.getSabotConfig());
        final Set<Class<? extends KVStoreProvider>> classes =
            results.getImplementations(KVStoreProvider.class);
        for (Class<? extends KVStoreProvider> it : classes) {
          try {
            KVStoreProviderType anno = it.getAnnotation(KVStoreProviderType.class);
            if (anno != null && anno.type().equals(datastoreType)) {
              cls = it;
              break;
            }
          } catch (Exception e) {
            logger.info(
                String.format(
                    "Unable to find KVStoreProviderType annotation in %s during search, skipping",
                    cls.getName()));
            continue;
          }
        }
        break;
    }
 
    // not able to find a KVStoreProvider for the requested services.datastore.type
    if (cls == null) {
      throw new RuntimeException("Unable to find appropriate KVStoreProvider for " + datastoreType);
    }
   // 动态创建,注意此处传递了fabric 服务,以及协调节点的master endpoint
    return KVStoreProvider.newInstance(
        cls,
        bootstrap.getClasspathScan(),
        fabricService,
        endPoint,
        bootstrap.getAllocator(),
        config);
  }

验证

可以通过arthas 命令验证vmtool 是一个很强大的命令

  • 参考命令
vmtool --action getInstances --className com.dremio.datastore.api.KVStoreProvider  --express 'instances'
  • 执行节点

  • master 协调节点

  • scale 协调节点

参考资料

dac/backend/src/main/java/com/dremio/dac/daemon/KVStoreProviderHelper.java
dac/backend/src/main/java/com/dremio/dac/daemon/DACDaemonModule.java
dac/backend/src/main/java/com/dremio/dac/service/exec/MasterStatusListener.java

posted on 2024-04-26 08:00  荣锋亮  阅读(16)  评论(0编辑  收藏  举报

导航