HBase在线迁移数据

本方案通过结合HBase SnapshotHBase Replication技术,在源端HBase集群不停服的情况下,实现存量数据和增量数据的在线迁移,确保迁移过程中数据无丢失。

方案介绍

HBase数据迁移过程中,传统基于Snapshot的方式仅支持离线迁移,无法满足源集群不停服的需求。由于迁移期间源端集群仍然在运行,可能会导致以下问题:

  • 增量数据丢失:在Snapshot导出和恢复的过程中,源集群产生的写入或更新操作可能无法同步到目标集群。

  • 数据一致性难以保障:单纯依赖Snapshot无法处理迁移过程中的实时增量数据。

为解决上述问题,提出以下在线迁移方案:

  1. 建立复制关系(Peer):

    • 使用HBase Replication功能,在源集群和目标集群之间建立表级别的复制关系,并暂时关闭自动同步功能。

    • 源集群会记录针对表的实时写入和变更操作,但不会立即将其同步到目标集群。

  2. 迁移存量数据:

    • 利用HBase Snapshot导出源集群的存量数据。

    • 如果源集群和目标集群的存储系统(如HDFSOSS-HDFS)互通,则直接将Snapshot导出到目标集群;否则,需先导出到源集群的中间路径,再同步到目标集群。

  3. 同步增量数据:存量数据恢复完成后,开启Replication Peer的自动同步功能,回放迁移期间产生的增量数据,确保源端和目标端的数据一致性。

通过上述步骤,本方案在保证源集群服务持续运行的同时,完整迁移存量和增量数据,避免数据丢失。

注意事项

  • HBase版本兼容性:

    • HBase 1.x版本:需设置hbase.replication=true,并重启主备集群以启用Replication功能。

    • HBase 2.x版本:默认已移除hbase.replication参数,无需额外设置。

  • Replication配置:HBase是以列族为单位设置是否启用Replication。如果需要迁移特定列族的数据,请确保相关列族已正确配置Replication属性。

  • 网络连通性:

    • 通过CEN(云企业网)、专线或VPN等方式,确保源HBase集群与目标HBase集群之间的网络互通。

    • 提前打通源集群和目标集群的网络连接,确保以下端口对源集群开放:

      • Zookeeper服务端口:目标集群Zookeeper所在ECS实例的2181端口。

      • HBase服务端口:目标集群EMR HBase所在ECS实例的160101602016030端口。

操作流程

步骤一:创建Peer(复制关系)

在源集群和目标集群之间建立表级别的复制关系,并暂时关闭自动同步功能,待完成存量Snapshot数据的同步之后再开启自动同步。

  1. 登录源集群的Master节点,详情请参见登录集群

  2. 执行以下命令,进入HBase Shell。

    hbase shell
  3. 添加Peer(复制关系)。

    HBase Shell中执行以下命令,为目标集群添加一个Peer(复制关系),并指定待迁移的表。

    add_peer '${peer_name}', CLUSTER_KEY => "${slave_zk}:${port}:/hbase", TABLE_CFS => { "${table_name}" => [] }

    涉及参数如下:

    • ${peer_name}:复制关系名称,您可以自定义。本文示例为peer1

    • ${slave_zk}:目标集群ZooKeeper的地址。通常是多个ZooKeeper节点的内网IP地址或主机名,格式为{slave_zk1}:2181,{slave_zk2}:2181,{slave_zk3}:2181

    • ${port}:目标集群ZooKeeper的端口,默认端口为2181。

    • ${table_name}:待迁移的表名。本文示例为t1

  4. 启用表级复制。

    启用表级复制功能,确保指定的表能够将写入的数据同步到目标集群。

    enable_table_replication 't1'
  5. 暂时关闭自动同步。

    该命令用于暂停指定对等体的数据复制过程。禁用后,源集群将不再向目标集群发送新的数据变更,但已有的数据不会被删除或影响。

    disable_peer 'peer1'

步骤二:创建Snapshot

在源集群的HBase Shell中,执行以下命令为待迁移的表创建Snapshot,用于导出存量数据。

snapshot '${table_name}', '${snapshot_name}'
  • 涉及参数如下:

    • ${table_name}:待迁移的表名。本文示例为t1

    • ${snapshot_name}:自定义的Snapshot名称。本文示例为t1-snapshot

  • 示例如下所示。

    snapshot 't1', 't1-snapshot'

步骤三:导出Snapshot到目标集群

场景1:源集群与目标集群的存储系统互通

如果源集群和目标集群的存储系统互通,则可以在源集群执行以下命令,直接导出Snapshot到目标集群。

