我正在使用
shc-core-1.1.2-2.2-s_2.11-SNAPSHOT.jar
使用其他scala类手动构建HBaseSinkProvider(link to a github issue)我想用这个堆栈创建一种实时ETL:
以上所有内容现在都运行良好,代码就像这样(Python):
spark \
.readStream \
.format('kafka') \
.option('kafka.bootstrap.servers', 'worker01:9092,worker02:9092,worker03:9092') \
.option('subscribe', 'youdo') \
.option('group.id', 'spark') \
.option('maxOffsetsPerTrigger', 100) \
.option('startingOffsets', 'earliest') \
.load() \
.withColumn(
'decoded',
from_json(
col('value').cast('string'),
schema
)
) \
.select(
'decoded.body.*',
'timestamp'
) \
.na.fill('null') \
.writeStream \
.outputMode("append") \
.format('HBase.HBaseSinkProvider') \
.option('hbasecat', catalog) \
.option('checkpointLocation', '/tmp/checkpoint') \
.start() \
.awaitTermination()
现在我遇到一个问题,我不能保证,不同分区中的消息排列正确。我的意思是,例如,O可能在HBase中有一个对象的版本8,我可以使用版本7的另一个分区使用消息 - 在这种情况下,我不能更新HBase中的数据。
首先,我尝试使用HBase加入输入流并过滤掉版本低于HBase的行:
<...>
.select(
'decoded.body.*',
'timestamp'
) \
.join(
sqlc.read \
.format('org.apache.spark.sql.execution.datasources.hbase') \
.options(catalog=catalog_hbase) \
.load() \
.select('id', col('hbase_version').cast('integer')),
['id'],
'left'
) \
.na.fill({'hbase_version': 0}) \
.filter(col('version').cast('integer') > col('hbase_version'))
<...>
这样做我总是得到streamingQueryException: key not found: hbase_version
- 我认为这不会因为shc而起作用,它看起来像是一个不受支持的功能。
我看到的另一种方法是为每一行手动设置HBase行时间戳(我有LastUpdateDate属性和Version) - 我该怎么做?
还有其他方法吗?
生成的代码必须是Python,但编译一些jar并将它们传递给带有spark-submit的脚本是可以的。