排查数据保留 (TTL) 问题,包括过期数据没有从 Azure HDInsight 存储中删除
在 HBase 群集中,你可能决定在数据老化后删除数据,这样既可以释放一些存储和节省成本(因为不再需要旧数据),也可以遵守法规。 如果需要,需要在 ColumnFamily 级别的表中将 TTL 设置为过期,并自动删除旧数据。 虽然 TTL 也可以在单元级设置,但在 ColumnFamily 级设置通常是一个更方便的选项,原因是易于管理,并且单元格 TTL(以毫秒表示)不能延长单元格的生存期直至超过 ColumnFamily 级别 TTL 设置(以秒表示),因此,只有单元级的保留时间更短才能从设置单元格级别 TTL 中获益。
尽管设置了 TTL,你可能会注意到未获得所需效果,即某些数据尚未过期和/或存储大小没有减少。
先决条件
按照步骤和给定的命令,打开两个到 HBase 群集的 ssh 连接:
在一个 ssh 会话中,保留默认的 bash shell。
在第二个 ssh 会话中,运行以下命令来启动 HBase shell。
hbase shell
检查是否配置了所需的 TTL,以及是否从查询结果中删除了过期的数据
按照给定的步骤了解问题发生的位置。 通过检查特定表或所有表的行为是否发生以开始操作。 如果不确定此问题是影响所有表还是特定表,那么就以示例的特定表名称作为开始。
首先检查是否已经为目标表的 ColumnFamily 配置了 TTL。 在启动了 HBase shell 的 ssh 会话中运行以下命令并观察输出。 一个列族将 TTL 设置为 50 秒,而另一个 ColumnFamily 没有为 TTL 配置任何值,因此它显示为“FOREVER”(此列族中的数据配置为不会过期)。
describe 'table_name'
如果未配置,则默认 TTL 设置为“FOREVER”。 数据未按预期过期并从查询结果中删除,这存在两种可能性。
- 如果 TTL 在“FOREVER”之后还有其他值,去哪个观察列族的值,并以秒为单位记下该值(特别注意与单元度量值相关的值,因为单元格 TTL 为毫秒,但列族 TTL 为秒),确认该值是否为预期值。 如果观察到的值不正确,请首先进行修复。
- 如果所有列族的 TTL 值为“FOREVER”,请将 TTL 配置为第一步,然后监视数据是否按预期过期。
如果确定 TTL 已配置且具有 ColumnFamily 的正确值,下一步是确认执行表扫描时过期的数据不再显示。 数据过期时,应将其删除,不显示在扫描表结果中。 在 HBase shell 中运行以下命令以检查。
scan 'table_name'
检查每个区域每个表的 StoreFiles 的数量和大小,以观察压缩操作后是否有任何更改可见
进行下一步之前,从 bash shell 的 ssh 会话中,运行以下命令以检查当前 StoreFile 的数量以及为配置了 TTL 的 ColumnFamily 显示的每个 StoreFile 的大小。 首先注意要检查的表和 ColumnFamily,然后在 ssh 会话 (bash) 中运行以下命令。
hdfs dfs -ls -R /hbase/data/default/table_name/ | grep "column_family_name"
很可能会在输出中显示更多结果,作为表的一部分,每个区域 ID 都有一个结果,对于所选 ColumnFamily,每个区域名称下存在的 StoreFiles 都介于 0 和更多结果之间。 若要计算上述结果输出中的行总数,请运行以下命令。
hdfs dfs -ls -R /hbase/data/default/table_name/ | grep "column_family_name" | wc -l
刷新后检查每个区域每个表的 StoreFiles 的数量和大小
根据为每个 ColumnFamily 配置的 TTL 以及为目标 ColumnFamily 在表中写入的数据量,部分数据可能仍存在于 MemStore 中,而不是作为 StoreFile 写入存储。 因此,为了确保数据以 StoreFile 的形式写入存储,在达到最大配置的 MemStore 大小之前,可以在 HBase shell 中运行以下命令,立即将数据从 MemStore 写入 StoreFile。
flush 'table_name'
通过在 bash shell 中再次运行命令来观察结果。
hdfs dfs -ls -R /hbase/data/default/table_name/ | grep "column_family_name"
针对修改了数据的每个区域,与之前的结果输出相比,StoreFile 会创建一个额外的存储文件,将包含该区域 MemStore 的当前内容。
在主要压缩之后,检查每个区域每个表的 StoreFiles 的数量和大小
此时,MemStore 中的数据已写入存储中的 StoreFile,但当前的一个或多个 StoreFiles 中可能仍存在过期的数据。 虽然次要压缩可以帮助删除某些过期条目,但不能保证将其全部删除为次要压缩。 它不会选择所有要压缩的 StoreFiles,而主压缩会选择该区域中要压缩的所有 StoreFiles。
此外,存在另一种情况,即次要压缩可能无法删除过期的 TTL 单元格。 有一个名为 MIN_VERSIONS 的属性,它默认值为 0(请参阅上述输出中描述 table_name 属性 MIN_VERSIONS=>'0')。 如果此属性设置为 0,则次要压缩会移除 TTL 过期的单元格。 如果此值大于 0,则次要压缩可能不会删除过期的 TTL 单元格,即使它作为压缩的一部分触及了相应的文件。 此属性将单元格的最小版本数配置为保留,即使这些版本 TTL 已过期。
若要确保从存储中删除过期的数据,我们需要运行主要的压缩操作。 主压缩操作完成后,它会为每个区域留下一个 StoreFile。 在 HBase shell 中,运行以下命令以对表执行主要压缩操作:
major_compact 'table_name'
根据表大小,主压缩操作可能需要一些时间。 在 HBase shell 中使用以下命令来监视进度。 如果在执行以下命令时压缩仍在运行,则会获得输出“MAJOR”,但如果压缩已完成,则会获得输出“NONE”。
compaction_state 'table_name'
如果快速切换到 bash 并运行命令,当压缩状态在 hbase shell 中显示为“NONE”时。
hdfs dfs -ls -R /hbase/data/default/table_name/ | grep "column_family_name"
请注意,除了每个区域每个 ColumnFamily 以前的 StoreFile 以外,还创建了一个额外的 StoreFile,在几分钟后,每个列系列在每个区域只保留最后一个创建的 StoreFile。
对于上面的示例区域,一旦额外的时刻过去,我们可以注意到有一个 StoreFile 保持不变。 此外,由于主压缩,此文件在存储中占用的大小会减少。 此时,在当前主压缩操作运行后,任何以前尚未(由另一个主压缩)删除的过期数据将很快被删除。
注意
在此故障排除练习中,你手动触发了主压缩。 但实际上,为许多表手动执行此操作是很耗时的。 默认 HDInsight HBase 群集已禁用主要压缩。 默认情况下禁用主要压缩的主要原因是,在进行主要压缩时,表操作的性能会受到影响。 但是,可以通过为属性 hbase.hregion.majorcompaction
配置值(以毫秒表示)来启用主要压缩,也可以使用 cron 选项卡作业或其他外部系统在方便的时候以较低的工作负载安排压缩。
后续步骤
如果你的问题未在本文中列出,或者无法解决问题,请访问以下渠道之一获取更多支持:
通过 Azure 社区支持获取 Azure 专家的解答。
如果需要更多帮助,可以从 Azure 门户提交支持请求。 从菜单栏中选择“支持” ,或打开“帮助 + 支持” 中心。 有关更多详细信息,请参阅如何创建 Azure 支持请求。 Azure 订阅包含对订阅管理和计费支持的访问权限,并且通过 Azure 支持计划之一提供技术支持。