首页 > 其他分享 >dremio datastore简单说明

dremio datastore简单说明

时间:2023-01-04 12:02:12浏览次数:49  
标签:dremio LocalKVStoreProvider 简单 put datastore config class

datastore 实际上是进行数据存储的实现(主要是配置以及元数据相关的)不少服务都使用到了此功能(namespace,catalog,user,job )
实际上dremio 官方对于dremio 的部署(软件版,尤其是是社区版)有比较明确的说明,需要zk 以及本地存储(或者nas)对于协调节点
的元数据进行存储,同时如果需要实现ha 模式,可以支持对于协调节点配置主从抢占模式,从节点可以进行数据查询处理,但是不进行
元数据操作(比如比较典型的反射处理,元数据刷新。。。。),通过基本的阅读datastore

datastore 提供的能力

  • key,value 存储
  • key,value 序列化,反序列化处理,当然部分上就有了protobuf
  • 索引能力提供,这部分实际上应该是加速key,value 检索的,实现上基于了lucene,同时自己包装了,实际上我们实际使用的kv存储,基本都会包含存储以及索引
  • rpc 能力,提供通用rpc 包装,方便不通client 使用DatastoreRpcService,DatastoreRpcClient,rpc 整体是基于FabricProtocol 协议的,dremio 通用的rpc 处理

参加实现图

从下图可以看出面向不同场景实现的还是不少的

 

 

KVStoreProviderHelper 对于kv 存储的初始化

KVStoreProviderHelper 包含了不少判断,基于系统配置 ,以及基于动态类创建机制,在DACDaemonModule 模块中

 
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);
    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) {
      // 默认因为就没有配置KVSTORE_TYPE_PROPERTY_NAME 的定义,所以就只能是本地LocalKVStoreProvider 的
      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)));
        cls = (isMaster || needsLocalKVStore)? LocalKVStoreProvider.class : RemoteKVStoreProvider.class;
        break;
 
      default:
       // 基于ClassPathScanner 查找实现,所以我们可以自己扩展
        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);
    }
 
    try {
      // 动态创建KVStoreProvider 的定义
      final Constructor<? extends KVStoreProvider> con = cls.getDeclaredConstructor(
        ScanResult.class,
        Provider.class,
        Provider.class,
        BufferAllocator.class,
        Map.class
      );
 
      return con.newInstance(bootstrap.getClasspathScan(),
                             fabricService,
                             endPoint,
                             bootstrap.getAllocator(),
                             config
      );
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }

历史遗留问题

从官方代码上可以看出,官方包含了一个遗留实现,具体通过的了一个adapter 进行适配解决
DACDaemonModule 参考

 
 registry.bind(
      LegacyKVStoreProvider.class,
      new LegacyKVStoreProviderAdapter(
        registry.provider(KVStoreProvider.class).get()) // i此处就使用到了上边的初始化定义了
    );

说明

以上只是一个简单的说明,具体会通过namespaceservice 以及其他模块进行集成说明,关于datastore服务的一些配置实际上官方文档并没有介绍
但是通过学习源码,我们可以了解一些内部处理,方便自己扩展以及研究

参考资料

dac/backend/src/main/java/com/dremio/dac/daemon/KVStoreProviderHelper.java
services/datastore/src/main/java/com/dremio/datastore/RemoteKVStoreProvider.java
services/datastore/src/main/java/com/dremio/datastore/DatastoreRpcClient.java
services/datastore/src/main/java/com/dremio/datastore/DatastoreRpcService.java

标签:dremio,LocalKVStoreProvider,简单,put,datastore,config,class
From: https://www.cnblogs.com/rongfengliang/p/17024437.html

相关文章

  • Linux环境下java环境变量配置简单说明
    第一步:到jdk包的路径下tar-xvfjdk-8u121-linux-x64.tar.gz-C/usr/lib/jvm第二步:cd/usr/lib/jvmls-ls查看下 第三步:配置环境变量vim/etc/profile按键i进入插入......
  • CSV:简单格式下隐藏的那些坑
    摘要:本文将盘点处理CSV数据时我遇到的一些坑。本文分享自华为云社区《CSV—简单格式下隐藏的那些坑》,作者:aKi。前言CSV(Comma-SeparatedValues),是一种通用的、相对简单的......
  • go time的定时器简单总结
    go的标准库中的time包为我们提供了多个定时器的接口,总共分为以下几个:time.After,到了给定的duration的时间时,返回可读chan,也不会阻止程序运行,相当于一个消息通知time.Sle......
  • 工厂模式C++实现 (内附简单源码实现)
    抽象工厂模式为什么要用抽象工厂模式?*举个实际应用的例子,一个显示器电路板厂商,旗下的显示器电路板种类有非液晶的和液晶的;这个时候,厂商建造两个工厂,工厂A负责生产非......
  • CyclicBarrier简单使用
    CyclicBarrier就是要实现有福同享有难同当的原理,吃饭的时候,要等室友都到了才会一起去吃食堂,吃饭食堂一起去教室     每一阶段完成后,才会开始下一阶段代码部分......
  • nginx-clojure 调试简单试用
    对于nginx-clojure的调试实际上就是基于jdwp参考配置nginx.confjvm_options"-agentlib:jdwp=transport=dt_socket,address=*:909#{pno},server=y,suspend=......
  • kubernetes简单使用教程(一)
    一、命名空间作用:用来隔离资源添加删除命名空间[root@k8s-master01~]#kubectlcreatenshellonamespace/hellocreated[root@k8s-master01~]#kubectlgetnsNAME......
  • dremio 表函数简单说明
    dremio对于表函数的处理实际上还是基于了apcahecalcite,只是对于dremio来说,使用相对不是很多目前dremio比较多的就是外部查询,还有就是关于iceberg的一些支持函数参......
  • redis的简单理解
       redis的作用1做缓存存储数据2做锁分布式锁3可以作为缓存数据库和计算等用途  redis的持久化方案RDB(默认) 和AOF rdb保存某个时间节点的全部快照 根......
  • 最最最简单使用Docker部署Wordpress
    普通Docker部署这种方式我用过,但是总体来说是比较麻烦的。但是可以简单说一下流程,总体流程如下:安装Docker环境拉取Wordpress镜像,运行镜像拉取MySql镜像,运行镜像Wordp......