Spark2.1.1<spark写入Hbase的三种方法性能对比>

测试条件

以下是我的PC信息
这里写图片描述

依赖:

<dependencies>
    <dependency>
        <groupId>org.apache.spark</groupId>
        <artifactId>spark-streaming_2.11</artifactId>
        <version>2.1.1</version>
    </dependency>
    <dependency>
        <groupId>org.apache.hbase</groupId>
        <artifactId>hbase-client</artifactId>
        <version>1.3.1</version>
    </dependency>
    <dependency>
        <groupId>org.apache.hbase</groupId>
        <artifactId>hbase-server</artifactId>
        <version>1.3.1</version>
    </dependency>
</dependencies>

1. 第一种方法
每次写进一条,调用API

  /**
   * Puts some data in the table.
   * 
   * @param put The data to put.
   * @throws IOException if a remote or network exception occurs.
   * @since 0.20.0
   */
  void put(Put put) throws IOException

我的代码

import org.apache.hadoop.hbase.{HBaseConfiguration, TableName}
import org.apache.hadoop.hbase.client.{ConnectionFactory, Put}
import org.apache.hadoop.hbase.io.ImmutableBytesWritable
import org.apache.hadoop.hbase.mapred.TableOutputFormat
import org.apache.hadoop.hbase.util.Bytes
import org.apache.hadoop.mapred.JobConf
import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.streaming.{Seconds, StreamingContext}


object Word {
  def main(args: Array[String]): Unit = {
    val sc = new SparkContext(new SparkConf().setMaster("local[2]").setAppName("hbase"))
    val rdd = sc.makeRDD(Array(1)).flatMap(_ => 0 to 1000000)
    rdd.foreachPartition(x => {
      val hbaseConf = HBaseConfiguration.create()
      hbaseConf.set("hbase.zookeeper.quorum", "172.17.11.85,172.17.11.86,172.17.11.87")
      hbaseConf.set("hbase.zookeeper.property.clientPort", "2181")
      hbaseConf.set("hbase.defaults.for.version.skip", "true")
      val hbaseConn = ConnectionFactory.createConnection(hbaseConf)
      val table = hbaseConn.getTable(TableName.valueOf("word"))
      x.foreach(value => {
        var put = new Put(Bytes.toBytes(value.toString))
        put.addColumn(Bytes.toBytes("f1"), Bytes.toBytes("c1"), Bytes.toBytes(value.toString))
        table.put(put)
      })
    })
  }
}

第一条的时间戳:1497973306787
这里写图片描述

最后一条的时间戳:1497973505273
这里写图片描述

时间戳之差1497973505273-1497973306787=198486

2.第二种方法
批量写入Hbase,使用的API:

  /**
   * {@inheritDoc}
   * @throws IOException
   */
  @Override
  public void put(final List<Put> puts) throws IOException {
    getBufferedMutator().mutate(puts);
    if (autoFlush) {
      flushCommits();
    }
  }

我的代码:

import org.apache.hadoop.hbase.{HBaseConfiguration, TableName}
import org.apache.hadoop.hbase.client.{ConnectionFactory, HTable, Put}
import org.apache.hadoop.hbase.io.ImmutableBytesWritable
import org.apache.hadoop.hbase.mapred.TableOutputFormat
import org.apache.hadoop.hbase.util.Bytes
import org.apache.hadoop.mapred.JobConf
import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.streaming.{Seconds, StreamingContext}


