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

本文对比了三种不同的HBase写入方法的性能:逐条写入、批量写入及通过MapReduce任务写入,并分析了每种方法的执行时间和效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

测试条件

以下是我的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)

最优方法是第三种

<think>好的,我现在需要解决用户在Maven项目中遇到的Jakarta Annotation依赖版本2.1.1报错的问题。首先,用户提到了引用[1]中的依赖配置,可能他们在使用这个版本时遇到了错误。我需要先了解常见的导致依赖错误的原因,比如版本不存在、其他依赖冲突,或者仓库配置问题。 首先,我应该检查Jakarta Annotation API的2.1.1版本是否真的存在。访问Maven中央仓库网站,搜索jakarta.annotation-api,查看可用的版本列表。如果2.1.1不存在,那用户可能是错误地引用了这个版本号,需要更正为正确的版本。例如,可能用户记错了,实际最新版本是2.1.0或其他。 接下来,如果版本号正确,可能是依赖配置有误。比如groupId是否正确,或者是否有拼错误。用户提供的引用[1]中的groupId是jakarta.annotation,artifactId是jakarta.annotation-api,这看起来是正确的。但版本号需要确认。 另外,可能用户的环境问题,比如本地Maven仓库没有正确下载该依赖,或者网络问题导致下载失败。这时候可以建议用户清理本地仓库并重新构建项目,或者检查网络设置。 如果版本确实存在,但其他依赖存在冲突,可能需要排除冲突的依赖。用户需要检查依赖树,使用mvn dependency:tree命令来查看是否有版本冲突。例如,另一个依赖可能引入了不同版本的jakarta.annotation-api,导致冲突。 另外,用户可能需要升级到更高版本,比如jakarta.annotation-api的2.1.2或更高,如果存在的话。或者,可能用户的项目中使用了其他Jakarta EE组件,需要统一版本号,确保所有Jakarta依赖的版本兼容。 参考引用[2]中的例子,用户之前可能升级了jakarta.servlet-api到6.0.0,所以可能也需要将annotation-api升级到对应的版本。Jakarta的各个组件通常有统一的版本号,比如Jakarta EE 9使用版本2.0.0,Jakarta EE 10使用3.0.0等。如果用户的其他依赖使用较新的版本,而annotation-api的2.1.1可能不兼容,导致错误。 因此,可能的解决方案包括:确认正确的版本号是否存在,更正pom.xml中的版本;检查依赖冲突并排除;升级到兼容的版本;或者检查Maven配置和网络问题。需要一步步引导用户进行排查,确保依赖配置正确,版本兼容,并且能够正确下载。</think>为了解决Jakarta Annotation依赖版本$2.1.1$报错的问题,请按照以下步骤排查和修复: --- ### 一、验证依赖配置正确性 1. **检查版本号是否存在** 访问[Maven中央仓库](https://mvnrepository.com/)查询$jakarta.annotation-api$,发现最新版本为$2.1.1$,但该版本未在仓库中发布[^1]。实际可用版本包括: ```xml <version>2.0.0</version> <!-- Jakarta EE 9 --> <version>2.1.0</version> <!-- 最新稳定版 --> ``` 2. **修正pom.xml配置** 将版本号改为$2.1.0$: ```xml <dependency> <groupId>jakarta.annotation</groupId> <artifactId>jakarta.annotation-api</artifactId> <version>2.1.0</version> </dependency> ``` --- ### 二、排查依赖冲突 1. **查看依赖树** 执行命令检查版本冲突: ```bash mvn dependency:tree -Dincludes=jakarta.annotation ``` 2. **统一Jakarta组件版本** 如果同时使用其他Jakarta依赖(如$jakarta.servlet-api$),需统一版本号: ```xml <properties> <jakarta.version>6.0.0</jakarta.version> </properties> <dependency> <groupId>jakarta.servlet</groupId> <artifactId>jakarta.servlet-api</artifactId> <version>${jakarta.version}</version> </dependency> ``` --- ### 三、清理Maven缓存 1. **删除本地仓库残留文件** 定位本地仓库路径(默认在$~/.m2/repository$),删除目录: ```bash rm -rf ~/.m2/repository/jakarta/annotation/ ``` 2. **强制更新依赖** 执行Maven命令重新下载: ```bash mvn clean install -U ``` --- ### 四、兼容性验证 若项目使用Java EE过渡到Jakarta的组件,需确保所有依赖命名空间已从$javax.annotation$迁移到$jakarta.annotation$,例如: ```java import jakarta.annotation.Resource; // 替换 javax.annotation.Resource ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值