如何自定义从Mysql到HBase的Sqoop导入序列化?

如何自定义从Mysql到HBase的Sqoop导入序列化?,mysql,serialization,import,hbase,sqoop,Mysql,Serialization,Import,Hbase,Sqoop,目前,我有一个MySql表email_历史记录,如下所示 email_address updated_date modification janet.ford@mmch.org 2014-10-20 NEW:confidence::75|NEW:sources::cif r.wagland@soton.ac.uk 2014-10-20 NEW:confidence::75|NEW:sources::cif|NEW:user::r.wagland

目前,我有一个MySql表email_历史记录,如下所示

email_address          updated_date    modification
janet.ford@mmch.org    2014-10-20      NEW:confidence::75|NEW:sources::cif
r.wagland@soton.ac.uk  2014-10-20      NEW:confidence::75|NEW:sources::cif|NEW:user::r.wagland
字段电子邮件地址和修改为VARCHAR,更新日期为date

导入到HBase时,行键需要是连接字节数组显示日期的电子邮件地址。值需要修改,但“:”需要转换为字节0x1F,“|”需要转换为字节0x1E。以下是此格式的示例

janet.ford@mmch.org\x00\x00\x01KS,\x7F\x00        column=c:v, timestamp=1423082506912, value=new\x1Fconfidence\x1F75\x1Enew\x1Fsources\x1Fcif
默认情况下,Sqoop通过将每个字段转换为其字符串表示形式,将所有值序列化为HBase,然后在目标单元格中插入该字符串的UTF-8字节


但字符串无法表示0x1E这样的字符,因此默认序列化无法满足我的要求。有谁能告诉我如何自定义序列化并将mysql表中的内容转换为所需的字节格式,从而放入HBase吗?

您可以用CHAR30表示0x1E向上箭头,用CHAR31表示0x1F向下箭头,因此,您可以提供免费查询并执行替换。这应该可以实现您想要的目标:

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 byte int posix时间戳之类的内容。。。遗憾的是,您不能这样做:所有内容都将作为字节编码的UTF8字符串导入到HBase中,但除了行键稍长一点之外,这应该不是什么大问题。如果必须使用这种精确的格式,则必须实现自己的作业,使用自定义的行键或列值序列化从MySQL读取数据并写入HBase。

REPLACE函数可以替换字符。但是如何将整个日期变量转换为字节数组呢?我仍然需要将修改后的_日期转换为字节数组。您不能,所有内容都作为字符串导入:Sqoop当前通过将每个字段转换为其字符串表示形式将所有值序列化为HBase,就像您以文本模式导入HDFS一样,然后在目标单元格中插入此字符串的UTF-8字节。只是想确保您了解如何将日期转换为字节数组。我们都知道,在JAVA中,日期可以转换为长值,然后可以转换为8个字节来表示长值。我只想将8个字节附加到行键。我知道SQOOP只支持字符串,但我们可以将8个字节转换为字符串。然后将字节的字符串表示形式传递给Sqoop。我只是不知道如何在SQL中将日期转换为long,然后转换为bytes,再转换为string。如果SQL无法转换date->long->Byte[]->string,请告诉我如何使用自定义序列化实现我自己的作业。或者给我一个教程或示例的链接。谢谢。您可以使用UNIX_TIMESTAMPupdated_date*1000将日期格式化为毫秒时间戳,问题是sqoop会将其转换为字符串表示形式,而不是将其存储为8字节长,即:1423782000000=>1423782000000=>13B,而不是\x00\x00\x01\x4B\x82\x3F\xAC\x90=>8B。理论上,您可以使用mysql HEX和UNHEX函数的组合来从以下数字生成一个8字节的UTF8字符串:CASTUNHEXLPADHEXUNIX\u TIMESTAMPupdated\u date*1000,16,0作为CHAR,但是mysql在\x00s上会有很多问题,所以。。。我不会这么做的。