Doris_数据库和湖仓一体

Doris_数据库和湖仓一体

  BE 节点
    Apache Doris 采用 MySQL 协议,高度兼容 MySQL 语法,支持标准 SQL
   存算一体架构
         Frontend (FE)  Master Follower Observer
		 Backend (BE) 数据会被切分成数据分片(Shard)
	存算分离架构
	    元数据层
		计算层
		存储层
PoC(Proof of Concept,概念验证)是一种针对客户具体应用场景或技术想法的验证性测试
    影响导入和查询性能的决策:数据模型、排序键、分区和分桶
湖上数据(即 Lakehouse 场景)
   无需数据导入,Doris 可直接访问湖仓数据
 飞轮科技(SelectDB)是 Apache Doris 的商业化公司  

Doris 湖仓一体解决方案

可扩展的连接器框架、存算分离架构、高性能的数据处理引擎和数据生态开放性
     数据目录(Catalog)、数据库(Database)、数据表(Table)三个层级
 
执行引擎: Doris 执行引擎基于 MPP 执行框架和 Pipeline 数据处理模型 
云原生:存算分离架构 
   存储系统 数据格式 
   open table format (Hive / Hudi/Delta Lake/Iceberg/ Paimon)	   
   元数据缓存 数据缓存 分区 列类型映射
   
   
   元数据缓存
      元数据包括库、表、列信息、分区信息、快照信息、文件列表等 
   数据缓存(Data Cache)通过缓存最近访问的远端存储系统(HDFS 或对象存储)的数据文件到本地磁盘上,加速后续访问相同数据的查询
     数据缓存功能仅作用于 Hive、Iceberg、Hudi、Paimon 表的查询
	 
	离线湖仓(如 Hive、Iceberg 和 Hudi) 

数据目录:

    数据目录(Data Catalog)用于描述一个数据源的属性
  		数据源的库、表、Schema、分区、数据位置
	Doris data  Catalog 
	     Internal Catalog	内置数据目录,名称固定为 internal,用于存储 Doris 内表数据
		 External Catalog	外部数据目录,指代所有 Internal Catalog 以外的数据目录
	应用场景:数据集成 数据集成 数据写回
       本质上,在 Doris 中创建的数据目录是作为“代理”
	         访问对应数据源的元数据服务(如 Hive Metastore)
			                 和存储服务(如 HDFS/S3)
    示例:
	   iceberg_catalog  hive_catalog  mysql_catalog  
     可以通过 SHOW CATALOGS 命令查看 catalog
	 SWITCH 语句用于将连接会话上下文切换到对应的数据目录
	操作: 刷新数据目录
应用:
    01. Hive Catalog
	    'type'='hms',   hms:标准的 Hive Metastore 服务
		'hive.metastore.type' = '<hive_metastore_type>', 
      通过连接 Hive Metastore,或者兼容 Hive Metatore 的元数据服务,
	      Doris 可以自动获取 Hive 的库表信息,并进行数据查询
		  (glue:使用 Hive Metastore 兼容接口访问 AWS Glue 元数据服务
		   dlf:使用 Hive Metastore 兼容接口访问阿里云 DLF 元数据服务。)
	02.1.Hudi Catalog
       Hudi Catalog 复用了 Hive Catalog。通过连接 Hive Metastore,或者兼容 Hive Metatore 的元数据服务
	   'type' = 'hms', -- required
       'hive.metastore.uris' = '<metastore_thrift_url>', -- required
	02.2:Delta Lake Catalog
	   Delta Lake Catalog 通过 Trino Connector 兼容框架,使用 Trino Delta Lake Connector 来访问 Delta Lake 表
	   Delta Lake Connector 插件
	    'type' = 'trino-connector',
        'trino.connector.name' = 'delta_lake',
        'trino.hive.metastore' = 'thrift',
    02.3.Iceberg Catalog		  
	  'type' = 'iceberg'
        Doris 支持通过多种元数据服务访问 Iceberg 表数据	
       'iceberg.catalog.type' = '<iceberg_catalog_type>',

    03.Paimon Catalog
      'type' = 'paimon',
       'paimon.catalog.type' = '<paimon_catalog_type>',
    03.2 BigQuery Catalog 
	   通过 Trino Connector 兼容框架,使用 Trino BigQuery Connector 来访问 BigQuery 表。

dataset-schema

Schema 变更主要涉及列的修改和索引的变化		   
	    轻量级 Schema Change 和重量级 Schema Change

TVF 功能 --通过parquet与duckdb建立关联

分析 S3/HDFS 上的文件 通过 Table Value Function(TVF)
     企业级的大数据分析引擎
     轻量级本地分析引擎
     TVF 的属性包括要分析的文件路径,文件格式、对象存储的连接信息等。
     其中文件路径(URI)可以使用通配符匹配多个文件,以下的文件路径都是合法的:
     
     匹配指定的文件         s3://bucket/path/to/tvf_test/test.parquet
     匹配所有 test_ 开头的文件 s3://bucket/path/to/tvf_test/test_*
     匹配所有 .parquet 后缀的文件  s3://bucket/path/to/tvf_test/*.parquet
     匹配 tvf_test目录下的所有文件  s3://bucket/path/to/tvf_test/*
     匹配文件名中包含 test的文件  s3://bucket/path/to/tvf_test/*test*		 

