RangeError:连接到节点js中的cassandra数据库时索引超出范围

时间:2017-02-08 16:53:03

标签: javascript node.js cassandra

我正在研究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)

2 个答案:

答案 0 :(得分:1)

TLDR 已在cassandra-driver v3.6.0版本中修复


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

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

这里都是可空类型:

  • 文本
  • ascii
  • varchar
  • 自定义
  • blob

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

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

答案 1 :(得分:0)

我在从表中获取时收到了同样的错误。由于错误位于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数据不一致。