首页 > 其他分享 >日常踩坑_关于cassandra使用了count(1)又又又超时了

日常踩坑_关于cassandra使用了count(1)又又又超时了

时间:2023-09-14 13:35:17浏览次数:45  
标签:count JMX cassandra ms timeout 超时 Cassandra

背景提要

由于习惯了用Mysql和Oracle这种数据库,切换到Cassandra之后真是踩了一系列的坑
本来是一个简单的请求,I just want 简简单单求个表的总行数
而表也不是什么千万级别的大表,just 只是小小的几千条数据而已,然而cassandra非常给面子,本应该在千万级别查询才出的错,出现在了我一张千行数据的小表上
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'}

解决

其实也不算是彻底解决,只是对于我当下可以解决(不过尝试了两千万数据,也可以计数,只是稍微慢一点)
原本的cql: select count(1) from keyspaceName.table_name;
完整的ssh command:sudo -u dean cqlsh 127.0.0.1 --ssl -u cassandra -ppassword -e 'use keyspaceName; select count(1) FROM table_name;' |grep -A2 count | xargs| awk '{print $NF}' 这条命令会最终直接输出行数

修改后的cql:copy keyspaceName.table_name(primary_key) to '/dev/null';
完整的ssh command: sudo -u dean cqlsh 127.0.0.1 --ssl -u cassandra -ppassword -e "copy keyspaceName.table_name(primary_key) to '/dev/null';" | sed -n 5p | sed 's/ .*//'

浅浅解析一下这条命令吧
cqlsh 127.0.0.1 --ssl -u cassandra -ppassword -e "copy keyspaceName.table_name(primary_key) to '/dev/null';

*  cqlsh 是 Cassandra Query Language Shell 的命令行工具,用于与 Cassandra 数据库交互。
*  127.0.0.1 是Cassandra sever
*  --ssl 是连接到 Cassandra 数据库的通信将通过 SSL/TLS 进行加密
*  -u cassandra -ppassword 是登录Cassandra数据库的用户及密码
*  -e 后跟的是实际的 CQL 查询字符串
*  copy keyspaceName.table_name(primary_key) to '/dev/null' 是要执行的 CQL 查询。它指定了要从keyspaceName下的 table_name 表中导出数据,但仅包括指定的 primary_key列,并将结果导出到 /dev/null,这实际上是将结果丢弃。
*   |:这是管道操作符,它将前一个命令的输出传递给下一个命令。
*  sed -n 5p:
     sed 是流编辑器,用于处理文本流的文本处理工具。
     -n 选项用于关闭默认的输出,只输出经过处理的文本。
     5p 是 sed 命令,它表示仅打印第五行。

*   |:再次使用管道操作符,将前一个命令的输出传递给下一个命令。
*   sed 's/ .*//':
    这是另一个 sed 命令,用于处理前一个命令的输出。
    's/ .*//' 是一个替换命令,它会将输入文本中的第一个空格及其后的所有字符替换为空字符串。这样可以提取第五行的第一个单词或字符串。

这条命令最终输出的就是表的总行数了

其他失败的无用尝试

1、网上大批量出现的是第一种更改request timeout的时间
即在cassandra server上更改cassandra.yaml里的如下参数

      sudo nano /etc/cassandra/cassandra.yaml
      # How long the coordinator should wait for read operations to complete
      read_request_timeout_in_ms: 50000
      # How long the coordinator should wait for seq or index scans to complete
      range_request_timeout_in_ms: 100000
      # How long the coordinator should wait for writes to complete
      write_request_timeout_in_ms: 20000
      # How long the coordinator should wait for counter writes to complete
      counter_write_request_timeout_in_ms: 50000
      # How long a coordinator should continue to retry a CAS operation
      # that contends with other proposals for the same row
      cas_contention_timeout_in_ms: 10000
      # How long the coordinator should wait for truncates to complete
      # (This can be much longer, because unless auto_snapshot is disabled
      # we need to flush first so we can snapshot before removing the data.)
      truncate_request_timeout_in_ms: 600000
      # The default timeout for other, miscellaneous operations
      request_timeout_in_ms: 100000

      # How long before a node logs slow queries. Select queries that take longer than
      # this timeout to execute, will generate an aggregated log message, so that slow queries
      # can be identified. Set this value to zero to disable slow query logging.
      slow_query_log_timeout_in_ms: 5000

