复制(在上一篇博客文章中介绍)已经发布了一段时间,并且是Apache HBase最常用的功能之一。使集群与不同的对等方复制数据是非常常见的部署,无论是作为DR策略还是简单地作为在生产/临时/开发环境之间复制数据的无缝方式。尽管这是使不同的HBase数据库在亚秒级延迟内保持同步的有效方法,但是复制仅对启用该功能后所摄取的数据进行操作。这意味着复制部署中涉及的所有集群上的所有现有数据仍将需要以其他某种方式在同级之间进行复制。有很多工具可用于同步不同对等集群上的现有数据。Snapshots、BulkLoad、CopyTable是此类工具的知名示例,以前的Cloudera博客文章中都提到了这些示例。HashTable/SyncTable,详细介绍了它的一些内部实现逻辑,使用它的利弊以及如何与上述其他数据复制技术进行比较。
HashTable/SyncTable简介
HashTable/SyncTable是一种工具,实现为两个作为单独步骤执行的map-reduce作业。它看起来类似于CopyTable工具,该工具可以执行部分或全部表数据复制。与CopyTable不同,它仅在目标集群之间复制分散的数据,从而在复制过程中节省了网络和计算资源。
该过程中要执行的第一步是HashTable Map-Reduce作业。这应在其数据应复制到远程对等方(通常是源集群)的集群上运行。下面显示了如何运行它的快速示例,本文稍后将给出每个必需参数的详细说明:
代码语言:javascript复制hbase org.apache.hadoop.hbase.mapreduce.HashTable --families=cf my-table /hashes/test-tbl
…
20/04/28 05:05:48 INFO mapreduce.Job: map 100% reduce 100%
20/04/28 05:05:49 INFO mapreduce.Job: Job job_1587986840019_0001 completed successfully
20/04/28 05:05:49 INFO mapreduce.Job: Counters: 68
…
File Input Format Counters
Bytes Read=0
File Output Format Counters
Bytes Written=6811788
一旦HashTable的上述命令作业执行完成,已经在源HDFS已经产生了一些输出hdfs 的/hashes/my-table 的表目录:
代码语言:javascript复制hdfs dfs -ls -R /hashes/test-tbl
drwxr-xr-x - root supergroup 0 2020-04-28 05:05 /hashes/test-tbl/hashes
-rw-r--r-- 2 root supergroup 0 2020-04-28 05:05 /hashes/test-tbl/hashes/_SUCCESS
drwxr-xr-x - root supergroup 0 2020-04-28 05:05 /hashes/test-tbl/hashes/part-r-00000
-rw-r--r-- 2 root supergroup 6790909 2020-04-28 05:05 /hashes/test-tbl/hashes/part-r-00000/data
-rw-r--r-- 2 root supergroup 20879 2020-04-28 05:05 /hashes/test-tbl/hashes/part-r-00000/index
-rw-r--r-- 2 root supergroup 99 2020-04-28 05:04 /hashes/test-tbl/manifest
-rw-r--r-- 2 root supergroup 153 2020-04-28 05:04 /hashes/test-tbl/partitions
需要这些作为SyncTable运行的输入。SyncTable必须在目标对等方启动。下面的命令为上一个示例中的HashTable的输出运行SyncTable 。它使用本文稍后说明的dryrun选项:
代码语言:javascript复制hbase org.apache.hadoop.hbase.mapreduce.SyncTable --dryrun --sourcezkcluster=zk1.example.com,zk2.example.com,zk3.example.com:2181:/hbase hdfs://source-cluster-active-nn/hashes/test-tbl test-tbl test-tbl
…
org.apache.hadoop.hbase.mapreduce.SyncTable$SyncMapper$Counter
BATCHES=97148
HASHES_MATCHED=97146
HASHES_NOT_MATCHED=2
MATCHINGCELLS=17
MATCHINGROWS=2
RANGESNOTMATCHED=2
ROWSWITHDIFFS=2
SOURCEMISSINGCELLS=1
TARGETMISSINGCELLS=1
作为快速参考,您可以仅将两个示例中的给定参数替换为实际环境值。本文的其余部分将更深入地介绍实现细节。
为什么要两个不同的步骤?
该工具的主要目标是仅识别和复制两个集群之间丢失的数据。HashTable充当分片/索引工作,分析表数据的批处理,并为每个批处理生成哈希索引。这些是作为作业参数之一传递的hdfs 的/hashes/my-table目录下文件中写入的输出。如前所述,SyncTable作业需要此输出。SyncTable以与HashTable使用的批处理大小相同的本地大小在本地扫描目标表,并使用HashTable使用的相同函数为这些批处理计算哈希值。然后比较本地批处理哈希HashTable输出中的值之一。如果哈希值相等,则意味着在两个集群中整个批次是相同的,并且不需要在该段上复制任何内容。否则,它将对源集群中的批次打开扫描,检查目标集群中是否已存在每个单元,仅复制那些有差异的单元。在稀疏,略有不同的数据集上,这将导致在两个集群之间复制的数据少得多。它还将仅需要在源中扫描少量的单元以检查不匹配。
必要参数
HashTable仅需要两个参数:表名称和将在其中写入相关哈希和其他元信息文件的输出路径。SyncTable使用HashTable输出目录作为输入,并分别使用源集群和目标集群中的表名称。由于我们使用HashTable/SyncTable在远程集群之间移动数据,因此必须为SyncTable定义sourcezkcluster选项。这应该是源集群的Zookeeper仲裁地址。在本文的示例中,我们还直接引用了源集群活动namenode地址,以便SyncTable将直接从源集群读取哈希输出文件。或者,可以将HashTable输出手动从源集群复制到远程集群(例如,使用distcp)。
注意:仅从CDH 6.2.1起才支持在不同kerberos领域下使用远程集群。
高级选项
这两个哈希表和SyncTable提供可调节以获得最佳效果额外的可选选项。
HashTable允许分别通过行键和修改时间(分别具有startrow/starttime,stoprow/stoptime属性)来过滤数据。数据集范围也可以受版本和列簇属性限制。所述BATCHSIZE属性定义了将被散列各部分的尺寸。这直接影响同步性能。在不匹配的情况很少的情况下,将较大的批处理值设置为更高的性能可能会导致数据集的较大部分被忽略,而无需通过SyncTable进行扫描。
SyncTable提供了dryrun选项,该选项允许预览要在目标中应用的更改。
SyncTable的默认行为是在目标端镜像源数据,因此目标中存在但源中不存在的任何其他单元最终都会在目标端被删除。在Active-Active复制设置下同步集群时,这可能是不希望的,在这种情况下,可以将doDeletes选项设置为false,从而跳过目标上删除的复制。对于不应将其他单元插入目标集群的情况,也有一个类似的doPuts标志。
输出分析
HashTable输出一些带有SyncTable的元信息的文件,但是这些文件不可读。它不会对现有数据执行任何更改,因此相关信息对于用户上下文几乎没有兴趣。
SyncTable是真正将修改应用到目标上的步骤,在实际更改目标集群数据之前,请先查看其摘要,这一点很重要(请参见上述dryrun选项)。它在映射的末尾发布一些相关的计数器以Reduce执行。查看上例中的值,我们可以看到有哈希的97148个分区(由BATCHES计数器报告),SyncTable仅检测到其中两个分区的差异(根据HASHES_MATCHED和HASHES_NOT_MACTHED计数器)。另外,内两个分区具有不同的散列, 17个单元在2行中是匹配的(分别由MATCHING_CELLS和MATCHING_ROWS报告),但是在这两个分区上也有2行是分歧的(根据RANGESNOTMATCHED和ROWSWITHDIFFS)。最后,SOURCEMISSINGCELLS和TARGETMISSINGCELLS会详细告诉我们单元仅存在于源集群还是目标集群上。在此示例中,源集群具有不在目标上的一个单元,但是目标也具有不在源上的单元。由于SyncTable是在未指定dryrun选项并将doDeletes选项设置为false的情况下运行的,作业已删除目标集群中的多余单元,并将源中找到的多余单元添加到了目标集群。假设在两个集群上均未发生写操作,则随后在目标集群中运行完全相同的SyncTable命令将不会显示任何差异:
代码语言:javascript复制hbase org.apache.hadoop.hbase.mapreduce.SyncTable --sourcezkcluster=zk1.example.com,zk2.example.com,zk3.example.com:2181:/hbase hdfs://nn:9000/hashes/test-tbl test-tbl test-tbl
…
org.apache.hadoop.hbase.mapreduce.SyncTable$SyncMapper$Counter
BATCHES=97148
HASHES_MATCHED=97148
…
适用场景
数据同步
乍一看,HashTable/SyncTable似乎与CopyTable工具重叠,但是在某些特定情况下,这两种工具都更适合。作为第一个比较示例,使用HashTable/SyncTable初始化包含100,004行且总数据大小为5.17GB的表的初始加载仅需几分钟即可完成SyncTable :
代码语言:javascript复制...
20/04/29 03:48:00 INFO mapreduce.Job: Running job: job_1587985272792_0011
20/04/29 03:48:09 INFO mapreduce.Job: Job job_1587985272792_0011 running in uber mode : false
20/04/29 03:48:09 INFO mapreduce.Job: map 0% reduce 0%
20/04/29 03:54:08 INFO mapreduce.Job: map 100% reduce 0%
20/04/29 03:54:09 INFO mapreduce.Job: Job job_1587985272792_0011 completed successfully
…
org.apache.hadoop.hbase.mapreduce.SyncTable$SyncMapper$Counter
BATCHES=97148
EMPTY_BATCHES=97148
HASHES_NOT_MATCHED=97148
RANGESNOTMATCHED=97148
ROWSWITHDIFFS=100004
TARGETMISSINGCELLS=749589
TARGETMISSINGROWS=100004
即使在如此小的数据集上,CopyTable的执行速度也更快(大约3分钟,而SyncTable则需要6分钟才能复制整个数据集):
代码语言:javascript复制...
20/04/29 05:12:07 INFO mapreduce.Job: Running job: job_1587986840019_0005
20/04/29 05:12:24 INFO mapreduce.Job: Job job_1587986840019_0005 running in uber mode : false
20/04/29 05:12:24 INFO mapreduce.Job: map 0% reduce 0%
20/04/29 05:13:16 INFO mapreduce.Job: map 25% reduce 0%
20/04/29 05:13:49 INFO mapreduce.Job: map 50% reduce 0%
20/04/29 05:14:37 INFO mapreduce.Job: map 75% reduce 0%
20/04/29 05:15:14 INFO mapreduce.Job: map 100% reduce 0%
20/04/29 05:15:14 INFO mapreduce.Job: Job job_1587986840019_0005 completed successfully
…
HBase Counters
BYTES_IN_REMOTE_RESULTS=2787236791
BYTES_IN_RESULTS=5549784428
MILLIS_BETWEEN_NEXTS=130808
NOT_SERVING_REGION_EXCEPTION=0
NUM_SCANNER_RESTARTS=0
NUM_SCAN_RESULTS_STALE=0
REGIONS_SCANNED=4
REMOTE_RPC_CALLS=1334
REMOTE_RPC_RETRIES=0
ROWS_FILTERED=0
ROWS_SCANNED=100004
RPC_CALLS=2657
RPC_RETRIES=0
现在,让我们再次使用这两种工具来处理数据集上的稀疏差异。所有这些示例上使用的test-tbl表在源集群中具有四个区域。在上一示例中将所有原始数据集复制到目标集群之后,我们仅在源端添加了四行,每个现有区域都添加了一行,然后再次运行HashTable/SyncTable以同步两个集群:
代码语言:javascript复制20/04/29 05:29:23 INFO mapreduce.Job: Running job: job_1587985272792_0013
20/04/29 05:29:39 INFO mapreduce.Job: Job job_1587985272792_0013 running in uber mode : false
20/04/29 05:29:39 INFO mapreduce.Job: map 0% reduce 0%
20/04/29 05:29:53 INFO mapreduce.Job: map 50% reduce 0%
20/04/29 05:30:42 INFO mapreduce.Job: map 100% reduce 0%
20/04/29 05:30:42 INFO mapreduce.Job: Job job_1587985272792_0013 completed successfully
…
org.apache.hadoop.hbase.mapreduce.SyncTable$SyncMapper$Counter
BATCHES=97148
HASHES_MATCHED=97144
HASHES_NOT_MATCHED=4
MATCHINGCELLS=42
MATCHINGROWS=5
RANGESNOTMATCHED=4
ROWSWITHDIFFS=4
TARGETMISSINGCELLS=4
TARGETMISSINGROWS=4
我们可以看到,只有四个分区不匹配,SyncTable的速度要快得多(大约需要一分钟才能完成)。使用CopyTable执行相同的同步显示以下结果:
代码语言:javascript复制20/04/29 08:32:38 INFO mapreduce.Job: Running job: job_1587986840019_0008
20/04/29 08:32:52 INFO mapreduce.Job: Job job_1587986840019_0008 running in uber mode : false
20/04/29 08:32:52 INFO mapreduce.Job: map 0% reduce 0%
20/04/29 08:33:38 INFO mapreduce.Job: map 25% reduce 0%
20/04/29 08:34:15 INFO mapreduce.Job: map 50% reduce 0%
20/04/29 08:34:48 INFO mapreduce.Job: map 75% reduce 0%
20/04/29 08:35:31 INFO mapreduce.Job: map 100% reduce 0%
20/04/29 08:35:32 INFO mapreduce.Job: Job job_1587986840019_0008 completed successfully
…
HBase Counters
BYTES_IN_REMOTE_RESULTS=2762547723
BYTES_IN_RESULTS=5549784600
MILLIS_BETWEEN_NEXTS=340672
NOT_SERVING_REGION_EXCEPTION=0
NUM_SCANNER_RESTARTS=0
NUM_SCAN_RESULTS_STALE=0
REGIONS_SCANNED=4
REMOTE_RPC_CALLS=1323
REMOTE_RPC_RETRIES=0
ROWS_FILTERED=0
ROWS_SCANNED=100008
RPC_CALLS=2657
RPC_RETRIES=0
即使只复制四个单元格,CopyTable花费的时间与复制整个数据集所花费的时间相同。对于这个非常小的数据集和一个空闲的集群,这仍然可以实现,但是在具有较大数据集的生产用例下,并且许多向其写入数据的客户端应用程序也可能使用目标集群,与SyncTable相比,CopyTable的性能下降会更高。
值得一提的是,还有其他工具/功能可以结合使用以用于目标集群的初始加载(目标根本没有数据),例如快照导出,批量加载,甚至是原始副本的直接副本。源集群中的表目录。对于要复制大量数据的初始负载,先制作表快照,然后再使用ExportSnapshot工具,将胜过SyncTable或CopyTable等在线复制工具。
检查复制完整性
当对可能的复制问题进行故障排除时,HashTable/SyncTable的另一个常见用途是监视集群之间的复制状态。在这种情况下,它可以用作VerifyReplication工具的替代方法。通常,在检查两个集群之间的状态时,要么根本没有不匹配,要么是暂时的临时问题导致较大数据集的一小部分不同步。在前面的示例中,我们一直在测试环境中使用两个簇上应有100,008行具有匹配值的行。使用dryrun选项在目标集群上运行SyncTable将使我们确定所有差异:
代码语言:javascript复制20/05/04 10:47:25 INFO mapreduce.Job: Running job: job_1588611199158_0004
…
20/05/04 10:48:48 INFO mapreduce.Job: map 100% reduce 0%
20/05/04 10:48:48 INFO mapreduce.Job: Job job_1588611199158_0004 completed successfully
…
HBase Counters
BYTES_IN_REMOTE_RESULTS=3753476784
BYTES_IN_RESULTS=5549784600
ROWS_SCANNED=100008
…
org.apache.hadoop.hbase.mapreduce.SyncTable$SyncMapper$Counter
BATCHES=97148
HASHES_MATCHED=97148
...
Unlike SyncTable we must run the VerifyReplication tool on the source cluster. We pass the peer id as one of its parameters so that it can find the remote cluster to scan for comparison:
20/05/04 11:01:58 INFO mapreduce.Job: Running job: job_1588611196128_0001
…
20/05/04 11:04:39 INFO mapreduce.Job: map 100% reduce 0%
20/05/04 11:04:39 INFO mapreduce.Job: Job job_1588611196128_0001 completed successfully
…
HBase Counters
BYTES_IN_REMOTE_RESULTS=2761955495
BYTES_IN_RESULTS=5549784600
…
org.apache.hadoop.hbase.mapreduce.replication.VerifyReplication$Verifier$Counters
GOODROWS=100008
...
SyncTable毫无区别地查找源分区和目标分区之间的所有哈希匹配,因此避免了再次扫描远程源集群的需要。对两个集群中的每个单元,VerifyReplication都会进行一个一对一的比较,即使处理如此小的数据集,这也可能已经带来了很高的网络成本。
在源集群中添加另一行,然后再次执行检查。使用VerifyReplication:
代码语言:javascript复制20/05/05 11:14:05 INFO mapreduce.Job: Running job: job_1588611196128_0004
…
20/05/05 11:16:32 INFO mapreduce.Job: map 100% reduce 0%
20/05/05 11:16:32 INFO mapreduce.Job: Job job_1588611196128_0004 completed successfully
…
org.apache.hadoop.hbase.mapreduce.replication.VerifyReplication$Verifier$Counters
BADROWS=1
GOODROWS=100008
ONLY_IN_SOURCE_TABLE_ROWS=1
…
在使用SyncTable之前,我们必须再次使用HashTable在源上重新生成哈希,因为现在有了一个新的单元格:
代码语言:javascript复制20/05/04 11:31:48 INFO mapreduce.Job: Running job: job_1588611196128_0003
…
20/05/04 11:33:15 INFO mapreduce.Job: Job job_1588611196128_0003 completed successfully
...
现在是SyncTable:
20/05/07 05:47:51 INFO mapreduce.Job: Running job: job_1588611199158_0014
…
20/05/07 05:49:20 INFO mapreduce.Job: Job job_1588611199158_0014 completed successfully
…
org.apache.hadoop.hbase.mapreduce.SyncTable$SyncMapper$Counter
BATCHES=97148
HASHES_NOT_MATCHED=97148
MATCHINGCELLS=749593
MATCHINGROWS=100008
RANGESMATCHED=97147
RANGESNOTMATCHED=1
ROWSWITHDIFFS=1
TARGETMISSINGCELLS=1
TARGETMISSINGROWS=1
我们可以看到,由于两个远程集群之间进行了额外的扫描和单元比较,因此执行时间增加了。同时,VerifyReplication的执行时间几乎没有变化。
结论
当处理两个集群数据集之间的稀疏不匹配项时,HashTable/SyncTable是用于移动数据的有价值的工具。它利用数据分区和散列来有效地检测两个数据集之间的距离差异,从而在比较两个集群中的数据时减少了要扫描的单元数,同时还避免了不必要地放入目标集群中已经存在的值。但是,这并不是灵丹妙药,如上面的一些示例所示,尽管它在功能上似乎与CopyTable工具 重叠,但在处理更大范围的顺序不匹配单元格时,后者可以提供更好的性能。从这个意义上讲,HashTable/SyncTable最适用于两个集群都已有数据的情况,或现有复制设置因对等方之一暂时不可用而中断的情况。
相关文章
https://blog.cloudera.com/apache-hbase-replication-overview/
https://blog.cloudera.com/approaches-to-backup-and-disaster-recovery-in-hbase/
https://blog.cloudera.com/online-apache-hbase-backups-with-copytable/
https://blog.cloudera.com/introduction-to-apache-hbase-snapshots/
原文作者:Wellington Chevreuil
原文链接:https://blog.cloudera.com/hbase-clusters-data-synchronization-with-hashtable-synctable-tool/