【问题标题】:Best way to store last-touched time in Cassandra在 Cassandra 中存储上次触摸时间的最佳方式
【发布时间】:2015-08-31 13:16:49
【问题描述】:

我在 Postgres 的 User 表中存储了最后一次接触的时间,但是有很多频繁的更新和足够的争用,我可以看到 3 个相同更新死锁的示例。

Cassandra 似乎更适合此目的 - 但我是否应该为此专门设置一张桌子?而且我不需要旧的时间戳,只需要最新的。我应该使用 Cassandra 以外的东西吗? 如果我应该使用 Cassandra,关于表属性的任何提示?

我想到的表:

CREATE TABLE ksp1.user_last_job_activities (
    user_id bigint,
    touched_at timeuuid,
    PRIMARY KEY (user_id, touched_at)
) WITH CLUSTERING ORDER BY (touched_at DESC)
    AND bloom_filter_fp_chance = 0.01
    AND caching = '{"keys":"ALL", "rows_per_partition":"NONE"}'
    AND comment = ''
    AND compaction = {'min_threshold': '4', 'class': 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy', 'max_threshold': '32'}
    AND compression = {'sstable_compression': 'org.apache.cassandra.io.compress.LZ4Compressor'}
    AND dclocal_read_repair_chance = 0.1
    AND default_time_to_live = 0
    AND gc_grace_seconds = 864000
    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';

更新

谢谢!我围绕 writetime 做了一些实验,因为无论如何我都必须写一个值,所以我只写了 time。

像这样:

CREATE TABLE simple_user_last_activity (
    user_id bigint,
    touched_at timestamp,
    PRIMARY KEY (user_id)
);

然后:

INSERT INTO simple_user_last_activity (user_id, touched_at) VALUES (6, dateof(now()));
SELECT touched_at from simple_user_last_activity WHERE user_id = 6;

由于touched_at 不再在主键中,每个用户只存储一条记录。

更新 2

我还有另一个选择。我也可以存储 job_id,从而为分析提供更多数据:

CREATE TABLE final_user_last_job_activities (
    user_id bigint,
    touched_at timestamp,
    job_id bigint,
    PRIMARY KEY (user_id, touched_at)
) 
WITH CLUSTERING ORDER BY (touched_at DESC)
AND default_time_to_live = 604800;

添加 1 周 TTL 会处理过期记录 - 如果没有记录,我会返回当前时间。

INSERT INTO final_user_last_job_activities (user_id, touched_at, job_id) VALUES (5, dateof(now()), 5);
INSERT INTO final_user_last_job_activities (user_id, touched_at, job_id) VALUES (5, dateof(now()), 6);
INSERT INTO final_user_last_job_activities (user_id, touched_at, job_id) VALUES (5, dateof(now()), 7);
INSERT INTO final_user_last_job_activities (user_id, touched_at, job_id) VALUES (5, dateof(now()), 6);

SELECT * FROM final_user_last_job_activities LIMIT 1;

这给了我:

 user_id | touched_at               | job_id
---------+--------------------------+--------
       5 | 2015-06-17 12:43:30+1200 |      6

简单的基准测试显示,在存储或从更大的表中读取方面没有显着的性能差异。

【问题讨论】:

  • Cassandra 每列都隐式支持writetime。请参阅this,看起来这就是您在此处寻找的内容。
  • @MSD writetime 远非完美。它不适用于任何集合类型,也不适用于主键。当然,它不能用于查看单元格何时被删除。在某种程度上,它肯定不是审计日志。但是在 SQL 数据存储中,有两个日期 creation_datemodification_date 是一种常见的做法,我开始相信这对于 cassandra 来说也是一个很好的做法。

标签: database postgresql cassandra


【解决方案1】:

因为 c* 是最后一次写入获胜,所以您可以简单地保留每行的最新版本。

正如 MSD 建议的那样,您可以使用writetime 来拉取写入时间。但要小心,因为这是特定于列的,您不能在主键列上使用写入时间。例如在如下表中:

cqlsh> create TABLE test.test ( a int, b int, c int, d int, primary key (a))
   ... ;
cqlsh> insert INTO  test.test (a, b, c, d) VALUES ( 1,2,3,4)
   ... ;

cqlsh> select * from test.test
   ... ;

 a | b    | c | d
---+------+---+------
 1 |    2 | 3 |    4

(2 rows)

cqlsh> insert into test.test (a,c) values (1, 6);
cqlsh> select * from test.test ;

 a | b    | c | d
---+------+---+------
 1 |    2 | 6 |    4

(2 rows)
cqlsh> select writetime(a), writetime(b), writetime(c), writetime(d) from test.test
   ... ;
InvalidRequest: code=2200 [Invalid query] message="Cannot use selection function writeTime on PRIMARY KEY part a"

cqlsh> select  writetime(b), writetime(c), writetime(d) from test.test  ;

 writetime(b)     | writetime(c)     | writetime(d)
------------------+------------------+------------------
 1434424690700887 | 1434424690700887 | 1434424702420929

否则你可以添加一个带有时间戳的cql列:

create TABLE test.test ( a int, b int, c int, d int, touched_at timeuuid, primary key (a)) ;

一些快速基准测试将帮助您确定哪个性能更高。

【讨论】:

    【解决方案2】:

    Cassandra 每列都隐含支持writetime。请参阅this,看起来这就是您在此处寻找的内容。

    【讨论】:

      猜你喜欢
      • 2015-05-11
      • 1970-01-01
      • 1970-01-01
      • 2020-10-25
      • 2012-07-15
      • 1970-01-01
      • 2013-12-26
      • 1970-01-01
      相关资源
      最近更新 更多