object Word {
  def main(args: Array[String]): Unit = {
    val sc = new SparkContext(new SparkConf().setMaster("local[2]").setAppName("hbase"))
    val rdd = sc.makeRDD(Array(1)).flatMap(_ => 0 to 1000000)
    rdd.map(value => {
      var put = new Put(Bytes.toBytes(value.toString))
      put.addColumn(Bytes.toBytes("f1"), Bytes.toBytes("c1"), Bytes.toBytes(value.toString))
      put
    }).foreachPartition(iterator => {
      var jobConf = new JobConf(HBaseConfiguration.create())
      jobConf.set("hbase.zookeeper.quorum", "172.17.11.85,172.17.11.86,172.17.11.87")
      jobConf.set("zookeeper.znode.parent", "/hbase")
      jobConf.setOutputFormat(classOf[TableOutputFormat])
      val table = new HTable(jobConf, TableName.valueOf("word"))
      import scala.collection.JavaConversions._
      table.put(seqAsJavaList(iterator.toSeq))
    })
  }
}

第一条数据的时间戳是

 0                               column=f1:c1, timestamp=1498013677545, value=0                                              
 1                               column=f1:c1, timestamp=1498013677545, value=1                                              
 10                              column=f1:c1, timestamp=1498013677545, value=10                                             
 100                             column=f1:c1, timestamp=1498013677545, value=100                                            
 1000                            column=f1:c1, timestamp=1498013677545, value=1000  

第9999条数据写进Hbase的时间戳是:

 108993                          column=f1:c1, timestamp=1498013680244, value=108993                                         
 108994                          column=f1:c1, timestamp=1498013680244, value=108994                                         
 108995                          column=f1:c1, timestamp=1498013680244, value=108995                                         
9999 row(s) in 1.2730 seconds

时间戳之差t=1498013680244-1498013677545=2699

3.第三种方法

将写进Hbase转换为Mapreduce任务

我的代码:

import org.apache.hadoop.hbase.{HBaseConfiguration, TableName}
import org.apache.hadoop.hbase.client.{ConnectionFactory, Put}
import org.apache.hadoop.hbase.io.ImmutableBytesWritable
import org.apache.hadoop.hbase.mapred.TableOutputFormat
import org.apache.hadoop.hbase.util.Bytes
import org.apache.hadoop.mapred.JobConf
import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.streaming.{Seconds, StreamingContext}


object Word {
  def main(args: Array[String]): Unit = {
    val sc = new SparkContext(new SparkConf().setMaster("local[2]").setAppName("hbase"))
    val conf = HBaseConfiguration.create()
    var jobConf = new JobConf(conf)
    jobConf.set("hbase.zookeeper.quorum", "172.17.11.85,172.17.11.86,172.17.11.87")
    jobConf.set("zookeeper.znode.parent", "/hbase")
    jobConf.set(TableOutputFormat.OUTPUT_TABLE, "word")
    jobConf.setOutputFormat(classOf[TableOutputFormat])

    val rdd = sc.makeRDD(Array(1)).flatMap(_ => 0 to 1000000)
    rdd.map(x => {
      var put = new Put(Bytes.toBytes(x.toString))
      put.addColumn(Bytes.toBytes("f1"), Bytes.toBytes("c1"), Bytes.toBytes(x.toString))
      (new ImmutableBytesWritable, put)
    }).saveAsHadoopDataset(jobConf)
  }
}

第一条的时间戳:

0                               column=f1:c1, timestamp=1498014877635, value=0    

最后一条的时间戳

 108993                          column=f1:c1, timestamp=1498014879526, value=108993                                         
 108994                          column=f1:c1, timestamp=1498014879526, value=108994                                         
 108995                          column=f1:c1, timestamp=1498014879526, value=108995  

时间戳之差t=1498014879526-1498014877635=1891

4.总结

通过以上对比可以看出,在其他条件相同的情况下
第三种方法(1498014879526-1498014877635=1891)>第二种方法(1498013680244-1498013677545=2699)>第一种方法(1497973505273-1497973306787=198486)