doris-数据类型

   ARRAY	
     不定长	由 T 类型元素组成的数组,不能作为 Key 列使用。目前支持在 Duplicate 和 Unique 模型的表中使用。		 

开发思路

 1. 写select 语句 read_json 解析json文件 
 2. 使用 create table table_nm as select * from read_json ()
 
 3. 使用Dbeaver的DDL语句,就可以生成创建表的语句,针对创建表的语句就行数据类型的修改
  	table_nm 的DDL语句,可以看出数据的取值特点

导入数据比较繁琐的情况 
    Doris 通过数据库访问的标准接口(ODBC)来访问外部表,
	  外部表省去了繁琐的数据导入工作,让 Doris 可以具有了访问各式数据库的能力,
	  并借助 Doris 本身的OLAP 的能力来解决外部表的数据分析问题:
##  Table Value Function 功能
DESC FUNCTION s3 (
    "URI" = "http://127.0.0.1:9312/test2/test.snappy.parquet",
    "s3.access_key"= "ak",
    "s3.secret_key" = "sk",
	"s3.endpoint" = "https://test.com",
	"s3.region" = "us-east-1",
    "format" = "parquet",
    "use_path_style"="true"
   );
PROPERTIES‌ 是建表语句中用于配置表级行为和存储特性的关键参数集合

 // 2. 使用 S3 Table Value Function 创建表CREATE
  CREATE TABLE
  AS SELECT cast(id as INT) as id, name, cast (age as INT) as age
  FROM s3(
      "uri" = "http://127.0.0.1:9312/test2/test.snappy.parquet",
      "s3.access_key"= "ak",
      "s3.secret_key" = "sk",
      "format" = "parquet",
      "use_path_style" = "true");

  // 3. 使用 S3 Table Value Function 插入数据
  INSERT INTO test_table (id,name,age)
  SELECT cast(id as INT) as id, name, cast (age as INT) as age
  FROM s3(	  
  说明 
   非AWS S3的自建存储,例如MinIO,强烈建议显式添加 s3.endpoint 和 s3.region 参数
    use_path_style 参数设置为 true 是正确的。对于 MinIO 这类不支持 Virtual-hosted Style 的存储系统,这个参数至关重要。

数组本身为 NULL‌ 和‌数组元素为 NULL duckdb的list相当于doris的array
   
  注意数据更新:S3外部表的数据存储在对象存储中,
   如果对象存储中的数据发生变化(如新增、修改、删除文件),S3外部表不会自动感知这些变化。
   如果需要查询最新数据,可能需要手动刷新表的元数据。
  REFRESH EXTERNAL TABLE user_behavior_s3;		 

和duckdb的关联

 将数据以Parquet格式存放在对象存储(S3、Azure Blob等)中
DuckDB 是一个嵌入式的分析型数据库,可以直接对 Parquet 等多种格式文件进行高速 SQL 查询,无需数据导入和服务器部署

开发思路

 1. 写select 语句 read_json 解析json文件 
 2. 使用 create table table_nm as select * from read_json () 
 3. 使用Dbeaver的DDL语句,就可以生成创建表的语句,针对创建表的语句就行数据类型的修改
  	table_nm 的DDL语句,可以看出数据的取值特点
	
array 定长  DOUBLE[3]  ArrayColumnWriter 继承自 ListColumnWriter
list  变长	DOUBLE[] 
duckdb将array更新为list
       ALTER TABLE your_table ALTER COLUMN your_array TYPE LIST
	   eg:
	    ALTER TABLE your_table ALTER COLUMN loati TYPE DOUBLE[] 
 S3 Parquet Export
   httpfs extension is set up and the S3 credentials are correctly configured,
   Parquet files can be written to S3 using the following command:

  COPY table_name TO 's3://s3-bucket/filename.parquet';

兼容性测试

v1.2-histrionicus/extension/parquet/column_writer.cpp
     auto &child_type = is_list ? ListType::GetChildType(type) : ArrayType::GetChildType(type);
     repeated_element.name = is_list ? "list" : "array";		 
     schema_path.emplace_back(is_list ? "list" : "array" 
v1.5-variegata/extension/parquet/writer/list_column_writer.cpp 
	 repeated_element.name = "list";
	 schemas.push_back(std::move(repeated_element))
extension/parquet/writer/array_column_writer.cpp
    
read_parquet parquet_scan
read_duckdb Function
-- Write query results to a Parquet file on Blob Storage
 COPY (SELECT * FROM my_table)
 TO 'az://my_container/path/output.parquet';
 
 extension/parquet/column_writer.cpp
 extension/parquet/writer/array_column_writer.cpp
      GetChildWriter().Write(*state.child_state, array_child, count * array_size);
 extension/parquet/writer/list_column_writer.cpp
      repeated_element.name = "list";

参考

  https://doris.apache.org/zh-CN/docs/3.x/lakehouse/catalog-overview		
  https://doris.apache.org/zh-CN/docs/3.x/lakehouse/file-analysis
  DuckDB中Parquet格式对数组类型处理的兼容性问题分析  https://blog.gitcode.com/b0bdd31ccd19a2d2c93d04e07cbdd99b.html
  数据类型  https://doris.apache.org/zh-CN/docs/3.x/table-design/data-type
  https://docs.selectdb.com/cloud/4.x/lakehouse/lakehouse-overview
posted @ 2026-04-21 15:04  辰令  阅读(11)  评论(0)    收藏  举报