Rob*_*Zag 3 java time-series prepared-statement cassandra
背景:我们使用 Cassandra 来存储一些时间序列数据,我们使用准备好的语句来访问数据。
我们通过以下方式对表中的数据进行分区:
拥有不同的表,我们需要为查询、时间段和保留策略的每种组合准备(仅在使用时)不同的语句,因此准备好的语句数量将激增。一些数学:
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 会不会对服务器造成任何问题?
这分为较小的问题:
这些准备好的语句的服务器端成本是多少?
每个准备好的语句将被解析并使用它的 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 对象会缓解这种情况(服务器端)吗?
我不这么认为。服务器必须跟踪数百个潜在客户端注册了哪些语句,以便安全地清理它们。