【问题标题】:Cassandra is missing data when loading a csv with cassandra-loader使用 cassandra-loader 加载 csv 时,Cassandra 缺少数据
【发布时间】:2018-08-09 20:36:42
【问题描述】:

我在 Ubuntu 16.04 上使用带有两个节点的 Cassandra 3.11.3。 我将在这里使用的键空间和表是:

## Create a keyspace
CREATE KEYSPACE sto
WITH REPLICATION = { 
'class' : 'SimpleStrategy', 
'replication_factor' : 1 
} ;
## Create a table
CREATE TABLE sto.cartespuce_numligne_date (
numcarteserie text,
codetypetitre int,
typetransaction int,
heuretransaction float,
numservice int,
numligne text,
direction text,
heureligne float,
numjour text,
numarret text,
numbus int,
date date,
PRIMARY KEY (numligne, date) 
) WITH CLUSTERING ORDER BY (date DESC);

我将一个包含 50,000 行的小型数据集上传到此表

numligne,date,codetypetitre,direction,heureligne,heuretransaction,numarret,numbus,numcarteserie,numjour,numservice,typetransaction
33,2017-12-07,144,Nord,13.88,15.27,2190,808,1229320749340288,1,268,2
749,2017-12-08,144,Nord,6.93,7.35,1459,507,1229320749340288,1,548,1

使用 cassandra-loader https://github.com/brianmhess/cassandra-loader

我可以使用 CQL 副本,但这是进一步加载的初步测试,我需要 cassandra-loader。

我加载了csv文件data.csv:

cassandra-loader -f data.csv -host my-ip-address -schema "sto.cartespuce_numligne_date(numligne,date,codetypetitre,direction,heureligne,heuretransaction,numarret,numbus,numcarteserie,numjour,numservice,typetransaction)"

处理运行顺利,以如下日志结束:

*** DONE: data.csv  number of lines processed: 50000 (50000 inserted)

但是当我用 CQL 计算行数时:

cqlsh> SELECT COUNT(*) FROM sto.cartespuce_numligne_date;

count
-------
9877

比较特殊情况,很明显数据库中缺少数据。我发现存储的数据和丢失的数据没有区别。

我怎样才能丢失 80% 的数据?

【问题讨论】:

  • 在您的 csv 源文件中...组合 numligne - date 是唯一的吗?
  • 不,你可以有几行具有相同的组合 numligne-date。例如“200 2018-01-27”作为键多次出现。
  • 你的表的主键是numligne,date。由于您的 csv 文件中的数据根据​​相同的主键不是唯一的,因此即使您进行插入,cassandra 也只会更新这些条目。举个例子,如果在第 43 行你有组合 33,2017-12-07,...这将被插入。如果在第 2000 行你有相同的组合,当这个插入运行时,Cassandra 实际上会进行更新,因为该键已经在数据库中。

标签: cassandra


【解决方案1】:

你的表的主键是 numligne, date。

由于您的 csv 文件中的数据根据​​相同的主键不是唯一的,因此即使您进行插入,cassandra 也只会更新这些条目。

举个例子,如果在第 43 行你有组合 33,2017-12-07,...这将被插入。如果在第 2000 行你有相同的组合,当这个插入运行时,Cassandra 实际上会做一个更新,因为那个键已经在数据库中了。

INSERT 和 UPDATE 操作都是upsert 操作。一些关于INSERTUPDATE 命令的进一步阅读。

为了避免这种情况,您可以定义另一个主键,以便每行都有一个唯一键,或者您可以编写自己的加载器,使用 IF NOT EXISTS 插入,这样它仅在行不存在时插入(请参阅INSERT 命令的链接,段落仅当行不存在时才插入行)。

Cassandra 提供了自己的COPY 命令,但是

该过程会验证 PRIMARY KEY 并更新现有记录。

检查您正在使用的工具的代码后,我可以看到INSERT command being used 没有使用 IF NOT EXISTS 因此如果密钥已存在,它也会更新。

【讨论】:

  • 所以键的组合必须始终是唯一的。我添加了一些其他变量以确保每一行的唯一性,并且我的数据现在都已加载。谢谢霍里亚。