hbase org.apache.hadoop.hbase.snapshot.ExportSnapshot -snapshot ${snapshot_name} -copy-to ${target_rootdir_path}
  • 涉及参数如下:

    • ${snapshot_name}:自定义的Snapshot名称。本文示例为t1-snapshot

    • ${target_rootdir_path}:目标集群HBase的根目录路径,请根据实际情况替换。

      • OSS-HDFS:您可以通过控制台,在目标集群的HBase服务中,查看hbase-site.xml文件的hbase.rootdir配置项,获取详细的路径信息。

        image

      • HDFS:您可以通过控制台,在目标集群的Hadoop-Common服务中,查看core-site.xml中的fs.defaultFS配置项,获取详细的路径信息。

  • 示例如下所示。

    hbase org.apache.hadoop.hbase.snapshot.ExportSnapshot -snapshot t1-snapshot -copy-to oss://xxx.cn-hangzhou.oss-dls.aliyuncs.com/hbase/c-9d34bc8fxxx

场景2:源集群与目标集群的存储系统不互通

如果源集群无法直接访问目标集群的存储路径,则需要先将Snapshot导出到源集群的中间路径(如HDFSOSS),然后再同步到目标集群。本文以将数据从HDFS迁移到OSS-HDFS为例。

  1. 导出Snapshot到中间路径。

    在源HBase集群中执行以下命令,将Snapshot导出到源集群的中间路径。

    hbase org.apache.hadoop.hbase.snapshot.ExportSnapshot -snapshot ${snapshot_name} -copy-to ${src_temp_path}/${table_name}
    • 涉及参数如下:

      • ${snapshot_name}:自定义的Snapshot名称。本文示例为t1-snapshot

      • ${src_temp_path}:源集群的中间路径。例如,本文源集群使用的是HDFS,则可以选择一个HDFS路径作为中间路径。

      • ${table_name}:待迁移的表名。本文示例为t1

    • 示例如下所示。

      hbase org.apache.hadoop.hbase.snapshot.ExportSnapshot -snapshot t1-snapshot -copy-to hdfs:///tmp/hbase-snapshot/t1
  2. 迁移数据到目标路径。

    执行以下命令,使用JindoDistCp工具将数据从源集群的中间路径迁移到目标集群的路径。关于JindoDistCp的更多介绍,请参见JindoDistCp使用说明

    1. EMR控制台配置OSS/OSS-HDFSAccessKey。

      Hadoop-Common服务的core-site.xml页签,新增以下配置项,以避免使用时多次填写的问题。新增配置项的具体操作,请参见管理配置项

      参数

      说明

      fs.oss.accessKeyId

      OSS/OSS-HDFSAccessKey ID。

      fs.oss.accessKeySecret

      OSS/OSS-HDFSAccessKey Secret。

    2. 在源HBase集群中,进入jindo-distcp-tool-*.jar所在的目录。

      cd /opt/apps/JINDOSDK/jindosdk-current/tools
      说明
      • EMR集群:EMR-5.6.0及以上版本、EMR-3.40.0及以上版本的集群已部署JindoDistCp,可在/opt/apps/JINDOSDK/jindosdk-current/tools目录下找到jindo-distcp-tool-*.jar

      • EMR集群:您可以自行下载JindoSDK(其中包含JindoDistCp工具),详情请参见JindoSDK下载安装和升级

    3. 执行以下命令,将Snapshot迁移至目标HBase集群。

      hadoop jar jindo-distcp-tool-*.jar --src ${src_temp_path}/${table_name} --dest ${target_temp_path}/${table_name} --disableChecksum --parallelism 10 
      • 涉及参数如下:

        • ${src_temp_path}:源集群的中间路径。

        • ${target_temp_path}:目标集群的中间路径。

        • ${target_bucket}:目标Bucket名称。

      • 示例如下所示。

        hadoop jar jindo-distcp-tool-4.6.11.jar --src hdfs:///tmp/hbase-snapshot/t1 --dest oss://hbase-test.cn-hangzhou.oss-dls.aliyuncs.com/hbase/recv/t1 --disableChecksum --parallelism 10
    4. Snapshot导入目标HBase集群。

      在目标HBase集群运行以下命令,将Snapshot从目标路径导入到HBase根目录。

      hbase org.apache.hadoop.hbase.snapshot.ExportSnapshot -snapshot ${snapshot_name} -copy-from ${target_temp_path} -copy-to ${target_rootdir_path}
      • 涉及参数如下:

        • ${target_temp_path}:目标集群的临时路径。

        • ${target_rootdir_path}:目标HBase集群的根目录路径。

          您可以通过控制台,在目标集群的HBase服务中,查看hbase-site.xml文件的hbase.rootdir配置项,获取详细的路径信息。

      • 示例如下所示。

        hbase org.apache.hadoop.hbase.snapshot.ExportSnapshot -snapshot t1-snapshot -copy-from oss://hbase-test.cn-hangzhou.oss-dls.aliyuncs.com/hbase/recv/t1 -copy-to oss://hbase-target.cn-hangzhou.oss-dls.aliyuncs.com/hbase/c-5418ce2a4xxx
  3. 检查迁移结果。

    迁移完成后,可以通过以下命令检查目标路径下的数据是否完整。

    hdfs dfs -ls ${target_rootdir_path}

