Cassandra 上准备好的语句的最大数量
Max number of prepared statement on 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
在客户端,我只能在缓存中保留最常用的 PS,但我找不到从服务器中删除未使用的缓存的方法,所以我担心大约 20.000 个准备好的语句可能对每个节点来说都是一个很大的成本。
问题:这个PS的数量会导致服务器出现问题吗?
这分为更小的问题:
- 这些准备好的语句的服务器端成本是多少?
- 服务器会保留 所有 和 PS 还是会删除较少使用的?
- 有没有比重启 Cassandra 节点来清理 PS 缓存更好的解决方案?
- 使用 Java 客户端,关闭 Session / Cluster 对象是否会缓解这种情况(服务器端)?
How much will be the server side cost of those prepared statements?
每个准备好的语句将被解析并进一步存储在缓存中,使用它的 MD5 摘要作为键。客户端即将重新注册的相同准备语句将导致服务器将 MD5 摘要与已存在的语句进行匹配,因此应避免。执行已注册的语句将使客户端将 MD5 连同查询参数一起发送到服务器,并且服务器能够使用 MD5 检索缓存的语句,与解析常规 CQL 语句相比执行速度更快。每个缓存的语句也将消耗 Java 堆的一部分,这对应于 MD5 密钥的总大小和语句对象的表示。
Will the server keep all the PS or will it remove the less used ones?
准备好的语句由服务器通过基于ConcurrentLinkedHashMap创建缓存来管理。缓存的容量取决于可用内存:Runtime.getRuntime().maxMemory() / 256
。条目也根据它们的内存使用情况进行加权,如果达到容量,大型语句将首先从缓存中逐出。您可以使用 org.apache.cassandra.metrics.CQL.PreparedStatementsEvicted
JMX 指标监视此行为。
Is there a better solution than restarting Cassandra nodes to clean the PS cache?
我不知道。我也不确定您为什么要这样做,因为将为相同的查询创建相同的 MD5 摘要。另请注意 Java 客户端将自动 re-register prepared statements that cannot be found on the server, e.g. in case it has been evicted from the cache (see also )。
using the Java client, will closing the Session / Cluster object alleviate this (server side)?
我不这么认为。服务器必须跟踪数百个潜在客户注册了哪些语句,以便安全地清理它们。
背景:我们正在使用Cassandra来存储一些时间序列数据,我们正在使用准备好的语句来访问数据。
我们按以下方式对表中的数据进行分区:
- 时间段(如一周或一个月)和
- 保留政策(例如 1 年、5 年或 10 年)
拥有不同的表,我们需要为查询、时间段和保留策略的每种组合准备(仅在使用时)不同的语句,因此准备语句的数量将会激增。一些数学:
timePeriods = 12..52 * yearsOfData
maxNumOfPrepStatements = timePeriods * policies * numOfQueries
ourCase => (20 * 10 y) * 10 p * 10 q = 20.000 prep statements
在客户端,我只能在缓存中保留最常用的 PS,但我找不到从服务器中删除未使用的缓存的方法,所以我担心大约 20.000 个准备好的语句可能对每个节点来说都是一个很大的成本。
问题:这个PS的数量会导致服务器出现问题吗?
这分为更小的问题:
- 这些准备好的语句的服务器端成本是多少?
- 服务器会保留 所有 和 PS 还是会删除较少使用的?
- 有没有比重启 Cassandra 节点来清理 PS 缓存更好的解决方案?
- 使用 Java 客户端,关闭 Session / Cluster 对象是否会缓解这种情况(服务器端)?
How much will be the server side cost of those prepared statements?
每个准备好的语句将被解析并进一步存储在缓存中,使用它的 MD5 摘要作为键。客户端即将重新注册的相同准备语句将导致服务器将 MD5 摘要与已存在的语句进行匹配,因此应避免。执行已注册的语句将使客户端将 MD5 连同查询参数一起发送到服务器,并且服务器能够使用 MD5 检索缓存的语句,与解析常规 CQL 语句相比执行速度更快。每个缓存的语句也将消耗 Java 堆的一部分,这对应于 MD5 密钥的总大小和语句对象的表示。
Will the server keep all the PS or will it remove the less used ones?
准备好的语句由服务器通过基于ConcurrentLinkedHashMap创建缓存来管理。缓存的容量取决于可用内存:Runtime.getRuntime().maxMemory() / 256
。条目也根据它们的内存使用情况进行加权,如果达到容量,大型语句将首先从缓存中逐出。您可以使用 org.apache.cassandra.metrics.CQL.PreparedStatementsEvicted
JMX 指标监视此行为。
Is there a better solution than restarting Cassandra nodes to clean the PS cache?
我不知道。我也不确定您为什么要这样做,因为将为相同的查询创建相同的 MD5 摘要。另请注意 Java 客户端将自动 re-register prepared statements that cannot be found on the server, e.g. in case it has been evicted from the cache (see also
using the Java client, will closing the Session / Cluster object alleviate this (server side)?
我不这么认为。服务器必须跟踪数百个潜在客户注册了哪些语句,以便安全地清理它们。