某客户大数据测试场景为:Solr 类似画像的数据查出用户标签——通过这些标签在 HBase 查询详细信息.以上测试功能以及性能.
其中 HBase 的数据量为 500G,Solr 约 5T.数据均需要从对方的集群人工迁移到我们自己搭建的集群.由于 Solr 没有在我们集群中集成,优先开始做 HBase 的数据迁移,以下总结了 HBase 使用以及数据迁移遇到的各种问题以及解决方法.
一. 迁移过程遇到问题以及解决
客户 HBase 版本:Version 0.94.15
腾讯大数据套件 HBase 版本:Version 1.2.1
客户私有云系统版本(测试):tlinux1.2
遇到的问题以及解决过程如下:
1.HBase 运行异常现象一(date 和 hwclock)
HBase 运行偶发不正常,出现组件停止运行的情况,看日志有说时间的差异等信息,但 date 查看完全一致,想到可能是硬件时间的差异问题,通过 hwclock 看,确实差异很大,通过 hwclock -w 调整后基本恢复.后确认初始化脚本中只对腾讯云环境的机器做了硬件时间同步,目前已优化.
2.HBase 运行异常现象二(hostname 和 / etc/resolv.conf)
HBase 再次运行不正常,出现组件停止运行的情况.通过日志看如下错误
ERROR [regionserver//10.0.0.106:16020] regionserver.HRegionServer: Master passed us a different hostname to use; was=10.0.0.106, but now=host-10-0-0-106.openstacklocal
通过 hostname 看所有机器 hostname 均为内网 IP,猜想可能是网络交互的时候查询什么表导致出现的不一致,查看 dns 解析信息如下
有
[root@10 ~]# hostname
10.0.0.106
; generated by /sbin/dhclient-script
#search openstacklocal 0.0.106
#nameserver 10.0.0.2
#nameserver 10.0.0.3
search openstacklocal
的情况,猜测是虚拟机的异常行为,注释掉 resolv.conf 里相关 search 信息,停掉 nscd 服务后,重启 HBase,再未出现这个错误,HBase 运行完全正常.
3. 需要支持 snappy 的发现与修复过程:
迁移表的过程中计划使用官方的 import/export 工具进行,第一步需要在目标集群建表,通过 desc 信息在目标集群建表完成后,list 可看到表,通过 scan 查询后,无法查询内容,查日志有如下错误:
org.apache.hadoop.HBase.DoNotRetryIOException: Compression algorithm 'snappy'previously failed test.
通过 google 查询需要 HBase 支持 snappy 压缩算法,通过 hadoop checknative 发现集群默认确实不支持 snappy 算法(虽然安装 snappyrpm
通过手动建表的方法用以下 desc 信息建表后可以 list 查看到表信息.scan 无法查看表内容,日志发现如下错误
Native library checking:
hadoop: true /data/tbds-base/usr/hdp/2.2.0.0-2041/hadoop/lib/native/libhadoop.so
zlib: true /lib64/libz.so.1
snappy: false
lz4: true revision:99
bzip2: false
openssl: false build does not support openssl.
desc 信息:
错误信息:
COLUMN FAMILIES DESCRIPTION
{NAME => 'A', DATA_BLOCK_ENCODING => 'NONE', BLOOMFILTER => 'NONE', REPLICATION_SCOPE => '0', VERSIONS => '1', COMPRESSION => 'SNAPPY', MIN_VERSIONS => '0', TTL => 'FOR
EVER', KEEP_DELETED_CELLS => 'false', BLOCKSIZE => '65536', IN_MEMORY => 'false', BLOCKCACHE => 'true', METADATA => {'ENCODE_ON_DISK' => 'true'}}
{NAME => 'D', DATA_BLOCK_ENCODING => 'NONE', BLOOMFILTER => 'NONE', REPLICATION_SCOPE => '0', VERSIONS => '2147483647', COMPRESSION => 'SNAPPY', MIN_VERSIONS => '0', TT
L => 'FOREVER', KEEP_DELETED_CELLS => 'false', BLOCKSIZE => '65536', IN_MEMORY => 'false', BLOCKCACHE => 'true', ENCODE_ON_DISK => 'true'
org.apache.hadoop.HBase.DoNotRetryIOException: java.lang.RuntimeException: native snappy library not available: this version of libhadoop was built without snappy support
在 HBase-site.xml 增加属性 HBase.regionserver.codecs value 为 snappy 即可,在测试集群通过该方法,HBase 启动失败
后确认 tlinux1.2 的 hadoop 集群上支持 snappy 的方法:即需要在特定系统编译 hadoop 相关本地库(native 库)替换 hadoop 当前的 native 库,然后 HBase 的启动环境脚本增加 hadoop 主目录即可
目前 tlinux1.2 下的 hadoop 的 nativesnappy 库有现网使用,同时需要保证这个 hadoop 的库可以引用到 libjvm.so(jre 的一个 so 文件)直接替换 hadoop/lib 下的 native 目录,保证已经安装 snappy 的 rpm 包,在 HBase-env.sh 里添加
HADOOP_HOME={Hadoop安装主目录}
.再 hadoop checknative 后发现已支持 snappy.逐步全量重启 HBase.
4.HBase0.9.4 集群数据表到 HBase1.2.1 集群数据表的迁移方法
Native library checking:
hadoop: true /data/tbds-base/usr/hdp/2.2.0.0-2041/hadoop/lib/native/libhadoop.so
zlib: true /lib64/libz.so.1
snappy: true /usr/lib64/libsnappy.so.1
lz4: true revision:99
bzip2: false
openssl: false build does not support openssl.
暴力迁移参考 http://my.oschina.net/CainGao/blog/616502
1) 找到源集群源表在 hdfs 上的目录位置,直接将该目录移动到目标集群 HBase 的表在目标集群 hdfs 上的表根目录下
2) 暴力迁移时 tableinfo 信息是一个文件即. tableinfo.00000001.0.9.4 的版本这个文件位于 HBase 表在 hdfs 上表目录的根目录下,而 1.2.1 的这个文件位于 HBase 表在 hdfs 上表目录的根目录下的./tabledesc 目录下,需要手动创建这个目录并调整这个文件的位置
3) 修改复制过来的表目录文件的属主信息
4) 重启 HBase 的所有组件
5) 此时登录 HBaseshell 已经可以通过 list 查看到迁移过来的表,但 scan 等操作会失败
6) 通过 HBase hbck -fixMeta 修复 meta 信息;HBase hbck -fixAssignments 修复分区.这两个步骤的操作过程中注意观察日志是否有异常,实践中首次尝试此方法有大量错误,发现错误内容为 snappy 相关,支持 snappy 后,查看表信息,表内容正常,随机选取表内容对比也正常,可认为此种方法迁移成功.
7) 通过 import/export 的方法迁移时需要在目标集群手动创建目标表,查看源集群的表结构如下:
import/export 参考地址
通过该 desc 信息创建新表时出现如下错误:
COLUMN FAMILIES DESCRIPTION {NAME => 'A', DATA_BLOCK_ENCODING => 'NONE', BLOOMFILTER => 'NONE', REPLICATION_SCOPE => '0', VERSIONS => '1', COMPRESSION => 'SNAPPY', MIN_VERSIONS => '0', TTL => 'FOR
EVER', KEEP_DELETED_CELLS => 'false', BLOCKSIZE => '65536', IN_MEMORY => 'false', BLOCKCACHE => 'true', METADATA => {'ENCODE_ON_DISK' => 'true'}}
{NAME => 'D', DATA_BLOCK_ENCODING => 'NONE', BLOOMFILTER => 'NONE', REPLICATION_SCOPE => '0', VERSIONS => '2147483647', COMPRESSION => 'SNAPPY', MIN_VERSIONS => '0', TT
L => 'FOREVER', KEEP_DELETED_CELLS => 'false', BLOCKSIZE => '65536', IN_MEMORY => 'false', BLOCKCACHE => 'true', ENCODE_ON_DISK => 'true'
Unknown argument ignored for column family A: ENCODE_ON_DISK
手动测试只要加这个参数 ENCODE_ON_DISK 去建表一定会出现这个错误,建表会成功,但表信息里没有这个字段了.经过 look 查代码发现这个字段在新版本已经废弃,但客户的老集群是版本需要这个字段,通过 import 的方法无法正常写入,通过步骤 6)的暴力迁移成功后(暴力迁移成功兼容了这个字段),查看表的 desc 信息如下:
老集群表结构
COLUMN FAMILIES DESCRIPTION {NAME => 'A', DATA_BLOCK_ENCODING => 'NONE', BLOOMFILTER => 'NONE', REPLICATION_SCOPE => '0', VERSIONS => '1', COMPRESSION => 'SNAPPY', MIN_VERSIONS => '0', TTL => 'FOR
EVER', KEEP_DELETED_CELLS => 'false', BLOCKSIZE => '65536', IN_MEMORY => 'false', BLOCKCACHE => 'true', METADATA => {'ENCODE_ON_DISK' => 'true'}}
{NAME => 'D', DATA_BLOCK_ENCODING => 'NONE', BLOOMFILTER => 'NONE', REPLICATION_SCOPE => '0', VERSIONS => '2147483647', COMPRESSION => 'SNAPPY', MIN_VERSIONS => '0', TT
L => 'FOREVER', KEEP_DELETED_CELLS => 'false', BLOCKSIZE => '65536', IN_MEMORY => 'false', BLOCKCACHE => 'true', METADATA => {'ENCODE_ON_DISK' => 'true'}
可以看到关于 ENCODE_ON_DISK 字段在新老版本的定义方法有差异,故我们测试在新集群使用上面的 desc 信息建表后,再通过 import 方法导入到 HBase.结果依然没有数据写入,可以断定这个参数 ENCODE_ON_DISK 在 HBase1.2.1 中完全废弃,新版本采用了一个整字段来包裹这个信息.当老集群有参数时,官方 import/export 方法在 HBase0.9.8 到 HBase1.2.1 直接迁移暂时不可用.
COLUMN FAMILIES DESCRIPTION {NAME => 'A', DATA_BLOCK_ENCODING => 'NONE', BLOOMFILTER => 'NONE', REPLICATION_SCOPE => '0', VERSIONS => '1', COMPRESSION => 'SNAPPY', MIN_VERSIONS => '0', TTL => 'FOR
EVER', KEEP_DELETED_CELLS => 'false', BLOCKSIZE => '65536', IN_MEMORY => 'false', BLOCKCACHE => 'true', METADATA => {'ENCODE_ON_DISK' => 'true'}}
{NAME => 'D', DATA_BLOCK_ENCODING => 'NONE', BLOOMFILTER => 'NONE', REPLICATION_SCOPE => '0', VERSIONS => '2147483647', COMPRESSION => 'SNAPPY', MIN_VERSIONS => '0', TT
L => 'FOREVER', KEEP_DELETED_CELLS => 'false', BLOCKSIZE => '65536', IN_MEMORY => 'false', BLOCKCACHE => 'true', ENCODE_ON_DISK => 'true'
二. 后续
在 HBase0.9.8 集群上建表设置
ENCODE_ON_DISK = false
(默认为 true),在 HBase1.2.1 上不带 ENCODE_ON_DISK 建表,使用 export/import 方法迁移测试研究其他 HBase 数据跨集群(版本差异,网络不通)迁移方法.
来源: https://www.qcloud.com/developer/article/1004363