数据湖之iceberg系列(四)iceberg-spark编程

1 创建maven项目 添加依赖
<properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <scala.version>2.12.12</scala.version>
        <spark.version>3.0.0</spark.version>
        <hadoop.version>3.1.1</hadoop.version>
        <encoding>UTF-8</encoding>
    </properties>
 
    <dependencies>
        <!-- 导入scala的依赖 -->
        <dependency>
            <groupId>org.scala-lang</groupId>
            <artifactId>scala-library</artifactId>
            <version>${scala.version}</version>
        </dependency>
 
        <!-- 导入spark的依赖 -->
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-core_2.12</artifactId>
            <version>${spark.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-sql_2.12</artifactId>
            <version>${spark.version}</version>
        </dependency>
 
        <!--JDBC驱动包-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.48</version>
        </dependency>
 
        <!--hive-->
    <!--    <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-hive_2.12</artifactId>
            <version>${spark.version}</version>
        </dependency>-->
 
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.62</version>
        </dependency>
        <dependency>
            <groupId>c3p0</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.1.2</version>
        </dependency>
 
 
        <dependency>
            <groupId>org.apache.iceberg</groupId>
            <artifactId>iceberg-core</artifactId>
            <version>0.10.0</version>
        </dependency>
 
        <!-- https://mvnrepository.com/artifact/org.apache.iceberg/iceberg-spark3-runtime -->
        <dependency>
            <groupId>org.apache.iceberg</groupId>
            <artifactId>iceberg-spark3-runtime</artifactId>
            <version>0.10.0</version>
        </dependency>
 
        <!-- https://mvnrepository.com/artifact/org.apache.avro/avro -->
        <dependency>
            <groupId>org.apache.avro</groupId>
            <artifactId>avro</artifactId>
            <version>1.9.0</version>
        </dependency>
    </dependencies>
 
    <build>
        <plugins>
            <!-- 指定编译java的插件 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.5.1</version>
            </plugin>
            <!-- 指定编译scala的插件 -->
            <plugin>
                <groupId>net.alchim31.maven</groupId>
                <artifactId>scala-maven-plugin</artifactId>
                <version>3.2.2</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>testCompile</goal>
                        </goals>
                        <configuration>
                            <args>
                                <arg>-dependencyfile</arg>
                                <arg>${project.build.directory}/.scala_dependencies</arg>
                            </args>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
 
        </plugins>
    </build>
2 加载已经存在的表数据
加载Hadoop表中的数据 

 /**
     * 1 添加个iceberg操作有关的依赖
     * 2  获取spark对象
     * 3  定义对应的(catalog)数据源
     * type: 支持 hadoop  会将目录和数据源信息存储在HDFS上
     */
    val spark = SparkSession.builder()
      .config("spark.sql.catalog.hadoop_prod.type", "hadoop") // 设置数据源类别为hadoop
      .config("spark.sql.catalog.hadoop_prod", classOf[SparkCatalog].getName)
      // 指定Hadoop数据源的根目录
      .config("spark.sql.catalog.hadoop_prod.warehouse", "hdfs://linux01:8020//doit/iceberg/warehouse/") // 设置数据源位置
      .appName(this.getClass.getSimpleName)
      .master("local[*]")
      .getOrCreate()
       // 加载指定的表 , 并展示所有的数据 , 这个表是已经存在的
       spark.read.format("iceberg").table("hadoop_prod.default.tb_test1").show()
    spark.close()
3  创建一张表
private def createTable = {
    val spark = SparkSession.builder()
      // 指定Hadoop数据源的根目录
      .appName(this.getClass.getSimpleName)
      .master("local[*]")
      .getOrCreate()
    val conf = new Configuration
    val warehousePath = "hdfs://linux01:8020//doit/iceberg/warehouse/"
    // 使用hadoop的catalog
    val catalog = new HadoopCatalog(conf, warehousePath)
    import org.apache.iceberg.catalog.TableIdentifier
    // 参数一  数据库   参数二 表
    val name: TableIdentifier = TableIdentifier.of("logging", "tb_user")
    val schema = new Schema(
      Types.NestedField.required(1, "id", Types.StringType.get()),
      Types.NestedField.required(2, "name", Types.StringType.get()),
      Types.NestedField.required(3, "age", Types.IntegerType.get()),
    );
    // 创建表
    catalog.createTable(name, schema, null)
 
    spark.close()
  }
 根据加载的数据创建表

   val spark = SparkSession.builder()
      .config("spark.sql.catalog.hadoop_prod.type", "hadoop") // 设置数据源类别为hadoop
      .config("spark.sql.catalog.hadoop_prod", classOf[SparkCatalog].getName)
      // 指定Hadoop数据源的根目录
      .config("spark.sql.catalog.hadoop_prod.warehouse", "hdfs://linux01:8020//doit/iceberg/warehouse/") // 设置数据源位置
      .appName(this.getClass.getSimpleName)
      .master("local[*]")
      .getOrCreate()
    // 读取数据 生成DF
    val schema = new StructType()
      .add("id", DataTypes.IntegerType, false)
      .add("name", DataTypes.StringType, false)
      .add("age", DataTypes.IntegerType, false)
    val df: DataFrame = spark.read.schema(schema).csv("hdfs://linux01:8020/log/")
    // 第一次插入数据使用 replace()  以后再插入数据使用 append
    df.writeTo("hadoop_prod.logging.tb_user3").create()
    spark.close()
创建分区表和指定数据存储格式 

val spark = SparkSession.builder()
      .config("spark.sql.catalog.hadoop_prod.type", "hadoop") // 设置数据源类别为hadoop
      .config("spark.sql.catalog.hadoop_prod", classOf[SparkCatalog].getName)
      // 指定Hadoop数据源的根目录
      .config("spark.sql.catalog.hadoop_prod.warehouse", "hdfs://linux01:8020//doit/iceberg/warehouse/") // 设置数据源位置
      .appName(this.getClass.getSimpleName)
      .master("local[*]")
      .getOrCreate()
    // 读取数据 生成DF
    val schema = new StructType()
      .add("id", DataTypes.IntegerType, false)
      .add("name", DataTypes.StringType, false)
      .add("age", DataTypes.IntegerType, false)
    val df: DataFrame = spark.read.schema(schema).csv("hdfs://linux01:8020/log/")
    // 第一次插入数据使用 replace()  以后再插入数据使用 append
     import spark.implicits._
    // 创建一张表 ,指定数据的存储格式和分区
    df.writeTo("hadoop_prod.logging.tb_user5")
      .tableProperty("write.format.default", "orc")
      .partitionedBy('name)
      .create
    spark.close()

4 列举出所有名称空间下的表
  private def listTables = {
    val conf = new Configuration
    val warehousePath = "hdfs://linux01:8020//doit/iceberg/warehouse/"
    // 使用hadoop的catalog
    val catalog = new HadoopCatalog(conf, warehousePath)
    val namespace: Namespace = Namespace.of("logging")
    val identifiers: util.List[TableIdentifier] = catalog.listTables(namespace)
    val value: util.Iterator[TableIdentifier] = identifiers.iterator()
    // 遍历所有的表
    while (value.hasNext) {
      println(value.next().name())
    }
  }
5 创建名称空间和列出系统中所有的数据库 
private def createNameSpaceAndList = {
    val conf = new Configuration
    val warehousePath = "hdfs://linux01:8020//doit/iceberg/warehouse/"
    // 创建一个catalog
    val catalog = new HadoopCatalog(conf, warehousePath)
    // 创建一个名称空间  也就是数据库
    catalog.createNamespace(Namespace.of("db1"))
    //列举出当前所有的数据库
    val namespaces: util.List[Namespace] = catalog.listNamespaces()
    // 遍历所有的数据库打印结果
    val iters: util.Iterator[Namespace] = namespaces.iterator()
    while (iters.hasNext) {
      val namespace: Namespace = iters.next()
      println(namespace.toString)
    }
  }
6 读取静态数据向iceberg表中插入数据
 private def insertIntoDataToHadoopCatalogTable = {
    val spark = SparkSession.builder()
      .config("spark.sql.catalog.hadoop_prod.type", "hadoop") // 设置数据源类别为hadoop
      .config("spark.sql.catalog.hadoop_prod", classOf[SparkCatalog].getName)
      // 指定Hadoop数据源的根目录
      .config("spark.sql.catalog.hadoop_prod.warehouse", "hdfs://linux01:8020//doit/iceberg/warehouse/") // 设置数据源位置
      .appName(this.getClass.getSimpleName)
      .master("local[*]")
      .getOrCreate()
    // 读取数据 生成DF
    val schema = new StructType()
      .add("id", DataTypes.IntegerType, false)
      .add("name", DataTypes.StringType, false)
      .add("age", DataTypes.IntegerType, false)
    val df: DataFrame = spark.read.schema(schema).csv("hdfs://linux01:8020/log/")
    // 第一次插入数据使用 replace()  以后再插入数据使用 append
    df.writeTo("hadoop_prod.logging.tb_user2").append()
    spark.close()
  }
7 读取hadoop类型的iceberg表数据
 private def readHadoopCatalogData = {
    val spark = SparkSession.builder()
      .config("spark.sql.catalog.hadoop_prod.type", "hadoop") // 设置数据源类别为hadoop
      .config("spark.sql.catalog.hadoop_prod", classOf[SparkCatalog].getName)
      // 指定Hadoop数据源的根目录
      .config("spark.sql.catalog.hadoop_prod.warehouse", "hdfs://linux01:8020//doit/iceberg/warehouse/") // 设置数据源位置
      .appName(this.getClass.getSimpleName)
      .master("local[*]")
      .getOrCreate()
    // 加载hadoop指定表目录下的表数据
    val df: DataFrame = spark.read.format("iceberg").load("hdfs://linux01:8020//doit/iceberg/warehouse/logging/tb_user2")
    // 打印表结构
    df.printSchema()
    // 展示数据
    df.show()
    // 使用SQL方式查询数据 
    df.createTempView("tb_user2")
    spark.sql("select * from tb_user2").show()
    spark.close()
  }
 
————————————————
版权声明:本文为CSDN博主「白眼黑刺猬」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_37933018/article/details/110483423

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值