Scylla 如何从缓存中清除数据?

S.O*_*O.S 3 database caching nosql scylla

Scylla 如何确定何时从缓存中逐出数据?例如,假设表T具有以下结构:

\n
K1 C1 V1 V2 V3\n
Run Code Online (Sandbox Code Playgroud)\n

我用 500 行填充上表(例如,查询SELECT * from T WHERE K1 = X & C1 = Y返回 500 行)。

\n

一段时间后,我在上面的表中插入一个新行,这将导致上面的查询返回 501 行,而不是 500 行。

\n

Scylla 是否知道自动从其缓存中逐出 500 行,或者至少将第 501 行添加到其缓存中?如果没有,大多数查询将很快开始返回过时的数据。同样,如果我不向数据库添加新行,而是更新现有 500 行之一,会发生什么情况。Scylla 是否知道此修改并能够自动更新其缓存?如果是,它是否足够智能,只更新已更改的数据(新行或已修改的行),还是逐出/更新所有 500 行?

\n

是否存在需要注意数据在内存中更新SSTables但未在内存中更新的情况?

\n

谢谢

\n

聚苯乙烯

\n

我读了很多关于Scylla 中缓存如何工作的内容,但我没有\xe2\x80\x99 看到上述问题的明确答案。如果 Scylla 确实知道后台更新,我也会很好奇它如何实现缓存的动态和智能更新。

\n

Nad*_*'El 5

我认为您误解了 Scylla 或任何数据库中缓存的作用。

缓存,顾名思义,缓存(即保留在内存中)各个行,而不是整个请求的结果。因此,请求一次返回 500 行这一事实并不意味着下一次该请求到来时,Scylla 将返回相同的 500 行。一点也不。让我尝试解释一下发生了什么,尽管这在其他地方也有记录,我还将简化一些细节,希望能够阐明要点:

当 Scylla 节点启动时,所有数据都位于磁盘上(存储在称为sstables 的文件中),内存中没有任何数据。当用户请求读取内存缓存中尚未存在的特定行时,将从磁盘读取该行,然后将其存储在缓存中。如果用户稍后再次读取同一行,则会立即从缓存中返回该行。如果用户写入这一行,该行将在缓存和磁盘上更新(细节稍微复杂一些,还有一个内存表 - memtable - 但我试图简化)。缓存始终是最新的 - 如果其中出现一行,则它是正确的。当然也有可能不会出现在其中。

您在问题文本中描述的情况(尽管不是您发布的实际查询!)是关于扫描分区切片,返回的不是一行而是许多行(500 或 501)。Scylla 需要(并且确实)投入更多的工作来正确处理这种情况:

当第一次完成某个范围的扫描时,Scylla 会读取该范围内的 500 行,并将它们放入行缓存中。但它也会记住缓存在该范围内是连续的- 这 500 行是该范围内存在的所有内容。因此,当用户再次尝试相同的查询时,缓存不需要检查这 500 行之间是否可能存在其他行 - 它知道没有。如果您稍后在该范围内写入第 501 行,该行将被添加到缓存中,缓存知道它保持连续,因此该范围的下一次扫描将返回 501 行。Scylla不需要仅仅因为将 500 行添加到同一分区就将其逐出。

如果在稍后的某个时间点,Scylla 耗尽内存并需要从缓存中逐出某些行,它可能会决定从缓存中逐出所有这些 501 行 - 或其中一些。如果它驱逐其中一些,它就会失去连续性 - 如果它只记住原始范围的 400 行,如果用户要求再次扫描该范围,Scylla 被迫(再次简化一些细节)读取其中的所有行磁盘范围,因为它不知道该范围内缺少哪些特定行。