步骤四:使用Snapshot恢复存量数据

  1. 登录目标集群的Master节点,详情请参见登录集群

  2. 执行以下命令,进入HBase Shell。

    hbase shell
  3. 执行以下命令,在目标集群恢复Snapshot并启用表。

    restore_snapshot '${snapshot_name}'
    enable '${table_name}'
    • 涉及参数如下:

      • ${snapshot_name}:自定义的Snapshot名称。

      • ${table_name}:待迁移的表名。

    • 示例如下所示。

      restore_snapshot 't1-snapshot'
      enable 't1'

步骤五:开启增量数据同步

在源集群的HBase Shell中执行以下命令,开启Peer同步。

enable_peer '${peer_name}'

示例如下所示。

enable_peer 'peer1'

步骤六:验证数据

验证迁移后的数据是否完整。

  • 小数据量场景:使用Scan验证。

    scan '${table_name}'

    示例如下所示。

    scan 't1'
  • 中等数据量场景:使用count验证。

    count '${table_name}'
  • 大数据量场景:使用get抽样验证。

    get '${table_name}', '${rowkey}'

    代码中的${rowkey}HBase表中每一行的唯一标识符。

步骤七:删除Snapshot

验证无误后,执行以下命令删除与目标表相关的所有快照,以释放存储空间。

delete_table_snapshots '${table_name}'

示例如下所示。

delete_table_snapshots 't1'

步骤八:清理Peer

在增量数据同步完成后,需进行应用的双写或割接操作,确保所有读写请求切换到目标HBase集群。为避免数据重复同步,在完成切换后需要删除源集群与目标集群之间的复制关系(Peer)。

  1. 客户端迁移。

    将涉及HBase集群的上下游应用切换到目标HBase集群,包括通过API或命令行读写HBase的应用。具体操作如下:

    • 更新连接配置:修改应用的配置文件或代码,将HBase连接信息(如Zookeeper地址、端口等)从源集群切换为目标集群。

    • 验证功能:确保应用能够正常读写目标集群,并进行必要的功能测试和数据校验。

    • 双跑或割接:根据业务需求,选择双跑(同时读写源和目标集群)或直接割接到目标集群。

  2. 禁用Peer的自动同步功能。

    在源集群的HBase Shell中,禁用指定Peer的自动同步功能,确保数据同步立即停止。

    disable_peer '${peer_name}'

    示例如下所示。

    disable_peer 'peer1'
  3. 删除Peer。

    禁用Peer后,删除Peer以彻底断开源集群与目标集群之间的复制关系。

    remove_peer '${peer_name}'

    示例如下所示。

    remove_peer 'peer1'
  4. 验证Peer是否删除成功。

    执行以下命令,列出当前的所有Peer,确保本文示例中的 peer1已被成功删除。

    list_peers

常见问题

为什么ExportSnapshot时报错?

在使用HBase ExportSnapshot工具迁移快照时,正确设置-copy-from-copy-to的路径是关键。如果路径配置不正确,可能会因路径解析失败而导致传输中断或任务失败。

问题原因

  • 路径格式错误:

    • 缺少协议头(如hdfs://oss://)。

    • 路径未包含完整的地址信息(例如NameNode地址或Bucket名称)。

  • 存储服务差异:不同存储服务(如HDFS、OSS-HDFS、OSS)对路径格式的要求不同。

  • 权限问题:源或目标路径的访问权限不足,导致无法读取或写入数据。

常见场景与解决方案

场景

描述

路径格式

OSS-HDFS → OSS-HDFS

在阿里云OSS-HDFS服务之间迁移快照。

  • 源路径:oss://<bucket>.<region>.oss-dls.aliyuncs.com/<path>

  • 目标路径:同源路径格式。

说明

确保路径包含完整的协议头和Bucket名称。

HDFS → HDFS

HDFS之间迁移快照。

  • 源路径:hdfs://<namenode-host>:<port>/<path>

  • 目标路径:同源路径格式。

HDFS → OSS-HDFS

HDFS迁移快照至阿里云OSS-HDFS。

  • 源路径:hdfs://<namenode-host>:<port>/<path>

  • 目标路径:oss://<bucket>.<region>.oss-dls.aliyuncs.com/<path>

OSS → OSS

在阿里云OSS之间迁移快照(标准OSS)。

  • 源路径:oss://<bucket>.oss-<region>.aliyuncs.com/<path>

  • 目标路径:同源路径格式。