[Cassandra经验谈]select count(*) 超时

1、为什么需要这个?
在向Cassandra中插入一些数据之后,往往想知道插入了多少条记录,这个时候可以通过select count(*) from test_table来进行查询。
当数据比较少的时候,该cql语句能正确得到查询结果,但是当插入的记录条数比较多的时候,非常容易导致超时。在命令行中有下面的提示
OperationTimedOut: errors={}, last_host=127.0.0.1
原文链接: http://http://www.flyml.net/2016/09/13/cassandra-tutorial-select-count-star-timeout-exception/
2、为什么会超时?
超时的原因很简单,当执行select count(*)的时候,和在数据库中执行select * from 的效果是相似的,都需要在Cassandra中的所有节点中查询。 这其实不只是Cassandra的问题,而是所有分布式系统的共同的问题,要统计记录的条数不是那么容易的一件事情。
http://www.flyml.net/2016/09/13/cassandra-tutorial-select-count-star-timeout-exception/
3、超时的几种解决方案?
3.1 在cqlsh命令行中使用COPY命令
cqlsh:keyspacename>COPY test_table TO ‘/home/user/data.csv’;
Using 7 child processes
Starting copy of keyspacename.test_table with columns […].
Processed: 20364153 rows; Rate: 7343 rows/s; Avg. rate: 32270 rows/s
20364153 rows exported to 1 files in 10 minutes and 31.083 seconds.
但是COPY命令和select count(*)的问题是一样的,也需要全集全扫描,可扩展性并不好, 而且实测发现,即使这种方法能得到记录的条数,但是也不是非常准确。举个例子:
原始条数有2003W,但是通过这样导出的方式,记录条数可能只有2000W条。 也就是说,会有千分之几的丢失数据的概率。
3.2 可以大概限制一下返回记录的条数,例如将一个查询分为两个以上不相交的查询

 

3.3 在进入cqlsh的时候重新设定超时时间

例如上面的超时时间设定为2分钟,具体设定多长时间需要根据集群的性能和查询数据的多少来合理设置,例如在我们的集群中有8个节点(8core i5,32G),复制策略是简单3份复制,当记录条数达到2000w的时候,超时时间大概需要设15分钟以上
3.4 通过配置文件修改超时时间
没有该文件的话可以手工创建该文件

3.5 直接修改cqlsh.py中的client_timeout
需要说明的是,3.4的优先级要高于3.5,推荐使用3.4的方法来修改,而不要修改cqlsh的启动脚本
3.6 使用一个第三方工具来进行统计[不推荐]
这个工具的原理很简单,就是通过numSplits参数分解token的范围来限制每次查询返回结果的记录条数从而避免超时的发生。
具体用法请参考上面的网页,例子
./cassandra-count -host 127.0.0.1 -keyspace test -table itest
但是实测的结果,该工具返回的结果比较有问题,不准确。千万不要被这个工具的结果给蒙骗了。这里之所以将这个方法写下来,就是提醒各位看官不要跳坑了。
http://www.flyml.net/2016/09/13/cassandra-tutorial-select-count-star-timeout-exception/
本文为原创文章,转载请注明出处
点赞
  1. 羊八井说道:

    请问你们俱体是怎么解决这个问题的了?
    我想到的一个方案是第另一个库的一个自增字段时保存count数量,就是每次写入Cassandra时都在另一个库里将一个计数字段+1.
    这样做需要在编程语言里来处理这个问题了,有点麻烦。

    1. rangerwolf说道:

      目前其实没有很好的办法, 用的是Spark读取全部数据再count一把~
      解决方案确实很重

发表评论

电子邮件地址不会被公开。 必填项已用*标注