database - Scylla 如何从其缓存中逐出数据?

标签 database caching nosql scylla

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

K1 C1 V1 V2 V3

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

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

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

是否有任何情况需要注意数据在 SSTables 而不是在内存中更新的位置?

谢谢

附言

我阅读了很多关于 how caching works in Scylla 的内容但我没有看到上述问题的明确答案。如果 Scylla 确实知道后台更新,我也很想知道它如何实现缓存的动态和智能更新。

最佳答案

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

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

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

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

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

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

关于database - Scylla 如何从其缓存中逐出数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72253581/

相关文章:

mysql - 从没有多个相同用户 ID 的表中选择数据

mysql - 此 SQL 条件会排除 NULL 值吗?

ruby-on-rails - Ruby on Rails : Clear a cached page

css - Prestashop 1.6 CCC css 每次缓存中的新文件

mongodb - 什么时候应该使用 NoSQL 数据库而不是关系数据库?可以在同一个网站上使用两者吗?

database - pgAdmin数据库还原

django - 无法删除 PostgreSQL 中的列

c# - 在 C# 中过滤巨大列表的最高效方法?

database - Cassandra 集群上的数据分区和复制

sql-server - 将 SQL Server 连接到 "NoSQL"数据库