什么时候创建多个表而不是创建具有大量列的单个表才有意义。据我了解,表通常只有几个列族 (1-2),每个列族可以支持 1000 多个列。
当 HBase 似乎在单个表中可能存在大量列时表现良好时,什么时候创建单独的表才有意义?
在回答问题本身之前,让我首先陈述一些起作用的主要因素。我假设使用的文件系统是 HDFS。
-
表被划分为键空间的不重叠的分区,称为区域。
-
键范围 -> 区域映射存储在一个称为元的特殊单区域表中。
-
一个区域的一个 HBase 列族中的数据存储在单个 HDFS 目录中。它通常是多个文件,但出于所有意图和目的,我们可以假设列族的区域数据存储在 HDFS 上的单个文件中,称为 StoreFile / HFile。
-
StoreFile 本质上是一个包含 KeyValue 的排序文件。 KeyValue 在逻辑上按顺序表示以下内容:(RowLength、RowKey、FamilyLength、FamilyName、Qualifier、Timestamp、Type)。例如,如果您的 CF 区域中只有两个 KV,其中键相同但值在两列中,则 StoreFile 的外观如下(除了它实际上是字节编码的,并且长度等元数据也是如此)正如我上面提到的那样存储):
Key1:Family1:Qualifier1:Timestamp1:Value1:Put
Key1:Family1:Qualifier2:Timestamp2:Value2:Put
-
StoreFile 分为blocks(默认64KB)并且每个数据块包含的key范围通过多级索引进行索引。可以使用索引+二分搜索来完成单个块内的随机查找。然而,在找到扫描所需的第一个块中的起始位置之后,扫描必须连续地通过特定块。
-
HBase 是一个基于 LSM 树的数据库,这意味着它有一个内存日志(称为Memstore)定期刷新到创建 StoreFiles 的文件系统。 Memstore 为特定列族的单个区域内的所有列共享。
在处理从 HBase 读取数据/向 HBase 写入数据时涉及多种优化,但上面给出的信息在概念上是正确的。鉴于上述陈述,以下是使用多个列与多个表相比其他方法的优点:
单表多列
- 由于前缀编码,磁盘上的压缩效果更好,因为键的所有数据都存储在一起,而不是跨表存储在多个文件中。由于数据大小较小,这也会导致磁盘活动减少。
- 元表上的负载较小,因为区域总数会较小。您将拥有一张表的 N 个区域,而不是 M 个表的 N*M 个区域。这意味着更快的区域查找和元表上的低争用,这是大型集群所关心的问题。
- 当您需要读取单个行键的多个列时,读取速度更快且 IO 放大较低(导致磁盘活动减少)。
- 当为单个行键写入多个列时,您可以利用行级事务、批处理和其他性能优化。
何时使用这个:
- 如果您想跨多列执行行级事务,您have to将它们放在一个表中。
- 即使您不需要行级事务,但您经常向多个列写入或查询同一行键。一个好的经验法则是,如果平均而言,超过 20% 的列具有单行值,您应该尝试将它们放在一个表中。
- 当你有太多列时。
多表
- 如果扫描主要只关注一列,则每个表的扫描速度更快,IO 放大也更低(请记住,扫描中的顺序查找将不必要地读取它们不需要的列)。
- 良好的数据逻辑分离,特别是当您不需要跨列共享行键时。为一种类型的行键设置一张表。
何时使用:
- 当数据有明确的逻辑分离时。例如,如果不同列集的行键架构不同,请将这些列集放在单独的表中。
- 当只有一小部分列具有行键值时(请参阅下面的更好方法)。
- 您希望为不同的列集设置不同的存储配置。例如。 TTL、压缩率、阻塞文件计数、memstore 大小等(请在下面查看此用例中更好的方法)。
另一种选择:单个表中的多个 CF
从上面可以看出,这两种方法都有优点。如果您的多列具有相同的行键结构(因此,您希望共享行键以提高存储效率或需要跨列事务)但数据非常稀疏(这意味着您只写/读),那么选择变得非常困难行键的一小部分列)。
在这种情况下,您似乎需要两全其美。这就是列族的用武之地。如果您可以将列集分区为逻辑子集,其中您主要只访问/读/写单个子集,或者您需要每个子集的存储级别配置(例如 TTL、存储类、写入大量压缩计划)等),那么您可以将每个子集设为一个列族。
由于特定列族的数据存储在单个文件(文件集)中,因此您可以在读取列子集时获得更好的局部性,而不会减慢扫描速度。
然而,有一个问题:
不要尝试不必要地使用列族。它们是有相关成本的,而且由于 HBase 中区域级写锁、监控等的工作方式,HBase 不能很好地处理 10 个以上的 CF。仅当跨 CF 的列之间存在逻辑关系,但通常不会跨 CF 执行操作或需要为不同的 CF 设置不同的存储配置时,才使用 CF。
如果您在所有列之间共享行键架构,那么仅使用包含所有列的单个 CF 是完全可以的,除非您有一个非常稀疏的数据集,在这种情况下,您可能需要基于上述要点的不同 CF 或不同表。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)