如何自定义Sqoop从Mysql导入序列化到HBase?
问题描述:
目前,我有一个MySql表“email_history”如下。如何自定义Sqoop从Mysql导入序列化到HBase?
email_address updated_date modification
[email protected] 2014-10-20 NEW:confidence::75|NEW:sources::cif
[email protected] 2014-10-20 NEW:confidence::75|NEW:sources::cif|NEW:user::r.wagland
字段“email_address”和“修改”是VARCHAR,“updated_date”是DATE。
导入HBase时,行键需要email_address连接字节数组显示日期。值需要修改,但':'需要转换为字节0x1F和'|'需要转换为字节0x1E。以下是这种格式的一个例子。
[email protected]\x00\x00\x01KS,\x7F\x00 column=c:v, timestamp=1423082506912, value=new\x1Fconfidence\x1F75\x1Enew\x1Fsources\x1Fcif
默认情况下,Sqoop序列化为HBase的所有值由每个字段转换为它的字符串表示,然后插入UTF-8字节此字符串在目标小区中的。
但是没有办法让字符串代表像0x1E这样的字符,因此默认的序列化不能满足我的要求。任何人都可以告诉我如何自定义序列化并将mysql表中的内容转换为所需的字节格式,然后放入HBase中?
答
您可以用CHAR(31)代表带有CHAR(30)和0x1F(向下箭头)的0x1E(向上箭头),因此,您可以提供免费查询并执行替换。这应该做到正是你要寻找的:
sqoop import --connect jdbc:mysql://localhost:3306/[db] \
--username [user] --password [pwd] \
--query 'SELECT CONCAT(email_address,updated_date) as id, REPLACE(REPLACE(modification,":",CHAR(31),uri),"|",CHAR(30),uri) as value FROM email_history WHERE $CONDITIONS' \
--split-by id \
--hbase-create-table --hbase-table [your_hbase_table] \
--hbase-row-key id --column-family [your_hbase_column_family]
只是在括号中相应的更换代码,并留下$CONDITIONS
为是(必须)
关于存储复合行键的日期部分byte []我认为你想把它存储为一个4字节的int(一个posix时间戳)o类似的东西......不幸的是,你不能:所有东西都将作为一个字节编码的UTF8字符串导入到HBase中,但它应该除了有更长的rowkeys之外,这不是一个大问题。如果必须具备这种确切格式,则必须实现自己的作业以从MySQL读取数据,并使用自定义序列化将行键或列值写入HBase。
REPLACE函数可以替换字符。但如何将整个DATE变量转换为字节数组?我仍然需要将modified_date转换为字节数组。 – user2690291 2015-02-12 16:50:15
你不能,一切都以字符串形式导入:https://sqoop.apache.org/docs/1.4.0-incubating/SqoopUserGuide.html#id1766141“Sqoop目前通过将每个字段转换为字符串将所有值序列化为HBase表示(就像您以文本模式导入到HDFS一样),然后将此字符串的UTF-8字节插入到目标单元格中。“ – 2015-02-12 19:31:48
只是想确保你知道如何将日期转换为字节数组。我们都知道在JAVA中Date可以转换为Long值,那么它可以转换为8个字节来表示Long值。我只想将8个字节附加到行键上。我明白SQOOP只支持字符串,但我们可以将8个字节转换为一个字符串。然后将字节的字符串表示传递给Sqoop。我只是不知道如何将日期转换为长字节然后再转换为SQL中的字符串。 – user2690291 2015-02-12 21:31:13