我正在为我的 Bigtable 寻找一个最佳方案,以通过指定年份(或完整日期)、国家和(或)城市来满足查询数据的要求。我曾考虑将我的行键命名为2019.us.NYC,然后通过前缀查询它,但这是一个坏主意,因为它只会将我的所有数据存储在一个节点上,直到 2020 年到来,而不是共享给其他节点。有任何想法吗?也许有人已经有了这样的案例?这里的瓶颈是每秒将有大约 50 000 000 行新行。
编辑:也许使用 BigQuery 更好?
我正在为我的 Bigtable 寻找一个最佳方案,以通过指定年份(或完整日期)、国家和(或)城市来满足查询数据的要求。我曾考虑将我的行键命名为2019.us.NYC,然后通过前缀查询它,但这是一个坏主意,因为它只会将我的所有数据存储在一个节点上,直到 2020 年到来,而不是共享给其他节点。有任何想法吗?也许有人已经有了这样的案例?这里的瓶颈是每秒将有大约 50 000 000 行新行。
编辑:也许使用 BigQuery 更好?
以下是一个可能的解决方案,根据您的要求:
yearand country,可选month的 , dayandcityyear+country由于year并且country始终存在于您的查询中,因此它们必须位于行键的开头,例如:
2018#de2019#de2019#us(我曾经在这里定界,但如果和总是分别定义在 4 和 2 个字符上#可能没用。您可以将其删除以节省一个字节!)。yearcountry
month+ day+city因为month,day和city是可选的,所以它们也可以出现在行键上,而是出现在末尾:
2018#de#0610#frankfurt2019#de#0115#berlin2019#us#0813#nyc我建议您根据需要重新排序元素(如果使用year,country和的查询city是最常见的,那么顺序应该是year#country#city)。只有您可以知道最频繁的查询。始终有必要在设计行键时考虑到您的查询。
但是,正如您在问题中所建议的那样,这种行键设计可能导致 Bigtable 节点热点(所有写入单个节点,因为行键是连续的)。为了解决这个问题并确保节点之间行键的完美分布,我建议您使用分桶。
对于每次写入,您可以生成一个随机数(介于 0 和 8 之间,例如,如果您需要 8 个存储桶),并将该存储桶编号添加到您的行键中。例如 :
3#2018#de#0610#frankfurt2#2019#de#0115#berlin7#2019#us#0813#nyc然后,您将确保在编写时您的密钥将正确分布在您的 Bigtable 节点上。
您可以查看此链接,了解如何在 HBase(Bigtable 等效项)上执行此操作:https ://hbase.apache.org/book.html#schema.casestudies.log_timeseries.tslead 。
但是由于这种分桶(或加盐),您需要更改查询表的方式。如果您想要美国 2019 年的所有数据,则需要执行 8 次扫描(每个存储桶一次):
0#2019#us#,结束键:0#2019#us~1#2019#us#,结束键:1#2019#us~2#2019#us#,结束键:2#2019#us~3#2019#us#,结束键:3#2019#us~4#2019#us#,结束键:4#2019#us~5#2019#us#,结束键:5#2019#us~6#2019#us#,结束键:6#2019#us~7#2019#us#,结束键:7#2019#us~(我~在 end 键的末尾使用,因为~在 ASCII 表中是在 . 之后的所有可能字符#。例如,对于第一次扫描,这可以确保0#2019#us#检索到所有开头的行键)
这些扫描可以并行执行以获得最佳性能。
扫描是在 Bigtable 中查询数据的最高效方式。您还可以使用一些过滤器(例如FuzzyRowFilter使用特定正则表达式查询行键),但扫描肯定会给您带来更好的延迟。您还可以执行扫描并在扫描后使用过滤器(例如,要检索2019inus中的所有数据nyc,需要过滤器以仅获取带有 的行city = nyc)。
因此,基于这些元素,我将设计我的密钥,例如:
<bucket_number>#<year>#<country>#<month><day>#<city>
使用扫描查询我的表。#如果所有字段都具有固定长度,则分隔符(此处)是无用的。
如果您有足够数量的<country>值将密钥分配到不同的节点,您也可以有一些没有分桶的变体:
<year>#<country>#<month><day>#<city>
或者 :
<country>#<year>#<month><day>#<city>
总之,在设计 Bigtable 行键时总是需要权衡取舍。通过使用分桶,您始终可以避免热点,但查询数据的方式更加复杂。但是,根据您的要求(许多写),这就是我要做的。
您还可以根据 Bigtable 集群中的节点数来更改存储桶的数量。如果您有超过 8 个节点,我建议您创建更多存储桶。理想情况下,1 个桶 = 1 个节点,但一个节点可以轻松包含多个桶。
我建议尽管与其他人一起测试这个关键设计,并在真实条件下(PoC)对它们进行基准测试。您可以使用Bigtable Key Visualizer检查您的密钥在集群中的分布情况。