如何将 ScyllaDB 中的 trim a list/set 设置为特定大小?

How to trim a list/set in ScyllaDB to a specific size?

有没有办法 trim 一个 list/set 到特定大小(根据元素数量)?

类似于 Redis 上的 LTRIM 命令 (https://redis.io/commands/ltrim)。

目标是向 list/set 中插入一个元素,但确保其最终大小始终 <= X(丢弃旧条目)。

我希望能够做的事的例子:


CREATE TABLE images (
    name text PRIMARY KEY,
    owner text,
    tags set<text> // A set of text values
);

-- single command
UPDATE images SET tags = ltrim(tags + { 'gray', 'cuddly' }, 10) WHERE name = 'cat.jpg';

-- two commands (Redis style)
UPDATE images SET tags = tags + { 'gray', 'cuddly' } WHERE name = 'cat.jpg';
UPDATE images SET tags = ltrim(tags, 10) WHERE name = 'cat.jpg';

没有,Scylla(或者Cassandra)中没有这样的操作。

第一个原因是效率:如您所知,Scylla 中 writes 如此高效的一个原因是它们不进行读取:将元素附加到 a list 只是将这个单个项目写入顺序文件(所谓的 "sstable")。它不需要读取现有列表并检查它已有的元素。您建议的操作需要在写入之前读取现有项目,从而显着降低速度。

第二个原因是一致性:如果像您建议的那样并行执行多个操作,以不同的顺序到达不同的协调器和副本,会发生什么情况?如果在较早的问题出现后,其中一个副本缺少其中一个值,会发生什么情况?没有解决这些问题的神奇方法,Scylla 为并发 Read-Modify-Write 操作提供的通用解决方案是 LWT(Lightweight Transacations)。您可以使用 LWT 模拟 ltrim 操作,但它会比普通写入慢得多。您需要将列表读取给客户端,对其进行修改(附加、ltrim 等),然后使用 LWT 将其写回(附加条件是它仍然具有其旧值,或者使用额外的 "version number" 柱子)。