使用默认时间戳将 Spark RDD 中的值放入相同的 HBase 列
Put values from Spark RDD to the same HBase column with default timestamp
我正在使用 Spark 并尝试将 RDD 写入 HBase table。
这里是示例代码:
public static void main(String[] args) {
// ... code omitted
JavaPairRDD<ImmutableBytesWritable, Put> hBasePutsRDD = rdd
.javaRDD()
.flatMapToPair(new MyFunction());
hBasePutsRDD.saveAsNewAPIHadoopDataset(job.getConfiguration());
}
private class MyFunction implements
PairFlatMapFunction<Row, ImmutableBytesWritable, Put> {
public Iterable<Tuple2<ImmutableBytesWritable, Put>> call(final Row row)
throws Exception {
List<Tuple2<ImmutableBytesWritable, Put>> puts = new ArrayList<>();
Put put = new Put(getRowKey(row));
String value = row.getAs("rddFieldName");
put.addColumn("CF".getBytes(Charset.forName("UTF-8")),
"COLUMN".getBytes(Charset.forName("UTF-8")),
value.getBytes(Charset.forName("UTF-8")));
return Collections.singletonList(
new Tuple2<>(new ImmutableBytesWritable(getRowKey(row)), put));
}
}
如果我像这样手动设置时间戳:
put.addColumn("CF".getBytes(Charset.forName("UTF-8")),
"COLUMN".getBytes(Charset.forName("UTF-8")),
manualTimestamp,
value.getBytes(Charset.forName("UTF-8")));
一切正常,我在 HBase 列 "COLUMN" 中的单元格版本与 RDD 中不同值的数量一样多。
但是如果我没有,那么只有一个cell版本。
换句话说,如果有多个 Put 对象具有相同列族和列,不同值和default时间戳,只插入一个值,省略另一个值(可能被覆盖)。
你能帮我理解它是如何工作的吗(saveAsNewAPIHadoopDataset 特别是)在这种情况下,我如何修改代码以插入值而不是手动插入时间戳。
当您不使用时间戳时,它们会被覆盖。 Hbase 需要每个值都有一个唯一的键,所以每个值的真实键是
rowkey + column family + column key + timestamp => value
当您不使用时间戳,并且它们被批量插入时,它们中的许多会获得相同的时间戳,因为 hbase 可以在同一毫秒内插入多行。因此,您需要为每个相同的列键值自定义一个时间戳。
我不明白为什么您不想使用自定义时间戳,因为您说它已经可以工作了。如果您认为它会在数据库中使用额外的 space,即使您不输入 Put 命令,hbase 也已经使用了时间戳。所以当你使用手动时间戳时没有任何变化,请使用它。
我正在使用 Spark 并尝试将 RDD 写入 HBase table。
这里是示例代码:
public static void main(String[] args) {
// ... code omitted
JavaPairRDD<ImmutableBytesWritable, Put> hBasePutsRDD = rdd
.javaRDD()
.flatMapToPair(new MyFunction());
hBasePutsRDD.saveAsNewAPIHadoopDataset(job.getConfiguration());
}
private class MyFunction implements
PairFlatMapFunction<Row, ImmutableBytesWritable, Put> {
public Iterable<Tuple2<ImmutableBytesWritable, Put>> call(final Row row)
throws Exception {
List<Tuple2<ImmutableBytesWritable, Put>> puts = new ArrayList<>();
Put put = new Put(getRowKey(row));
String value = row.getAs("rddFieldName");
put.addColumn("CF".getBytes(Charset.forName("UTF-8")),
"COLUMN".getBytes(Charset.forName("UTF-8")),
value.getBytes(Charset.forName("UTF-8")));
return Collections.singletonList(
new Tuple2<>(new ImmutableBytesWritable(getRowKey(row)), put));
}
}
如果我像这样手动设置时间戳:
put.addColumn("CF".getBytes(Charset.forName("UTF-8")),
"COLUMN".getBytes(Charset.forName("UTF-8")),
manualTimestamp,
value.getBytes(Charset.forName("UTF-8")));
一切正常,我在 HBase 列 "COLUMN" 中的单元格版本与 RDD 中不同值的数量一样多。
但是如果我没有,那么只有一个cell版本。
换句话说,如果有多个 Put 对象具有相同列族和列,不同值和default时间戳,只插入一个值,省略另一个值(可能被覆盖)。
你能帮我理解它是如何工作的吗(saveAsNewAPIHadoopDataset 特别是)在这种情况下,我如何修改代码以插入值而不是手动插入时间戳。
当您不使用时间戳时,它们会被覆盖。 Hbase 需要每个值都有一个唯一的键,所以每个值的真实键是
rowkey + column family + column key + timestamp => value
当您不使用时间戳,并且它们被批量插入时,它们中的许多会获得相同的时间戳,因为 hbase 可以在同一毫秒内插入多行。因此,您需要为每个相同的列键值自定义一个时间戳。
我不明白为什么您不想使用自定义时间戳,因为您说它已经可以工作了。如果您认为它会在数据库中使用额外的 space,即使您不输入 Put 命令,hbase 也已经使用了时间戳。所以当你使用手动时间戳时没有任何变化,请使用它。