spd*_*cbr 5 database-design hadoop hbase
什么时候创建多个表而不是创建具有大量列的单个表是有意义的。我知道表通常只有几个列族(1-2),每个列族可以支持1000多个列。
当HBase在单个表中可能包含大量列的情况下表现良好时,何时创建单独的表才有意义?
在回答问题本身之前,让我首先说明一些起作用的主要因素。我将假设使用的文件系统是HDFS。
StoreFile本质上是一个包含KeyValues的排序文件。KeyValue在逻辑上表示以下顺序:(行长度,行键,家庭长度,家庭名称,限定符,时间戳,类型)。例如,如果您的区域中只有两个KV,而CF的键是相同的,但值在两列中,则这就是StoreFile的样子(除了它实际上是字节编码的,而且像length这样的元数据也是如此)如上文所述存储):
Key1:Value1:Family1:Qualifier1:Timestamp1:Put
Key1:Value2:Family1:Qualifier2:Timestamp2:Put
Run Code Online (Sandbox Code Playgroud)StoreFile分为多个块(默认为64KB),每个数据块中包含的键范围由多级索引建立索引。可以使用索引+二进制搜索在单个块内进行随机查找。但是,在将开始位置定位在扫描所需的第一个块中之后,扫描必须依次通过特定的块。
HBase是基于LSM树的数据库,这意味着它具有内存日志(称为Memstore),该日志会定期刷新到创建StoreFiles的文件系统。对于特定列族,单个区域内的所有列均共享Memstore。
在从HBase读取数据/向HBase写入数据时涉及多个优化,但是上面给出的信息在概念上是正确的。鉴于以上陈述,与其他方法相比,具有多个列和多个表的优点如下:
单表多列
何时使用:
多个表
何时使用:
另一种排序方式:单个表中有多个CF
从上面可以看到,这两种方法都有优点。如果您对多个列具有相同的行键结构(因此,您希望共享行键以提高存储效率或需要跨列进行事务处理)但数据非常稀疏(这意味着您只写/读),则选择将变得非常困难行键的一小部分列)。在这种情况下,您似乎需要两全其美。这就是列族的用处。如果您可以将列集划分为逻辑子集,而这些子集通常只访问/读取/写入单个子集,或者您需要每个子集的存储级别配置(例如TTL,存储类,编写繁重的压缩计划)等),则可以将每个子集设为一个列族。由于特定列族的数据存储在单个文件(文件集)中,
但是,有一个陷阱:
不要尝试不必要地使用列族。与它们相关联的代价是,由于区域级别的写锁定,监视等在HBase中的工作方式,HBase在10个以上的CF上做得不好。仅当跨CF的列之间具有逻辑关系但通常不跨CF执行操作或需要为不同的CF具有不同的存储配置时,才使用CF。如果您在所有列之间共享行键架构,则最好只使用一个包含所有列的CF,除非您的数据集非常稀疏,在这种情况下,您可能需要基于上述几点的不同CF或不同表。