然后搭配 cqlsh --request-timeout=60000 使用
但实际上,当我手动执行cql时发现,实际返回readTimeout错误返回时花费的时间并没有超过timeout的设置值,
也就是说实际问题不是给cassandra运行cql的时间太短,而是cassandra根本无法正常执行该cql,所以实际需要从cql本身入手,而非超时设置上

2、关于如何正常计数,cassandra给出的官方解答是增加一列计数列counter
我本身没有去尝试这个计数列,因为我的表是一个比较老的表,牵涉很多,增加额外的一列用来计数是一个非常不合理的更改
其次,稍微了解了一下cassandra的这个计数列,该列实际是需要自己手动进行行数的增减的,这非常的不人性化

3、网上提出了可以使用第三方工具或库去进行计数,比较推荐的是 cassandra-count(一个开源小工具)和 使用Cassandra的JMX接口获取总数
cassandra-count:github开源项目cassandra-count
该工具安装运行还是挺简单的,但后续安装之后一直报找不到NoHostAvaliable,没有进一步的研究
但该工具去计算计数时,实际会消耗一些资源,降低性能,所以谨慎选择

Cassandra的JMX接口获取总数(实际配置过程略有些复杂,以下步骤供诸君参考)

* 启用 JMX 监控:
    首先,确保您已经启用了 Cassandra 的 JMX 监控功能。这通常需要在 Cassandra 配置文件中进行配置。查找并编辑  `cassandra-env.sh`  或 `cassandra.in.sh`(取决于Cassandra 版本),并确保以下行没有被注释掉:
    JVM_OPTS="$JVM_OPTS -Dcom.sun.management.jmxremote.port=<JMX_PORT>" 
    将 `<JMX_PORT>` 替换为您希望用于 JMX 连接的端口号。

* 重启 Cassandra: 在修改了配置后,重启 Cassandra 以应用更改。
* 使用 JMX 客户端: 使用 JMX 客户端工具(例如 JConsole、VisualVM 或编程语言中的 JMX 客户端库)连接到正在运行的 Cassandra 实例的 JMX 端口。需要提供连接信息,包括主机名和端口号。
* 浏览 MBeans: 连接到 Cassandra 的 JMX 后,浏览 MBeans(管理 Bean)树以查找与表相关的统计信息。通常,Cassandra 的表信息存储在 MBeans 的 `org.apache.cassandra.db` 部分下。
* 查询表的总行数
  在 MBeans 中找到与表相关的 MBean,查看其属性以获取总行数(RowCount)。通常,表的 MBean 名称可能与表的 keyspace 和表名相关

为什么Cassandra不能进行有效的count计数

在不断的尝试获取一个有效的行数时不停的跳坑,让我对于cassandra的怨气达到了巅峰,为什么一个数据库的能设计成只是求一个行数都如此艰难的地步
1、数据分布和分片
cassandra是分布式架构嘛,所以cassandra将数据分布在了多个节点上,并且使用了分片(sharding) 来处理大量的数据,这意味着数据分散存储在了不同的节点上,要计算总行数时,就需要从所有节点检索并汇总计数,这期间涉及到了网络通信和数据传输,导致了查询变得非常耗时

2、分布式一致性
cassandra强调分布式系统中的高可用性和分区容忍性,为了实现这些目标,cassandra采用的是分布式一致性模型,这意味着在多个节点之间的数据一致性需要经过复杂的协调和通信,这增加了查询的延迟

3、数据模型
Cassandra的数据模型是面向列族(Column Family)的,而不是传统的关系型数据库,这种数据模型适用于高度分布式和横向扩展的场景,但不像传统关系型数据库会优化count查询

4、没有内置索引
Cassandra没有内置的用于计算总行数的索引,这意味着要执行 count 查询,通常需要扫描全表或分区,这在大型表上非常耗时

总之,就是希望cassandra会优化吧

跳坑结束,祝你开心!

标签:count,JMX,cassandra,ms,timeout,超时,Cassandra
From: https://www.cnblogs.com/deanCopy/p/17700367.html

