Bigtable:在行键上使用时间戳时避免热点

Posted

技术标签:

【中文标题】Bigtable:在行键上使用时间戳时避免热点【英文标题】:Bigtable: Avoiding hotspotting when using timestamps on row keys 【发布时间】:2019-02-27 17:41:34 【问题描述】:

Cloud Bigtable docs on schema design for time series说:

在绝大多数情况下,时间序列查询是在给定时间段内访问给定数据集。因此,请确保给定时间段内的所有数据都存储在连续的行中,除非这样做会导致热点。

另外,here's what they recommend to avoid hotspotting:

如果您要存储手机的电池状态,并且您的行键由单词“BATTERY”加上时间戳组成,那么行键将始终按顺序增加。由于 Cloud Bigtable 将相邻的行键存储在同一个服务器节点上,因此所有写入将仅集中在一个节点上,直到该节点已满,此时写入将移至集群中的下一个节点。

建议现场推广:

将列数据中的字段移动到行键中以使写入不连续。

例如:

BATTERY#20150301124501001 --> BATTERY#Corrie#20150301124501001

问题:

    字段提升可以解决热点问题。不过,这不会让按时间范围查询有点困难吗? 另一方面,如果您只想通过 TIMESTAMP 查询范围,是否可以避免热点?不要这么认为,对吧?

谢谢!

【问题讨论】:

【参考方案1】:
    字段提升可以解决热点问题。不过,这不会让按时间范围查询有点困难吗?

这取决于您的查询是什么样的。例如,如果要查询 Corrie 从 T1 到 T2 的电池状态,可以轻松构造一个行范围:[BATTERY#Corrie#T1,BATTERY#Corrie#T2]。但是,如果要查询所有用户的电池状态,则将扫描所有前缀为BATTERY 的行。

因此,您拥有的最重要的查询应该指示您将哪些字段提升为行键。此外,具有高基数的字段在提升为行键时更有帮助,因为它们将负载分配给更多的平板电脑。

    另一方面,如果您只想通过 TIMESTAMP 查询范围,是否可以避免热点?不要这么认为,对吧?

我不完全确定“仅查询范围内的时间戳”是什么意思,你能举个例子吗?

很大程度上取决于“TIMESTAMP”的含义。如果您总是想查询最后 10 分钟,那么您的所有查询将在任何给定时间转到单个服务器,您将体验到热点。

要记住的另一件事是,如果您没有正确设计行键,写入将遇到热点,您将无法获得良好的写入吞吐量。建议设计行键以避免热点。

【讨论】:

谢谢!我所说的“按时间戳查询范围”的意思是按日期查询。示例“从 1 月 1 日到 1 月 10 日”。如果用户名比时间戳有更好的提升,示例查询将需要扫描所有用户名。那么,我的问题是“如果您要查询一系列日期,是否可以避免热点”? 我仍然不清楚您要做什么。您的目标访问模式是什么,最重要的查询是什么?此外,如果您的写入负载很大,您应该在写入期间考虑热点。 对不起,让我澄清一下。假设我们想要存储传感器每 1 天发送一次的事件。我们最重要的查询是按日期范围:“从 1 月 1 日到 1 月 10 日”。我建议的行键是 SENSOR##。仍然有人说这会产生热点。因此,建议的密钥是 SENSOR##。所以我的结论是:如果需要按范围查询,没有办法避免热点。对吗? 如果您想创建“SENSOR##”键,您将始终拥有当前时间戳的写入热点。由于您不能在日期之前进行字段提升或移动 sensorId,您应该考虑salting。类似于 SENSOR###。这将使用您的密钥设计创建 K 个不同的连续密钥空间来代替 1。缺点是需要 K 次查询来获取一段时间内的所有数据并进行聚合。 谢谢。这是我期待的答案。谢谢!

以上是关于Bigtable:在行键上使用时间戳时避免热点的主要内容,如果未能解决你的问题,请参考以下文章

当数据重复且我没有时间戳时避免重复插入的建议

我的 BigTable 架构会导致热点吗?

如何在唯一键上加入 DataFrame 时避免洗牌?

避免在行跨度不起作用的标题表中出现分页符(打印)

使用 Impala 查询加盐的 Hbase 行键

使用 PySpark 将日期和时间字符串转换为时间戳时如何保留毫秒?