在Cassandra中丢失大量插入数据

时间:2017-03-14 10:33:11

标签: cassandra spring-data spring-data-cassandra

我在Cassandra中丢失插入数据时遇到了麻烦。

我正在通过Stream读取来自csv文件的大量插件。由于查询不同,数据被复制到两个表中。每隔30,000个元素我将数据拆分为新分区(chunkCounter)。

 private PersistenceInformation persist(final String period, final String tradePartner, final Integer version, Stream<Transaction> transactions) {

    int elementsInChunkCounter = 0;
    int chunkCounter = 1;
    int elementCounter = 0;

    Iterator<Transaction> iterator = transactions.filter(beanValidator).iterator();

    List<List<?>> listImportData = new ArrayList<>(30000);
    List<List<?>> listGtins = new ArrayList<>(30000);

    while (iterator.hasNext()) {

        Transaction tr = iterator.next();

        List<Object> importTemp = new ArrayList<>(9);
        importTemp.add(period);
        importTemp.add(tradePartner);
        importTemp.add(version);
        importTemp.add(chunkCounter);
        importTemp.add(tr.getMdhId());
        importTemp.add(tr.getGtin());
        importTemp.add(tr.getQuantity());
        importTemp.add(tr.getTransactionId());
        importTemp.add(tr.getTimestamp());
        listImportData.add(importTemp);

        List<Object> gtinTemp = new ArrayList<>(8);
        gtinTemp.add(period);
        gtinTemp.add(tradePartner);
        gtinTemp.add(version);
        gtinTemp.add(chunkCounter);
        gtinTemp.add(tr.getMdhId());
        gtinTemp.add(tr.getGtin());
        gtinTemp.add(tr.getQuantity());
        gtinTemp.add(tr.getTimestamp());
        listGtins.add(gtinTemp);

        elementsInChunkCounter++;
        elementCounter++;

        if (elementsInChunkCounter == 30000) {
            elementsInChunkCounter = 0;
            chunkCounter++;

            ingestImportData(listImportData);
            listImportData.clear();

            ingestGtins(listGtins);
            listGtins.clear();
        }
    }

    if (!listImportData.isEmpty()) {
        ingestImportData(listImportData);
    }

    if (!listGtins.isEmpty()) {
        ingestGtins(listGtins);
    }

    return new PersistenceInformation();
}

private void ingestImportData(List<List<?>> list) {
    String cqlIngest = "INSERT INTO import_data (pd, tp , ver, chunk, mdh_id, gtin, qty, id, ts) VALUES (?,?,?,?,?,?,?,?,?)";
    cassandraOperations.ingest(cqlIngest, list);
}

private void ingestGtins(List<List<?>> list) {
    String cqlIngest = "INSERT INTO gtins (pd, tp, ver, chunk, mdh_id, gtin, qty, ts) VALUES (?,?,?,?,?,?,?,?)";
    cassandraOperations.ingest(cqlIngest, list);
 }

这很好用,直到我注意到有时数据集丢失了。第二个表(gtins)中有一个条目,但未插入主表中的数据集。应用程序计算了它,但数据库没有写它。

该表以这种方式构建:

CREATE TABLE import_data (
    tp text,
    pd text,  
    ver int,
    chunk int,
    mdh_id uuid,
    gtin text,
    qty float,
    id text,
    ts timestamp
PRIMARY KEY ((tp, pd, ver, chunk), ts, mdh_id)) WITH CLUSTERING ORDER BY (ts DESC);

mdh_id是我的应用程序中的UUID,因此每个数据集都有一个唯一的密钥,并且不会被意外覆盖。

Cassandra日志文件甚至没有显示警告。

目前我正在评估BatchStatement,但由于5kb的限制,我需要插入每个第8个数据集,否则数据库会丢失更多的条目。

我的申请中出现任何错误的建议都非常感谢。非常感谢。

0 个答案:

没有答案