#node.js #cassandra #scylla
#node.js #кассандра #scylla
Вопрос:
У меня есть таблица с именем domains , в которой есть 2 столбца, один столбец представляет собой строку с именем domain, которая является первичным ключом, а второй столбец называется ip_addresses и представляет собой набор адресов inet.
Код:
const cassandra = require('cassandra-driver');
const readline = require('readline');
const fs = require('fs');
const client = new cassandra.Client({
localDataCenter: 'us-east',
contactPoints: ['REDACTED'],
keyspace: 'default_keyspace'
});
const readInterface = readline.createInterface({
input: fs.createReadStream('./domains'),
output: null,
console: false
});
readInterface.on('line', async (line) => {
const splitLine = line.split(',')
const domain = splitLine[0]
splitLine.shift()
const query = `INSERT INTO domains (domain, ip_addresses) VALUES(?, ?);`;
const parsed = splitLine.map(e => `'${e}'`)
const ips = `{${parsed.join(',')}}`
console.log("IPS ", ips)
console.log('DOMAIN', domain)
client.execute(query, [ domain, ips ]).then((result) => console.log('User with email %s', result.rows[0])).catch(e => console.error(e))
});
console.log("DONE")
Значения:
IP-адреса: {'172.217.15.110'}
ДОМЕН: google.com
Ошибка гласит следующее:
ResponseError: marshaling error: read_simple_bytes - not enough bytes (requested 841888305, got 10) Backtrace: 0x326f94d
0xea40d6
0xea42a6
0xea44f1
0x17cba2e
0x17d1644
0x17d1a18
0x14ea92e
0x14ec4b6
0x15cd85e
0x15d2801
0x15aa827
0x15b1634
0x15b30fc
0x15b3f9f
0x15b5d8b
0x15b5dad
0x15baa48
0x2d7d4bc
0x2dda680
0x2dda88f
0x2e0f705
0x2d79e69
0x2d7af1e
0xd2ff96
/opt/scylladb/libreloc/libc.so.6 0x271a2
0xc5502d
Что я могу сделать, чтобы исправить это?
Спасибо
Ответ №1:
Похоже, драйвер не смог правильно сериализовать набор IP-адресов. Я не node.js эксперт, но я предполагаю, что драйвер просто не может вывести правильный тип из "{'172.217.15.110'}"
строки и просто сериализует его как строку.
Вот почему я думаю, что драйвер отправил что-то, что на самом деле не является набором IP-адресов: Scylla вернула сообщение об ошибке, сообщающее, что размер буфера, по-видимому, равен 841888305
. Это число представлено в шестнадцатеричном виде 322E3231
, что, в свою очередь, подозрительно похоже на часть строки ASCII… и он фактически представляет "2.21"
в ASCII, который является подстрокой строкового представления IP-адреса, который вы пытались отправить.
В CQL большинство типов сериализуются в форме [4 bytes of length][data]
. Scylla определенно проанализировала часть вашей строки IP как длину, что означает, что она ожидала другого расположения данных.
Вы должны просмотреть документацию и посмотреть, как сообщить драйверу, что на самом деле вы пытаетесь отправить набор IP-адресов, который является типом CQL set<inet>
. Вот как мне удалось ввести правильные данные из node.js в Сциллу, на основе вашего кода (я жестко закодировал адрес для простоты, но вы должны понять идею):
readInterface.on('line', async (line) => {
const splitLine = line.split(',')
const domain = splitLine[0]
splitLine.shift()
const query = `INSERT INTO domains (domain, ip_addresses) VALUES(?, ?);`;
const ips = [cassandra.types.InetAddress.fromString('127.0.0.1')]
console.log("IPS ", ips)
console.log('DOMAIN', domain)
client.execute(query, [ domain, ips ]).then((result) => console.log('User with email %s', result.rows[0])).catch(e => console.error(e))
});
Ответ №2:
Похоже, что Scylla разбилась. Какую версию вы запускаете и какое сообщение в журнале? Из этого можно получить трассировку стека, вы можете следовать процедуре в вики. Если вы используете старую версию, просто обновите ее до поддерживаемой и выполните повторное тестирование.
Комментарии:
1. Не сбой 🙂 Наш десериализатор просто печатает трассировку каждой неудачной десериализации, но после этого узел остается стабильным и работает. Я изложу свое подозрение в собственном ответе