Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cassandra/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance 删除行与删除列的性能比较_Performance_Cassandra_Tombstone - Fatal编程技术网

Performance 删除行与删除列的性能比较

Performance 删除行与删除列的性能比较,performance,cassandra,tombstone,Performance,Cassandra,Tombstone,我正在为Cassandra 2.1.3上的timeseries应用程序创建数据模型。我们将为系统的每个用户保留X数量的数据,我想知道针对这一需求设计的最佳方法是什么 备选案文1: 在分区键中使用一个“bucket”,以便X period的数据进入同一行。大概是这样的: ((id, bucket), timestamp) -> data 我可以一次删除一行,代价是维护这个bucket概念。它还限制了我可以查询时间戳的范围,可能会导致多次查询 备选案文2: 将所有数据存储在同一行中。每列有N

我正在为Cassandra 2.1.3上的timeseries应用程序创建数据模型。我们将为系统的每个用户保留X数量的数据,我想知道针对这一需求设计的最佳方法是什么

备选案文1: 在分区键中使用一个“bucket”,以便X period的数据进入同一行。大概是这样的:

((id, bucket), timestamp) -> data
我可以一次删除一行,代价是维护这个bucket概念。它还限制了我可以查询
时间戳
的范围,可能会导致多次查询

备选案文2: 将所有数据存储在同一行中。每列有N个删除

(id, timestamp) -> data
范围查询也很容易。但在多次删除列之后,性能如何


考虑到我们计划使用TTL让数据过期,这两种模型中哪一种能提供最好的性能?选项1的墓碑开销是多少?我认为这完全取决于您计划为最终选择的给定分区键提供多少数据、您的TTL是什么以及您正在进行的查询

我通常倾向于选项#1,尤其是如果所有写入的TTL都相同。此外,如果您使用LeveledCompactionStrategy或DataTieredCompactionStrategy,Cassandra将很好地将来自同一分区的数据保存在同一SSTable中,这将大大提高读取性能

如果使用选项#2,同一分区的数据可能分布在多个级别(如果使用LCS),或者通常是多个SSTABLE,这可能导致您从大量SSTABLE中读取数据,具体取决于查询的性质。还有热插销的问题,如果您有一个非常宽的分区,您可能会使特定的cassandra节点过载

#1的另一个好处(您提到过)是,您可以轻松删除整个分区,从而创建一个更便宜的墓碑标记。此外,如果您使用的是相同的TTL,那么该分区中的数据将几乎同时过期

我确实同意,必须进行多个查询以跨多个分区进行读取是有点痛苦的,因为这会给应用程序端带来一些复杂性。如果无法隐式确定给定id的存储桶,您可能还需要维护一个单独的表来跟踪它们


就性能而言,您是否认为在应用程序进行查询时,您可能需要读取跨分区的数据?例如,如果您有一个“最近1000条记录”的查询,并且一个分区通常比这个分区宽,那么您可能只需要对选项1进行一次查询。但是,如果您想要像“给我所有记录”这样的查询,选项#2可能会更好,否则您需要为每个bucket进行查询。

创建上述表后:

CREATE TABLE option1 (
                 ...   id bigint,
                 ...   bucket bigint,
                 ...   timestamp timestamp,
                 ...   data text,
                 ...   PRIMARY KEY ((id, bucket), timestamp)
                 ... ) WITH default_time_to_live=10;

CREATE TABLE option2 (
                 ...   id bigint,
                 ...   timestamp timestamp,
                 ...   data text,
                 ...   PRIMARY KEY (id, timestamp)  
                 ... ) WITH default_time_to_live=10;
我插入了一个测试行:

INSERT INTO option1 (id,bucket,timestamp,data) VALUES (1,2015,'2015-03-16 11:24:00-0500','test1');
INSERT INTO option2 (id,timestamp,data) VALUES (1,'2015-03-16 11:24:00-0500','test2');
…等待了10秒钟,在跟踪打开的情况下进行查询,我看到每个表都有相同的墓碑计数。所以无论哪种方式,我都不应该让你太担心

真正的问题是,如果您认为您将达到每个分区20亿列的限制,那么选项1是安全的。如果您有很多数据选项,那么#1的性能可能会更好(因为您将不再需要查看与
bucket
不匹配的分区),但实际上在这方面,任何一个都可以

tl;博士


由于无论您选择哪种选项,性能和墓碑问题都是相似的,我认为选项#2是更好的选项,这只是因为易于查询。

对于选项#1和#2,墓碑的数量将是相同的(取决于可能不正确的压缩效率),但根据您的查询,您需要通读的内容可能会有所不同。例如,如果您的bucket为“day”,并且您确实按天读取查询,那么使用选项#1,您将不需要读取前几天的墓碑数据,而使用选项#2,您需要读取到分区内的数据位置,如果有前几天的墓碑指向该数据(虽然列索引间隔可能会有帮助)。@AndyTolbert说得很好。我只是根据模型进行观察,但你绝对正确,额外的分区存储桶将减少逻辑删除。