有没有办法有效地计算 Cassandra 中一个非常大的分区的行数?
Is there a way to effectively count rows of a very huge partition in Cassandra?
我有非常庞大的 Cassandra table,其中包含超过 10 亿条记录。我的主键形式如下:“(partition_id, cluster_id1, cluster_id2)
”。现在对于几个特定的 partition_id,我有太多记录,如果不引发超时异常,我无法 运行 对这些分区键进行行计数。
我在cqlsh中运行的是:
SELECT count(*) FROM relation WHERE partition_id='some_huge_partition';
我遇到了这个异常:
ReadTimeout: Error from server: code=1200 [Coordinator node timed out waiting for replica nodes' responses] message="Operation timed out - received only 0 responses." info={'received_responses': 0, 'required_responses': 1, 'consistency': 'ONE'}
我尝试设置 --connect-timeout
和 --request-timeout
,但没有成功。我在 ElasticSearch 中统计了相同的数据,行数大约为 3000 万(同一分区)。
我的 Cassandra 是 3.11.2,CQLSH 是 5.0.1。 Cassandra 集群包含 3 个节点,每个节点有更多的 1T 硬盘(相当老的服务器,超过 8 年)。
简而言之,我的问题是:
- 我怎么算呢?甚至可以在 Cassandra 中计算一个巨大的分区吗?
- 我可以使用带有分区键的 COPY TO 命令作为过滤器,以便我可以在导出的 CSV 文件中对其进行计数吗?
- 有没有一种方法可以在任何分区变得太大之前监控插入过程?
非常感谢高级。
是的,使用 Cassandra 很难处理大分区。确实没有监控特定分区大小的好方法,尽管 Cassandra 会警告在 system.log
中写入大分区。未绑定分区增长是您在创建 table 期间需要解决的问题,它涉及添加额外的(通常基于时间的)分区键,这些分区键源自对您的业务用例的理解。
这里的答案是,您可以使用COPY
命令导出分区中的数据。为了防止它超时,您需要使用 PAGESIZE
和 PAGETIMEOUT
选项,有点像这样:
COPY products TO '/home/aploetz/products.txt'
WITH DELIMITER='|' AND HEADER=true
AND PAGETIMEOUT=40 AND PAGESIZE=20;
这会将 products
table 导出到 pipe-delimited 文件,header,页面大小一次为 20 行,40每个页面获取的第二次超时。
如果仍然超时,请尝试减少 PAGESIZE
and/or 增加 PAGETIMEOUT
.
我发现借助 Spark 和很棒的 Spark Cassandra Connector 库,我终于可以计算一个大的 table 而不会遇到任何超时限制。 Python Spark代码是这样的:
tbl_user_activity = sqlContext.read.format("org.apache.spark.sql.cassandra").options(keyspace='ks1', table='user_activity').load()
tbl_user_activity.where('id = 1').count()
它会 运行 一段时间,但最终会起作用。
我有非常庞大的 Cassandra table,其中包含超过 10 亿条记录。我的主键形式如下:“(partition_id, cluster_id1, cluster_id2)
”。现在对于几个特定的 partition_id,我有太多记录,如果不引发超时异常,我无法 运行 对这些分区键进行行计数。
我在cqlsh中运行的是:
SELECT count(*) FROM relation WHERE partition_id='some_huge_partition';
我遇到了这个异常:
ReadTimeout: Error from server: code=1200 [Coordinator node timed out waiting for replica nodes' responses] message="Operation timed out - received only 0 responses." info={'received_responses': 0, 'required_responses': 1, 'consistency': 'ONE'}
我尝试设置 --connect-timeout
和 --request-timeout
,但没有成功。我在 ElasticSearch 中统计了相同的数据,行数大约为 3000 万(同一分区)。
我的 Cassandra 是 3.11.2,CQLSH 是 5.0.1。 Cassandra 集群包含 3 个节点,每个节点有更多的 1T 硬盘(相当老的服务器,超过 8 年)。
简而言之,我的问题是:
- 我怎么算呢?甚至可以在 Cassandra 中计算一个巨大的分区吗?
- 我可以使用带有分区键的 COPY TO 命令作为过滤器,以便我可以在导出的 CSV 文件中对其进行计数吗?
- 有没有一种方法可以在任何分区变得太大之前监控插入过程?
非常感谢高级。
是的,使用 Cassandra 很难处理大分区。确实没有监控特定分区大小的好方法,尽管 Cassandra 会警告在 system.log
中写入大分区。未绑定分区增长是您在创建 table 期间需要解决的问题,它涉及添加额外的(通常基于时间的)分区键,这些分区键源自对您的业务用例的理解。
这里的答案是,您可以使用COPY
命令导出分区中的数据。为了防止它超时,您需要使用 PAGESIZE
和 PAGETIMEOUT
选项,有点像这样:
COPY products TO '/home/aploetz/products.txt'
WITH DELIMITER='|' AND HEADER=true
AND PAGETIMEOUT=40 AND PAGESIZE=20;
这会将 products
table 导出到 pipe-delimited 文件,header,页面大小一次为 20 行,40每个页面获取的第二次超时。
如果仍然超时,请尝试减少 PAGESIZE
and/or 增加 PAGETIMEOUT
.
我发现借助 Spark 和很棒的 Spark Cassandra Connector 库,我终于可以计算一个大的 table 而不会遇到任何超时限制。 Python Spark代码是这样的:
tbl_user_activity = sqlContext.read.format("org.apache.spark.sql.cassandra").options(keyspace='ks1', table='user_activity').load()
tbl_user_activity.where('id = 1').count()
它会 运行 一段时间,但最终会起作用。