最优方法是第三种

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>untitled</artifactId> <version>1.0-SNAPSHOT</version> <packaging>pom</packaging> <modules> <module>first</module> <module>spring5-ioc-xml</module> <module>spring5-ioc-annotation</module> <module>spring5-reflect</module> <module>atguigu-spring</module> <module>spring6-aop</module> <module>spring6-jdbc-tx</module> </modules> <properties> <maven.compiler.source>17</maven.compiler.source> <maven.compiler.target>17</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>6.0.2</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>6.0.2</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>6.0.2</version> </dependency> <dependency> <groupId>jakarta.annotation</groupId> <artifactId>jakarta.annotation-api</artifactId> <version>2.1.1</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13.2</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifa
最新发布
04-03
<think>好的,用户想了解如何在Maven的POM文件中配置Spring项目的依赖管理。首先,我需要回忆Maven中的dependencyManagement的作用。根据引用[2],dependencyManagement用于统一管理依赖版本和范围,子模块继承时可以不用指定版本号。而引用[3]提到可以通过<scope>import</scope>来聚合多个pom的dependencyManagement,这可能在Spring Boot项目中用到。 接下来,用户需要具体的例子,可能需要展示一个典型的Spring Boot项目的父POM配置。通常Spring Boot项目会使用spring-boot-starter-parent作为父项目,或者通过dependencyManagement引入Spring Boot的BOM(Bill of Materials)。比如,在父POM的dependencyManagement中导入spring-boot-dependencies,这样所有子模块的Spring依赖就可以省略版本号。 然后,用户可能想知道如何管理不同模块的依赖,比如web、data-jpa等。需要展示如何在子模块的dependencies中添加starter依赖,比如spring-boot-starter-web,并说明由于父POM的dependencyManagement,这里不需要版本。 另外,引用[1]提到dependencies标签用于管理依赖,而dependencyManagement是集中管理版本。需要区分两者的不同,确保用户理解何时使用哪个部分。 还要注意是否需要处理多模块项目,引用[3]提到的聚合工程可能需要使用import scope来合并多个依赖管理,这在复杂项目中可能会有用。例如,如果项目同时需要Spring Cloud的依赖管理,可以通过import scope引入。 最后,确保提供的示例代码正确,符合Maven语法,并且注释清晰。同时,生成的相关问题需要涵盖用户可能进一步询问的内容,比如版本冲突解决、多模块配置等。</think>### Maven项目配置及Spring依赖管理示例 在Maven中管理Spring依赖时,通常结合`<dependencyManagement>`实现版本统一控制。以下是典型配置步骤: --- #### 1. **父POM中定义Spring Boot依赖管理** 通过`<dependencyManagement>`导入Spring Boot官方提供的BOM(Bill of Materials),自动管理所有Spring Boot相关依赖的版本: ```xml <project> <dependencyManagement> <dependencies> <!-- 引入Spring Boot官方BOM --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>3.1.0</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> </project> ``` - `<scope>import</scope>`表示继承目标POM中定义的依赖管理规则[^3] - 子模块中引用Spring依赖时**无需指定版本号** --- #### 2. **子模块添加具体依赖** 在需要Spring功能的模块中,直接声明starter依赖: ```xml <dependencies> <!-- Web模块 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- 数据访问模块 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> </dependencies> ``` --- #### 3. **多模块依赖管理(可选)** 对于需要合并多个BOM的复杂项目: ```xml <dependencyManagement> <dependencies> <!-- 同时引入Spring Cloud和Spring Boot的BOM --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>2022.0.1</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>3.1.0</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> ``` - 多个BOM的依赖版本会根据声明顺序合并 --- #### 4. **依赖范围控制示例** 通过`<scope>`定义依赖作用域: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> ``` - `test`表示该依赖仅在测试阶段有效[^2] --- ### 关键概念对比 | 配置项 | 作用域 | 特点 | |---------------------|----------------|----------------------------------------------------------------------| | `<dependencies>` | 当前模块 | 直接引入依赖,版本号必须显式声明 | | `<dependencyManagement>` | 全局管理 | 仅定义版本和范围,子模块引用时可省略版本号[^2] |
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值