相关文章

  • tomcat报错:java.io.IOException: 您的主机中的软件中止了一个已建立的连接。页面响应
    tomcat报错:java.io.IOException:您的主机中的软件中止了一个已建立的连接。tomcat报错:org.apache.catalina.connector.ClientAbortException:java.io.IOException:您的主机中的软件中止了一个已建立的连接。 出现原因:1、由于客户端在发送请求后,还没等服务器响应就断开了......
  • count() 和 count(1) 有什么区别?哪个性能最好?
    count(*)和count(1)有什么区别?哪个性能最好?count(*)和count(1)没有区别,因为count(*)会优化为count(0)count(字段)的性能是最差的,因为要遍历一遍,并且还要比较是否是null结论:count(*)=count(1)>count(字段)怎么解决呢使用近似值,使用explain命令,返回值有rows列,标识表的近......
  • Bug库____org.springframework.jdbc.IncorrectResultSetColumnCountException: Incorr
    Bug:使用到了spring的jdbctemplate模板使用到以下template.queryForObject(sql,requiredType)template.queryForList(sql,elementType,args)报以下错误org.springframework.jdbc.IncorrectResultSetColumnCountException:Incorrectcolumncount:expected1,actual3检查完......
  • BUG(Spring Framework JdbcTemplate) org.springframework.jdbc.IncorrectResultSetCo
    一.SpringFramework queryForObject问题1.spring4.0之前使用使用jdbctemplate的queryForObject(Stringsql,Object[]args,RowMapper<T>rowMapper)直接放入class类型会报错org.springframework.jdbc.IncorrectResultSetColumnCountException:Incorrectcolumncount:expec......
  • 【题解】CF1830B The BOSS Can Count Pairs
    你考虑,我们观察数据范围,发现可以是\(O(n\sqrtn)/O(n\logn)\)的,我们又看到乘法,便有几个大概的想法:数论分块\(O(\sqrtn)\)枚举其中一个乘数还有什么……(笔者学识浅陋,读者可以帮忙补充)我们可以找到两种\(O(n^2)\)做法:\(O(n^2)\)枚举数对\((i,j)\)然后进行判断。......
  • [ABC319G] Counting Shortest Paths
    [ABC319G]CountingShortestPathsAtcoder:[ABC319G]CountingShortestPaths洛谷:[ABC319G]CountingShortestPathsProblem经典问题:求补图的最短路,边权均为\(1\),并顺带求出\(1\ton\)最短路的数量。\(n\le2\times10^5\)。Solution每次从队列中把最早遍历到的节点......
  • oracle与sqlserver执行count(*)返回的结果兼容
    由于以前都是在sqlserver2005处理,现在客户要求oracle数据库服务器,最初的代码为:allRecordSize=(Integer)rs1.getObject(1);//IntegerallRecordSize=0;当执行的时候报:BigDecimal无法转化为Integer类型为了兼容两者修改后的代码为:Objecto=rs1.getObject(1);System.out.......
  • 阿里云函数计算FC,连接数据库超时的原因
    使用阿里云函数计算,连接sqlserver数据库一直超时 经过分析是sqlserver版本问题,sql2008r2必须升级到SP3  MicrosoftSQLServer2008R2(SP3)-10.50.6000.34(X64)  Aug19201412:21:34  Copyright(c)MicrosoftCorporation EnterpriseEdition(64-bit......
  • [原创]IOCP网络模型设置AcceptEx超时
    关键字:IOCP防止恶意链接;iocp检测只连接不发送数据;iocp设置AcceptEx超时;iocp防止ddos问题起因:(2008年的文章)https://bbs.csdn.net/topics/250032963在写服务器程序,比较常见的一个问题是,当socket连上来以后,它可能继没有数据发送也没有接受。那么这个连接就会挂在那里。假设这......
  • 无涯教程-JavaScript - DCOUNTA函数
    描述DCOUNTA函数返回列表或数据库中符合您指定条件的列中非空白单元格的计数。此函数与DCOUNT函数相似,不同之处在于DCOUNTA函数对所有非空白单元进行计数。DCOUNT函数仅计算包含数值的单元格。语法DCOUNTA(database,field,criteria)争论Argument描述Required/Opti......