有没有办法有效地计算Cassandra中一个非常大的分区的行数?

时间:2018-08-08 10:56:13

标签: cassandra cqlsh

我有一个非常庞大的Cassandra表,其中包含超过10亿条记录。我的主键格式如下:“ (partition_id, cluster_id1, cluster_id2)”。现在,对于几个特定的​​partition_id,我的记录太多了,如果没有引发超时异常,就无法在这些分区键上运行行计数。

我在cqlsh中运行的是:

SELECT count(*) FROM relation WHERE partition_id='some_huge_partition';

我遇到了这个例外:

  

ReadTimeout:服务器错误:代码= 1200 [协调器节点等待副本节点的响应超时] message =“操作超时-仅收到0个响应。 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 HDD(相当陈旧的服务器,已经使用了8年以上)。

简而言之,我的问题是:

  1. 我怎么算呢?甚至有可能在Cassandra中计算出一个巨大的分区吗?
  2. 我可以将COPY TO命令与分区键一起用作过滤器,以便可以在导出的CSV文件中进行计数吗?
  3. 有没有办法在任何分区变得太大之前监视插入过程?

非常感谢。

2 个答案:

答案 0 :(得分:1)

是的,使用Cassandra很难处理大型分区。尽管Cassandra会警告您不要在system.log中写入较大的分区,但实际上并没有一种监视特定分区大小的好方法。无限分区增长是您在创建表期间需要解决的问题,它涉及添加一个额外的(通常是基于时间的)分区键,该键是从了解您的业务用例中得出的。

这里的答案是,您可能可以使用COPY命令导出分区中的数据。为了避免超时,您需要使用PAGESIZEPAGETIMEOUT选项,如下所示:

COPY products TO '/home/aploetz/products.txt'
  WITH DELIMITER='|' AND HEADER=true
  AND PAGETIMEOUT=40 AND PAGESIZE=20;

这会将products表导出到一个由管道分隔的文件,该文件带有标题,页面大小一次为20行,每次提取页的超时时间为40秒。

如果仍然存在超时,请尝试减少PAGESIZE和/或增加PAGETIMEOUT

答案 1 :(得分:0)

我发现,有了Spark和令人敬畏的Spark Cassandra Connector库,我终于可以在不遇到任何超时限制的情况下计算一个大表了。 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()

它会运行一段时间,但最终会起作用。