我使用apachespark从cassandra读取数据,而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
错误日志是直接的,由于逻辑删除扫描,读取失败。
我不明白的是,我做同样的工作已经一年多了,从来没有遇到过这个问题。但是,这是次要的。首先我想知道我该怎么解决这个问题?
可以为未传递的列值创建墓碑,因为我使用cassandrainsertjson特性来插入doc。在此确认,这种方法将创建墓碑。
我该怎么解决这个问题?基于非空值创建多个insert查询是一个复杂的选项。
在我看来,即使插入虚拟值也不切实际。所有从这些表中读取数据的客户机都需要进行更改。
我个人认为,如果一个列在json中不存在,cassandra就不应该为它创建墓碑。
解决这个问题的其他选择是什么?
1条答案
按热度按时间hc8w905p1#
你有几种可能:
不要将数据作为json插入,而是在应用程序中解析json,并使用
unset
您可以通过将jsonMap到pojo,并使用还支持将null替换为unset
. 这是最好的方法,因为tombstone将影响所有应用程序和cassandra本身。但真正的解决方案将取决于您的用例—您是只插入新数据,还是同时更新现有数据?在后一种情况下,您需要确保覆盖以前的数据减少spark应用程序中的页面大小,以在一个页面中读取较少的行。这是由
spark.cassandra.input.fetch.size_in_rows
参数,在文档中描述。如果将dse与dse分析一起使用,则可能需要禁用连续分页