2012-08-12 66 views
3

我正在使用具有默认Cassandra缓存设置的Hector从CF中读取行。 这意味着密钥缓存已打开。我正在使用jconsole监视关键缓存命中。Memtable和键缓存混淆

但是即使读取一行(通过主键)100次,缓存命中也不会增加。该行最近已更新。

所以当关键缓存打开时,卡桑德拉的读取流程是什么。是这样吗?

  1. 检查内存MemTable中的行(最近插入/更新后可能驻留在那里)。
  2. 如果在MemTable中找不到,则会检查密钥缓存中的密钥。
  3. 如果发现密钥(缓存命中),一次搜索,否则2次尝试获取该行。

但是使用cassandra-clicassandra-jdbc(CQL),我得到了不同的结果。 也就是说,即使最近更新了该行,每次从该行读取都会导致键缓存命中。说,我读了100次,我得到100次点击。

为什么这种差异?

嗯,我有种想通了这一点我自己,而是希望有人证实..

看起来更新导致刚刚获取被更新到MemTable中的列。 因此,当我使用hector更新一行时,我没有更新所有列。只是一列x,并且读取操作的同一列x。所以没有缓存命中,因为它已经在MemTable中。

运行CQL时,我刚刚运行了一个select * from cf,导致另一列y也被导入。 y列未被更新,所以我假设它不会在内存中(MemTable),因此导致缓存命中。

回答

4

当您读取一行时,Memtables和SSTables总是被选中,并且结果合并在一起。密钥缓存仅用于SSTables,而不是memtables(基本上是hashmaps)。

如果你写了一个新行然后在不久之后读取它,那么memtable可能不会被刷新,并且仍然保存该行。在这种情况下,Cassandra甚至不必查看关键缓存,因为它可以快速检查SSTable布隆过滤器,以查看该行尚未处于任何SSTable中。所以,在这种情况下,memtable中的行数据直接返回。

如果强制刷新memtable(使用nodetool),然后多次读取该行,您将看到密钥缓存开始被使用。

+0

这是否适用于更新行? 而且是存储在列级的MemTable中的数据?也就是说,在MemTable刷新之后,我只更新一行中的一列'x',并读取另一列在同一行中说'y',然后由于'y'列尚未加载,键缓存再次被击中MemTable中? – varun 2012-08-15 05:39:41

+0

这应该解释它是如何工作的:http://wiki.apache.org/cassandra/MemtableSSTable。事情不会回到memtables中;一旦你从sstables读取任何东西,密钥缓存将被使用。 – 2012-08-19 05:43:02