scala - 创建 hfile 时出现 Spark 问题 - 添加了一个在词法上不大于先前单元格的键

标签 scala apache-spark hbase bulk-load

我正在尝试创建 hfiles 以批量加载到 Hbase 中,尽管一切看起来都很好,但它仍然会抛出行键错误。 我正在使用以下代码:

val df = sqlContext.read.format("com.databricks.spark.csv")
   .option("header", "true")
   .option("inferSchema", "true")
   .load("data.csv")

import sqlContext.implicits._

val DF2 = df.filter($"company".isNotNull)
  .dropDuplicates(Array("company"))
  .sortWithinPartitions("company").sort("company")

val rdd = DF2.flatMap(x => { 
  val rowKey = Bytes.toBytes(x(0).toString)
  for (i <- 0 to cols.length - 1) yield {
    val index = x.fieldIndex(new String(cols(i)))
    val value = if (x.isNullAt(index)) "".getBytes else x(index).toString.getBytes
         (new ImmutableBytesWritable(rowKey), new KeyValue(rowKey, COLUMN_FAMILY, cols(i), value))
  }
})

rdd.saveAsNewAPIHadoopFile("HDFS LOcation", classOf[ImmutableBytesWritable], classOf[KeyValue], classOf[HFileOutputFormat2], fconf)

我正在使用以下数据

company,date,open,high,low,close,volume
ABG,01-Jan-2010,11.53,11.53,11.53,11.53,0
ABM,01-Jan-2010,20.66,20.66,20.66,20.66,0
ABR,01-Jan-2010,1.99,1.99,1.99,1.99,0
ABT,01-Jan-2010,53.99,53.99,53.99,53.99,0
ABX,01-Jan-2010,39.38,39.38,39.38,39.38,0
ACC,01-Jan-2010,28.1,28.1,28.1,28.1,0
ACE,01-Jan-2010,50.4,50.4,50.4,50.4,0
ACG,01-Jan-2010,8.25,8.25,8.25,8.25,0
ADC,01-Jan-2010,27.25,27.25,27.25,27.25,0

它抛出错误为

java.io.IOException: Added a key not lexically larger than previous. Current cell = ADC/data:high/1505862570671/Put/vlen=5/seqid=0, lastCell = ADC/data:open/1505862570671/Put/vlen=5/seqid=0
    at org.apache.hadoop.hbase.io.hfile.AbstractHFileWriter.checkKey(AbstractHFileWriter.java:204)
    at org.apache.hadoop.hbase.io.hfile.HFileWriterV2.append(HFileWriterV2.java:265)
    at org.apache.hadoop.hbase.regionserver.StoreFile$Writer.append(StoreFile.java:992)
    at org.apache.hadoop.hbase.mapreduce.HFileOutputFormat2$1.write(HFileOutputFormat2.java:199)

我什至尝试对数据进行排序,但仍然抛出错误。

最佳答案

花了几个小时后我找到了解决方案,根本原因是列未排序。

由于 Hfile 需要按字典顺序排序的键值,并且在您的情况下,在编写 HFileOutputFormat2->AbstractHFileWriter 时发现添加了一个在词法上不比以前大的键。当前单元格。您已经在行级别应用了排序,一旦您对列进行排序,它也会起作用。

这里的问题有很好的解释why-hbase-keyvaluesortreducer-need-to-sort-all-keyvalue .

解决方案:

//sort columns
val cols = companyDs.columns.sorted

//Rest of the code is same

val output = companyDs.rdd.flatMap(x => {
  val rowKey = Bytes.toBytes(x(0).toString)
 val hkey = new ImmutableBytesWritable(rowKey)
  for (i <- 0 to cols.length - 1) yield {
    val index = x.fieldIndex(new String(cols(i)))
    val value = if (x.isNullAt(index)) "".getBytes else x(index).toString.getBytes
    val kv = new KeyValue(rowKey,COLUMN_FAMILY, cols(i).getBytes(),System.currentTimeMillis()+i ,x(i).toString.getBytes())
    (hkey,kv)
  }
})
output.saveAsNewAPIHadoopFile("<path>"
  , classOf[ImmutableBytesWritable], classOf[KeyValue],
  classOf[HFileOutputFormat2], config)

关于scala - 创建 hfile 时出现 Spark 问题 - 添加了一个在词法上不大于先前单元格的键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46325233/

相关文章:

apache - hadoop和hbase最新兼容版本

scala - 如何在 List[F[G[A]]] 上运行序列以获得 F[G[List[A]]]

scala - 如何使用 spark-shell 导入自己的 scala 包?

java - 重播实时收集的数据以模拟真实的流量延迟和消息排序

python - 在 Spark 中调用外部 matlab 函数

java - mongo-hadoop 连接器 :how to query data

java - HBase:/hbase/meta-region-server 节点不存在

java.lang.NoClassDefFoundError : org/apache/hadoop/conf/Configuration 错误

scala - 在 IntelliJ 中,我在哪里输入 Homebrew Scala 路径/usr/local/opt/scala/idea?

scala - 为什么 scala 的集合默认不是 'views'?