18

我需要每天将 60GB 的数据插入 cassandra。

这分解为
100 组
密钥 每组 150,000 个密钥 每个密钥
4KB 数据

在写入性能方面,我最好使用
每组 1 行,每行 150,000 个键 每组
10 行,每行 15,000 个键 每组
100 行,每行 1,500 个键 每组
1000 行,每行 150 个键

另一个要考虑的变量,我的数据在 24 小时后过期,所以我使用 TTL=86400 来自动过期

关于我的配置的更具体的细节:

CREATE TABLE stuff (
  stuff_id text,
  stuff_column text,
  value blob,
  PRIMARY KEY (stuff_id, stuff_column)
) WITH COMPACT STORAGE AND
  bloom_filter_fp_chance=0.100000 AND
  caching='KEYS_ONLY' AND
  comment='' AND
  dclocal_read_repair_chance=0.000000 AND
  gc_grace_seconds=39600 AND
  read_repair_chance=0.100000 AND
  replicate_on_write='true' AND
  populate_io_cache_on_flush='false' AND
  compaction={'tombstone_compaction_interval': '43200', 'class': 'LeveledCompactionStrategy'} AND
  compression={'sstable_compression': 'SnappyCompressor'};

访问模式详细信息:
4KB 值是一组 1000 个 4 字节浮点数打包成一个字符串。

一个典型的请求将需要随机选择 20 - 60 个这些浮点数。

最初,这些浮点数都存储在相同的逻辑行和列中。此处的逻辑行表示给定时间的一组数据,如果它们全部写入具有 150,000 列的一行。

随着时间的推移,一些数据被更新,在列集中的一个逻辑行内,打包字符串中的一组随机级别将被更新。新级别不是就地更新,而是与其他新数据一起写入新的逻辑行,以避免重写所有仍然有效的数据。这会导致碎片化,因为现在需要访问多行来检索这组 20 - 60 个值。现在,请求通常会从 1 到 5 个不同行的同一列中读取。

测试方法 我为每种配置写了 5 个随机数据样本,并对结果取平均值。速率计算为 (Bytes_written / (time * 10^6))。时间以毫秒为单位测量。Pycassa 被用作 Cassandra 接口。使用了 Pycassa 批量插入运算符。每个插入将多列插入单行,插入大小限制为 12 MB。队列在 12MB 或更少时刷新。大小不考虑行和列开销,只考虑数据。数据源和数据接收器在不同系统的同一网络上。

写入结果 请记住,由于 Cassandra 配置的复杂性,还有许多其他变量在起作用。
1 行 每行 150,000 个键:14 MBps
10 行 每行 15,000 个键:15 MBps
100 行 每行 1,500 个键:18 MBps
1000 行 每行 150 个键:11 MBps

4

2 回答 2

3

答案取决于您的数据检索模式是什么,以及数据的逻辑分组方式。概括地说,这是我的想法:

  • 宽行(每组 1 行):这可能是最好的解决方案,因为它可以防止请求同时到达多个节点,并且使用二级索引或复合列名称,您可以根据需要快速过滤数据。如果您需要每个请求访问一组数据,这是最好的选择。但是,在宽行上执行过多的 multiget 会增加节点上的内存压力,并降低性能。
  • 窄行(每组 1000 行):另一方面,宽行可能会导致集群中的读取热点。如果您需要对完全存在于一个宽行中的数据子集发出大量请求,则尤其如此。在这种情况下,瘦行将在整个集群中更均匀地分配您的请求,并避免热点。此外,根据我的经验,“更瘦”的行在使用 multiget 时往往表现得更好。

我建议,分析您的数据访问模式,并基于此最终确定您的数据模型,而不是相反。

于 2013-09-27T07:03:06.030 回答
-1

您最好使用每组 1 行,每行 150,000 列。使用 TTL 进行自动清洁过程是个好主意。

于 2013-09-27T06:51:09.310 回答