Memtable和密钥缓存混乱

var*_*run 3 cql cassandra hector

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

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

因此,当打开密钥缓存时,Cassandra的读取流程是什么。像这样吗

  1. 在内存中的MemTable中检查该行(可以在最近的插入/更新后驻留在该行中)。
  2. 如果未在MemTable中找到,则检查密钥缓存中的密钥。
  3. 如果找到键(缓存命中),则执行一次搜索,否则执行2次搜索以获取行。

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

为什么会有这种差异?

好吧,我有点想通自己,但希望有人确认..

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

在运行CQL时,我只是在运行a select * from cf,这也导致获取另一列y。该列y尚未更新,因此我假设它不会在内存中(MemTable),因此导致缓存命中。

Tyl*_*bbs 5

读取行时,始终会同时检查Memtable和SSTable,然后将结果合并在一起。密钥缓存仅用于SSTables,而不用于内存表(基本上是哈希表)。

如果您写了新行,然后不久后又读取了该行,则该内存表可能尚未刷新,并且仍将保留该行。在这种情况下,Cassandra甚至不必查看键缓存,因为它可以快速检查SSTable布隆过滤器,以查看该行是否不在任何SSTables中。因此,在这种情况下,仅直接返回来自内存表的行数据。

如果您强行(使用nodetool)尽早刷新内存表,然后读取该行几次,您会发现密钥缓存开始被使用。