gpt4 book ai didi

performance - 使用 timeuuid 作为列名将日志数据写入 Cassandra 时性能不佳

转载 作者:行者123 更新时间:2023-12-02 02:01:24 27 4
gpt4 key购买 nike

遵循 an ebay tech blog 中的指示和 a datastax developers blog ,我在 Cassandra 1.2 中对一些事件日志数据进行建模。作为分区键,我使用“ddmmyyhh|bucket”,其中 bucket 是介于 0 和集群中节点数之间的任意数字。

The Data model

cqlsh:Log> CREATE TABLE transactions (yymmddhh varchar, bucket int, rId int, created timeuuid, data map, PRIMARY KEY((yymmddhh, bucket), created) );

(rId identifies the resource that fired the event.) (map is are key value pairs derived from a JSON; keys change, but not much)

我假设这转化为复合主键/行键,每小时有 X 个存储桶。我的列名不是 timeuuid。查询此数据模型按预期工作(我可以查询时间范围。)

问题在于性能:插入新行的时间不断增加。所以我在做某事错误,但无法确定问题所在。

当我使用 timeuuid 作为行键的一部分时,性能在较高水平上保持稳定,但这会阻止我查询它(没有行键的查询当然会抛出有关“过滤”的错误消息).

有什么帮助吗?谢谢!

更新

从 map 数据类型切换到预定义的列名可以缓解这个问题。插入时间现在似乎保持在每次插入 <0.005 秒左右。

核心问题仍然存在:我如何有效地使用“ map ”数据类型?什么是一种有效的方式来插入数千个键,而键只有微小的变化。

我使用数据导入 map 的 key 大多保持不变。我理解 datastax 文档(由于声誉限制无法发布链接,抱歉,但很容易找到)说每个键都会创建一个额外的列 - 或者它是否为每个“ map ”创建一个新列?这对我来说……很难相信。

最佳答案

我建议您对行进行一些不同的建模。如果您最终可能会在其中包含太多元素,那么这些集合并不是很好用。原因是 Cassandra 二进制协议(protocol)的限制,它使用两个字节来表示集合中的元素数量。这意味着如果您的集合中有超过 2^16 个元素,大小字段将溢出,即使服务器将所有元素发送回客户端,客户端也只会看到 N % 2^16 第一个元素(所以如果你有 2^16 + 3 个元素,它在客户端看来就好像只有 3 个元素)。

如果将那么多元素放入您的集合中没有风险,您可以忽略此建议。我不认为使用集合会给你带来更差的性能,我真的不确定那是怎么发生的。

CQL3 集合基本上只是存储模型之上的黑客攻击(我并不是说任何负面意义上的黑客攻击),您可以自己制作一个不受上述限制约束的类似 MAP 的行:

CREATE TABLE transactions (
yymmddhh VARCHAR,
bucket INT,
created TIMEUUID,
rId INT,
key VARCHAR,
value VARCHAR,
PRIMARY KEY ((yymmddhh, bucket), created, rId, key)
)

(请注意,我将 rId 和 map 键移到了主键中,我不知道 rId 是什么,但我认为这是正确的)

与使用 MAP 相比,这有两个缺点:它要求您在查询数据时重新组合 map (每个 map 条目会返回一行),并且它使用的空间稍多一些,因为 C* 会插入一些额外的列,但好处是获得太大的集合没有问题。

最终,这在很大程度上取决于您希望如何查询数据。不要优化插入,优化读取。例如:如果您不需要每次都读回整个映射,但通常只从中读取一个或两个键,则将键放在分区/行键中,并且每个键有一个单独的分区/行(这假设键集是固定的,所以你知道要查询什么,所以正如我所说:这在很大程度上取决于你想如何查询你的数据)。

您还在评论中提到,当您将存储桶的数量从三个 (0-2) 增加到 300 (0-299) 时,性能得到提升。这样做的原因是您可以在整个集群中更均匀地分布负载。当你有一个基于时间的分区/行键时,比如你的 yymmddhh,总会有一个热分区,所有写入都在那里(它全天移动,但在任何给定时刻它都会只命中一个节点)。您使用 bucket 列/单元格正确地添加了一个平滑因子,但是只有三个值,至少两个在同一物理节点上结束的可能性太高。有了 300,您的价差就会好得多。

关于performance - 使用 timeuuid 作为列名将日志数据写入 Cassandra 时性能不佳,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17082963/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com