我使用 Apache Spark 从 Cassandra 读取数据,这在后台是基于令牌范围的扫描。但是,最近我在从我的 Cassandra 表中读取数据时看到了很多失败。
读取失败,原因如下:
Caused by: com.datastax.driver.core.exceptions.ReadFailureException: Cassandra failure during read query at consistency LOCAL_ONE (1 responses were required but only 0 replica responded, 1 failed)
at com.datastax.driver.core.exceptions.ReadFailureException.copy(ReadFailureException.java:85)
at com.datastax.driver.core.exceptions.ReadFailureException.copy(ReadFailureException.java:27)
at com.datastax.driver.core.DriverThrowables.propagateCause(DriverThrowables.java:37)
at com.datastax.driver.core.DefaultResultSetFuture.getUninterruptibly(DefaultResultSetFuture.java:245)
at com.datastax.driver.core.AbstractSession.execute(AbstractSession.java:68)
当我检查系统日志时,我发现了以下问题:
ERROR [ReadStage-1] 2020-04-09 10:25:59,701 StorageProxy.java:1896 - Scanned over 100001 tombstones during query 'SELECT * FROM my_keyspace.my_table WHERE token(id) > -5868586221781016365 AND token(id) <= -5347313590141106513 LIMIT 5000' (last scanned row partion key was (my_key_1)); query aborted
错误日志是直截了当的,由于墓碑扫描,读取失败。
我没有得到的是,我运行同一个 Spark 工作一年多了,从来没有遇到过这个问题。但是,那是次要的。首先我想知道我该如何解决这个问题?
可以为未传递的列值创建墓碑,因为我使用 Cassandra Insert Json 功能插入文档。在这里确认,这种方法将创建墓碑。
我该如何解决?基于非空值创建多个插入查询是一个复杂的选项。
在我看来,即使插入虚拟值也是不切实际的。从这些表中读取数据的所有客户端都需要进行更改。
如果 JSON 中不存在列,我个人认为 Cassandra 永远不应该为列创建 Tombstone。
解决此问题的其他选择是什么?