1

我在 AWS 上的 Cassandra 2.2.0 中创建了一个结构简单的表:

CREATE TABLE data_cache (
    cache_id text,
    time timeuuid,
    request_json_data text,
    PRIMARY KEY (cache_id, time)
) WITH CLUSTERING ORDER BY (time DESC)
    AND bloom_filter_fp_chance = 0.01
    AND caching = '{"keys":"ALL", "rows_per_partition":"NONE"}'
    AND comment = ''
    AND compaction = {'class': 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'}
    AND compression = {'sstable_compression': 'org.apache.cassandra.io.compress.LZ4Compressor'}
    AND dclocal_read_repair_chance = 0.1
    AND default_time_to_live = 3600
    AND gc_grace_seconds = 86400
    AND max_index_interval = 2048
    AND memtable_flush_period_in_ms = 0
    AND min_index_interval = 128
    AND read_repair_chance = 0.0
    AND speculative_retry = '99.0PERCENTILE';

我在 AWS 上有 2 个数据中心 - eu 和 us-east。

我遇到的问题是表很快填满,以至于系统上没有更多的磁盘空间。当 READ 在 CQLSH 中变得不负责任时,截断表也是有问题的。

如您所见 - 我将默认 TTL 更改为 3600 秒(或 1 小时),并将 GC 宽限秒数更改为短于默认的 10 天。

目前,每个集群的数据现在为 101GB,系统变得无响应。如果我尝试一个简单的select count(*) from data_cache方法,它会向我发送连接超时 - 尝试 3 次后,集群本身就会丢失。错误日志指出 java 内存不足。

我应该怎么做?我究竟做错了什么?

目前存在 TTL,因此数据不会破坏服务器,直到我们知道我们将使用缓存多长时间,因此为什么它只设置为 1 小时 - 但如果我们认为缓存应该构建 1 天 - 我们将扩展容量因此,但我们也需要从中读取,由于崩溃,我们无法这样做。

4

2 回答 2

4

你所经历的一切都是意料之中的。Cassandra 擅长检索一条特定记录,但不擅长一次检索数十亿行。事实上,您的简单SELECT COUNT(*) FROM data_cache操作就是在后台读取您的所有数据集。由于 Cassandra 的性质,计数很困难

如果您通过 BOTH 查询cache_id并且time一切都很好,但如果您不这样做,那就麻烦了,特别是如果您不知道行的宽度。

请注意 TTL 会生成墓碑,它迟早会打击你。即使您降低了宽限期,TTL 也不能保证您的可用空间会被收集。事实上,使用默认参数,SizeTieredCompactionStrategy 需要 4 个大小大致相同的 SSTable,但如果您没有这样相等的表,那么压缩不会做任何事情。在最坏的情况下, SizeTieredCompactionStrategy 要求磁盘上的可用空间至少是被压缩的最大 CF 的大小

在我看来,您正在尝试将 Cassandra 用作缓存,但您目前正在像队列一样使用它。我会重新考虑数据模型。如果您来这里时对您想要实现的目标有更好的说明,也许我们可以帮助您。

于 2016-12-22T09:13:32.923 回答
1

我认为您的第一个问题与压缩有关,更准确地说与写入吞吐量和压缩之间的比率有关。在 cassandra.yaml 文件中有一个字段compaction_throughput_mb_per_sec。如果它的值低于您的写入负载,Cassandra 将无法清除空间,最终将没有 dsik 空间和节点崩溃。

我想知道您的数据是否正确分布在您的集群中。我在这里看到您使用 PARTITION_KEYcache_id和 CLUSTERING_KEY time。这意味着任何具有相同内容的插入cache_id都会进入同一个节点。因此,如果您在同一个中获得的太少cache_id或太多,工作负载将不会平均分配,并且存在节点无响应的风险。您必须牢记的限制是每个分区不超过 100 000 行,每个分区不超过 100 Mb。timecache_id

于 2016-12-22T08:43:06.680 回答