Cassandra 上准备好的语句的最大数量

Rob*_*Zag 3 java time-series prepared-statement cassandra

背景:我们使用 Cassandra 来存储一些时间序列数据,我们使用准备好的语句来访问数据。

我们通过以下方式对表中的数据进行分区:

  • 时间段(如一周或一个月)和
  • 保留政策(如 1 年、5 年或 10 年)

拥有不同的表,我们需要为查询、时间段和保留策略的每种组合准备(仅在使用时)不同的语句,因此准备好的语句数量将激增。一些数学:

timePeriods = 12..52 * yearsOfData
maxNumOfPrepStatements = timePeriods * policies * numOfQueries

ourCase => (20 * 10 y) * 10 p * 10 q = 20.000 prep statements
Run Code Online (Sandbox Code Playgroud)

在客户端,我只能将最常用的 PS 保留在缓存中,但是我找不到从服务器中删除未使用的 PS 的方法,所以我担心拥有大约 20.000 个准备好的语句可能对每个节点来说都是一笔巨大的成本。

问题:这个数量的 PS 会不会对服务器造成任何问题?

这分为较小的问题:

  • 这些准备好的语句的服务器端成本是多少?
  • 服务器会保留所有PS 还是会删除较少使用的 PS?
  • 有没有比重启 Cassandra 节点来清理 PS 缓存更好的解决方案?
  • 使用 Java 客户端,关闭 Session/Cluster 对象会缓解这种情况(服务器端)吗?

Ste*_*ski 5

这些准备好的语句的服务器端成本是多少?

每个准备好的语句将被解析并使用它的 MD5 摘要作为键进一步存储在缓存中。客户端即将重新注册的相同准备语句将导致服务器将 MD5 摘要与现有语句进行匹配,因此应避免。执行已注册的语句将使客户端将 MD5 与查询参数一起发送到服务器,服务器能够使用 MD5 检索缓存的语句,与解析常规 CQL 语句相比,执行速度更快。每个缓存的语句还将消耗 Java 堆的一部分,该部分对应于 MD5 键的总大小和语句对象的表示。

服务器会保留所有 PS 还是会删除较少使用的 PS?

准备好的语句由服务器通过创建基于ConcurrentLinkedHashMap的缓存来管理。缓存的容量取决于可用内存:Runtime.getRuntime().maxMemory() / 256。条目也按其内存使用情况加权,如果容量已达到,大型语句将首先从缓存中驱逐。您可以使用org.apache.cassandra.metrics.CQL.PreparedStatementsEvictedJMX 指标监控此行为。

有没有比重启 Cassandra 节点来清理 PS 缓存更好的解决方案?

不是我所知道的。我也不确定您为什么要这样做,因为将为相同的查询创建相同的 MD5 摘要。另请注意,Java 客户端将自动重新注册在服务器上找不到的准备好的语句,例如,如果它已从缓存中逐出(另请参阅此答案)。

使用 Java 客户端,关闭 Session/Cluster 对象会缓解这种情况(服务器端)吗?

我不这么认为。服务器必须跟踪数百个潜在客户端注册了哪些语句,以便安全地清理它们。