【问题标题】:RangeError: index out of range when connect to cassandra databse in node jsRangeError:在节点js中连接到cassandra数据库时索引超出范围
【发布时间】:2017-06-26 10:10:38
【问题描述】:

我正在开发 NodeJS 项目,我尝试使用 cassandra-driver 包从存储在 cassandra 数据库中的表中选择数据, 我使用这一行启动客户端连接:

const cassandra = require('cassandra-driver');
const cassandraClient = new cassandra.Client({ contactPoints: ['192.168.0.253'], keyspace: 'test' });

有时候我调用url,引擎会成功获取结果,顺便说一下有时候会报这个错误:

{ [RangeError: index out of range]
  coordinator: '192.168.0.253:9042',
  query: 'SELECT * FROM table where hidden=false ALLOW FILTERING' }

这个错误通常在最近更新 cassandra 表时引发! 我不知道这是否重要,但是有另一个服务连接到 cassandra 数据库并插入新数据,这与问题有关吗?我该如何解决这个错误?

如果这两个服务是这个错误的原因,当有活动的服务写入cassandra表时,有没有办法让cassandra表不被阻塞(读取和写入),意味着ghost读取没有问题?

堆栈错误:

{ [RangeError: index out of range]
  coordinator: '192.168.0.253:9042',
  query: 'SELECT * FROM table where hidden=false ALLOW FILTERING' }
RangeError: index out of range
    at checkOffset (buffer.js:663:11)
    at Buffer.readInt32BE (buffer.js:828:5)
    at Function.Long.fromBuffer (/home/l.alassadi/alarm-socket/node_modules/cassandra-driver/lib/types/index.js:466:25)
    at Encoder.decodeLong (/home/l.alassadi/alarm-socket/node_modules/cassandra-driver/lib/encoder.js:133:17)
    at Encoder.decodeTimestamp (/home/l.alassadi/alarm-socket/node_modules/cassandra-driver/lib/encoder.js:142:26)
    at Encoder.decode (/home/l.alassadi/alarm-socket/node_modules/cassandra-driver/lib/encoder.js:1202:18)
    at Parser.parseRows (/home/l.alassadi/alarm-socket/node_modules/cassandra-driver/lib/streams.js:377:36)
    at Parser.parseResult (/home/l.alassadi/alarm-socket/node_modules/cassandra-driver/lib/streams.js:335:10)
    at Parser.parseBody (/home/l.alassadi/alarm-socket/node_modules/cassandra-driver/lib/streams.js:185:19)
    at Parser._transform (/home/l.alassadi/alarm-socket/node_modules/cassandra-driver/lib/streams.js:137:10)

【问题讨论】:

  • 不确定那里会发生什么。你能打印错误的堆栈吗(console.log(err.stack))。另外,您使用的是哪个版本的 nodejs 驱动程序,您的 C* 集群的版本是什么?
  • @AndyTolbert 我已经打印了错误堆栈并编辑了问题。卡桑德拉版本:[cqlsh 5.0.1 |卡桑德拉 3.9 | CQL 规范 3.4.2 | Native protocol v4] Node js 版本:v5.9.1 cassandra-driver 版本:3.2.0 但是不明白你说的c*集群版本是什么意思?
  • 它看起来像一个驱动程序错误......你能在开发环境中重现它吗?你能发布表格架构吗?

标签: javascript node.js cassandra


【解决方案1】:

我在从表中提取数据时收到了同样的错误。由于错误在Buffer.readInt32BE,猜测是在解析可能是数字类型的字段时。

查看堆栈跟踪,转到函数Function.Long.fromBuffer 并打印传递的bytes 参数。现在,看看我的查询,它有两个Timestamp 类型的字段,甚至可以表示为Integer 类型。

我的查询在这里select item_id, created_date, modified_date from mytable。修改了库方法以打印在encoder.js 中遇到的值:

 this.decodeLong = function (bytes) {
    console.log("---->" + Long.fromBuffer(bytes));
    return Long.fromBuffer(bytes);
 };

在执行我的服务方法时发现前三个值被打印出来。由于这是第四项失败,并且我的查询只有两种数字类型,因此得出的结论是异常是在解析第二行的 modified_date 字段期间发生的。

尝试更新cassandra-driver,问题依然存在。删除导致问题的行并解决此问题。所以,我想,再次将字段更新为不同的值应该可以解决这个问题。看起来与 cassandra 数据不一致。

【讨论】:

    【解决方案2】:

    TLDR 已在 cassandra-driver v3.6.0

    中修复

    RangeError 是由cassandra-driver 中的问题引起的,特别是它如何解码来自数据库服务器的数据。它出现在以下情况:

    1. 该表包含一个 map 类型的列
    2. 地图的值类型不可为空
    3. 所选行具有所述列
    4. 列(地图)的值有一个没有值的键(不太清楚这怎么可能,但确实如此)

    这里是所有可以为空的类型:

    • 文字
    • ascii
    • varchar
    • 自定义
    • 斑点

    长话短说,当映射内的不可为空类型(如 int)的字段被序列化为空缓冲区时,驱动程序不会处理这种情况。在这种情况下,驱动程序无条件地尝试从缓冲区中读取与类型大小相等的字节数,并因上述错误而失败。

    对此进行调查后,我已向cassandra-driver 提交了fix。 3.6.0已经接受并发布。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-07-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-04
      • 2021-04-25
      • 2016-03-29
      • 1970-01-01
      相关资源
      最近更新 更多