Cassandra阅读时间超过预期

时间:2013-05-16 16:49:42

标签: cassandra

我正在使用带有CQL3的cassandra 1.2。我的密钥空间中有三个列族。当我查询其中一个列族(手机)时,需要很长时间才能进行检索。这是我的查询

**select * from phones where phone_no in ('9038487582');**

以下是查询的跟踪输出。

activity                                        | timestamp    | source      | source_elapsed
-------------------------------------------------+--------------+-------------+----------------
                              execute_cql3_query | 16:35:47,675 | 10.1.26.155 |              0
                               Parsing statement | 16:35:47,675 | 10.1.26.155 |             58
                              Peparing statement | 16:35:47,675 | 10.1.26.155 |            335
      Executing single-partition query on phones | 16:35:47,676 | 10.1.26.155 |           1069
                    Acquiring sstable references | 16:35:47,676 | 10.1.26.155 |           1097
                       Merging memtable contents | 16:35:47,676 | 10.1.26.155 |           1143
 Partition index lookup complete for sstable 822 | 16:35:47,676 | 10.1.26.155 |           1376
 Partition index lookup complete for sstable 533 | 16:35:47,686 | 10.1.26.155 |          10659
      Merging data from memtables and 2 sstables | 16:35:47,704 | 10.1.26.155 |          29192
              Read 1 live cells and 0 tombstoned | 16:35:47,704 | 10.1.26.155 |          29332
                                Request complete | 16:35:47,704 | 10.1.26.155 |          29601

我在键空间上只有1个复制因子。并有3个节点集群。电话有大约4000万行,每行只有两列。它在29毫秒,15毫秒,8毫秒,5毫秒,3毫秒回来,但它不一致。你们能否就我可能犯的错误给出任何建议?此外,我的用例将具有极低的缓存命中率,因此缓存键对我来说不是解决方案。另外,这是我的列族定义。

CREATE TABLE phones (
  phone_no text PRIMARY KEY,
  ypids set<int>
) WITH
  bloom_filter_fp_chance=0.100000 AND
  caching='KEYS_ONLY' AND
  comment='' AND
  dclocal_read_repair_chance=0.000000 AND
  gc_grace_seconds=864000 AND
  read_repair_chance=0.100000 AND
  replicate_on_write='true' AND
  populate_io_cache_on_flush='false' AND
  compaction={'class': 'LeveledCompactionStrategy'} AND
  compression={'sstable_compression': 'SnappyCompressor'};

3 个答案:

答案 0 :(得分:4)

索引查找速度相当快(可能是因为经常访问,因此操作系统会缓存索引文件);你一直在失去的地方是在“合并数据”步骤之间。在这些之间发生的事实是寻求sstable中的数据位置。 (我为1.2.6添加了一个新的跟踪条目,以便明确说明。)

这解释了为什么有时候它很快,有时候不是 - 如果你的搜索是无竞争的,或者更好的缓存,那么查询会很快。否则会慢一些。

我看到了几个可能有用的选项:

  1. 切换到水平压缩(http://www.datastax.com/dev/blog/when-to-use-leveled-compaction
  2. 添加更多机器以通过强力获取更多iops
  3. 切换到SSD以通过更好的硬件获得更多iops
  4. 添加更多内存以使缓存更有效地弥补iops的不足
  5. 您会注意到只有第一个选项不包含更多或不同的硬件,所以这是我首先评估的内容。但好处有限:充其量你会将sstables的数量减少到1。

答案 1 :(得分:3)

从上面提供的表中,大部分查询时间都在索引查找和合并SSTables中。这是相当普遍的,我不相信你做错了什么。

通过对数据进行反规范化可以避免索引查找。 Cassandra通常的做法是围绕查询设计ColumnFamilies,而不是像关系系统中典型的表。这就把负担放在写入数据的地步,这是Cassandra最强的地方,当然由于数据重复和cassandra自然倾向于为客户提供不同的数据视图以优化数据的集群可用性而存在数据一致性

可靠的合并是卡桑德拉的阿喀琉斯之踵。 Cassandra以读取时间延迟和延迟一致性为代价优化了写入速度和可靠性。 Cassandra完全正常的是,“慢”读取的持续时间会有所不同。为了减少这个问题,有两种方法,第一种是避免在列系列中进行任何类型的数据更新或删除,因为这是导致后续压缩的原因。但即便如此,只会延迟sstable工作,因为插入会导致memtables被刷新。因此,如果变化/持续时间仍然太长,可以考虑的另一个解决方案是使用诸如Memcache之类的缓存来引导Cassandra。这是Netflix在此处记录的方法Netflix benchmarking of Cassandra

为了完整性,我应该补充说,Cassandra中的列族设置可以进行调整,基准测试,然后再次调整以减少此问题。但是,只有这个问题是Cassandra设计中固有的问题才能得到一个。您应该查看的设置是高速缓存大小,例如memtables及其溢出率,这是创建新SSTable的点。压缩也可以提供帮助,因为这有助于将更多数据压缩到内存中。通常我希望未索引的读取需要2-10ms(平均5ms),具体取决于Amazon EC2中的硬件和群集活动(这是我最近工作的环境)。

答案 2 :(得分:1)

Cassandra查询通常非常快,通常需要一段时间。如果对列族的单个列进行查询,与对所有列进行查询相比,返回需要多长时间?一些开销是预期导致更多列的原因,但不是很多,比如大约1或2ms。

如果查询all并查询单行之间存在很大差异(大于两倍),即使列族中没有太多数据,也许您的查询构造不正确。如果您希望连续存在可预测的列,则可以尝试一起查询它们,而不是使用通配符查询。它可能会对查询的速度产生巨大影响。