hbase 如何选择预拆分策略以及它如何影响您的行键

nir*_*nir 4 java hadoop hbase

我正在尝试预先拆分 hbase 表。HbaseAdmin java api 是创建一个 hbase 表,它是 startkey、endkey 和区域数量的函数。这是我从 HbaseAdmin 使用的 java apivoid createTable(HTableDescriptor desc, byte[] startKey, byte[] endKey, int numRegions)

关于根据数据集选择 startkey 和 endkey 有什么建议吗?

我的方法是假设我们在数据集中有 100 条记录。我希望数据大约分为 10 个区域,因此每个区域将有大约 10 条记录。所以为了找到startkey,我会说scan '/mytable', {LIMIT => 10}并选择最后一个rowkey作为我的startkey,然后scan '/mytable', {LIMIT => 90}选择最后一个rowkey作为我的endkey。

这种查找 startkey 和 rowkey 的方法看起来不错还是有更好的做法?

编辑 我尝试了以下方法来预拆分空表。所有三个都不像我使用的那样工作。我想我需要加盐才能获得平等分配。

PS> 我只显示一些地区信息

1)

byte[][] splits = new RegionSplitter.HexStringSplit().split(10);
hBaseAdmin.createTable(tabledescriptor, splits);
Run Code Online (Sandbox Code Playgroud)

这给出了具有以下边界的区域:

{
    "startkey":"-INFINITY",
    "endkey":"11111111",
    "numberofrows":3628951,
},
{
    "startkey":"11111111",
    "endkey":"22222222",
},
{   
    "startkey":"22222222",
    "endkey":"33333333",
},
{
    "startkey":"33333333",
    "endkey":"44444444",
},
{
    "startkey":"88888888",
    "endkey":"99999999",
},
{
    "startkey":"99999999",
    "endkey":"aaaaaaaa",
},
{
    "startkey":"aaaaaaaa",
    "endkey":"bbbbbbbb",
},
{
    "startkey":"eeeeeeee",
    "endkey":"INFINITY",
}
Run Code Online (Sandbox Code Playgroud)

这是没用的,因为我的 rowkeys 是复合形式'deptId|month|roleId|regionId',不适合上述边界。

2)

byte[][] splits = new RegionSplitter.UniformSplit().split(10);
hBaseAdmin.createTable(tabledescriptor, splits)
Run Code Online (Sandbox Code Playgroud)

这有同样的问题:

{
    "startkey":"-INFINITY",
    "endkey":"\\x19\\x99\\x99\\x99\\x99\\x99\\x99\\x99",
}
{
    "startkey":"\\x19\\x99\\x99\\x99\\x99\\x99\\x99\\
    "endkey":"33333332",
}
{
    "startkey":"33333332",
    "endkey":"L\\xCC\\xCC\\xCC\\xCC\\xCC\\xCC\\xCB",
}
{
    "startkey":"\\xE6ffffffa",
    "endkey":"INFINITY",
}
Run Code Online (Sandbox Code Playgroud)

3)我尝试提供开始键和结束键并获得以下无用区域。

hBaseAdmin.createTable(tabledescriptor, Bytes.toBytes("04120|200808|805|1999"),
                               Bytes.toBytes("01253|201501|805|1999"), 10);
{
    "startkey":"-INFINITY",
    "endkey":"04120|200808|805|1999",
}
{
    "startkey":"04120|200808|805|1999",
    "endkey":"000PTP\\xDC200W\\xD07\\x9C805|1999",
}
{
    "startkey":"000PTP\\xDC200W\\xD07\\x9C805|1999",
    "endkey":"000ptq<200wp6\\xBC805|1999",
}
{
    "startkey":"001\\x11\\x15\\x13\\x1C201\\x15\\x902\\x5C805|1999",
    "endkey":"01253|201501|805|1999",
}
{
    "startkey":"01253|201501|805|1999",
    "endkey":"INFINITY",
}
Run Code Online (Sandbox Code Playgroud)

Ram*_*ram 5

第一个问题:根据我对 hbase 的经验,我不知道使用开始键和结束键创建区域数量的任何硬性规则。

但根本的事情是,

使用您的rowkey 设计,数据应该分布在各个区域而不是热点(36.1. Hotspotting

但是,如果您像您提到的那样定义固定数量的区域,则为 10。在大量数据负载后可能不会有 10。如果达到一定的限制,区域数量将再次分裂。

在您使用 hbase 管理文档创建表的方式中,创建具有指定区域数量的新表。指定的开始键将成为表第一个区域的结束键,指定的结束键将成为表最后一个区域的开始键(第一个区域的起始键为空,最后一个区域的起始键为空结束键)。

此外,我更喜欢通过带有 presplits 的脚本创建一个表,比如 0-10,我将设计一个行键,使其加盐,并将位于其中一个区域服务器上以避免热点。喜欢在此处输入图片说明

编辑: 如果你想实现自己的 regionSplit 你可以实现并提供你自己的实现org.apache.hadoop.hbase.util.RegionSplitter.SplitAlgorithm和覆盖

public byte[][] split(int numberOfSplits)
Run Code Online (Sandbox Code Playgroud)

第二个问题:我的理解:您想为特定表中插入的数据找到 startrowkey 和 end rowkey...下面是方法。

  • 如果您想查找开始和结束行键scan '.meta'表以了解您的开始行键和结束行键如何..

  • 如果您可以查看行键在每个区域中的分布情况,您可以访问 ui http://hbasemaster:60010。每个区域的 start 和 rowkeys 都会在那里。

  • 要知道您的键是如何组织的,在预先拆分您的表并插入到 hbase 之后...使用FirstKeyOnlyFilter

例如:scan 'yourtablename', FILTER => 'FirstKeyOnlyFilter()' 显示所有 100 个行键。

如果您有大量数据(不是您提到的 100 行)并且想要转储所有行键,那么您可以从外部外壳使用下面的内容。

echo "scan 'yourtablename', FILTER => 'FirstKeyOnlyFilter()'" | hbase shell > rowkeys.txt
Run Code Online (Sandbox Code Playgroud)