这是我保存到Cassandra表的RDD的内容。 但看起来第一行先写入,然后第一行覆盖它。所以我最终输出不好。
(494bce4f393b474980290b8d1b6ebef9,2017-02-01,PT0H9M30S,WEDNESDAY) (494bce4f393b474980290b8d1b6ebef9,2017-02-01,PT0H10M0S,WEDNESDAY)
有没有办法强制写入Cassandra的行的顺序。 请帮忙。 感谢
答案 0 :(得分:4)
在单个任务中,执行是确定性的,但可能不是 订购你期待。这里有两件事要考虑。
可能不是。只有当您的数据真正分散时,这才真正重要 在RDD中。如果特定Cassandra分区的条目分布在其中 多个Spark分区然后Spark执行的顺序可能会搞乱 你的upsert。考虑
Spark Partition 1 has Record A
Spark Partition 2 has Record B
Both Spark Partitions have work start simultaneously, but Record B is
reached before Record A.
但我认为这不太可能是问题。
您遇到的问题很可能是常见问题:the order of statements in my batch is not respected。这个问题的核心是Cassandra批次中的所有语句都是同时执行的。"这意味着如果任何Primary Key
存在冲突,则需要解决冲突。在这些情况下,Cassandra为所有冲突选择更大的单元格值。由于连接器自动批处理写入同一分区键,因此最终会出现冲突。
您可以在示例中看到这一点,保留较大的值(PT0H9M30S)并丢弃较小的值(PT0H10M0S)。问题不在于订单,而是批处理正在发生的事实。
非常仔细。我会考虑采取一些方法。
最好的选择是不要根据时间进行upsert。如果您有PRIMARY_KEY
的多个条目,但只想要最后一个,请在点击Cassandra之前减少Spark。在尝试写入之前删除不需要的条目将节省Cassandra集群的时间和负载。否则你使用Cassandra作为一个相当昂贵的重复数据删除机。
更糟糕的选择是禁用Spark Cassandra Connector中的批处理。如果您只关心Spark分区中的顺序,这会损害性能,但会解决问题。如果您有多个Spark分区,这仍然会导致冲突,因为您无法控制它们的执行顺序。
状态不好。订单很糟糕。如果可能的话,将您的系统设计为幂等的。如果有多条记录并且您知道哪些记录很重要,请在进入分布式LWW系统之前删除那些记录。
答案 1 :(得分:3)
这完全取决于您所制作的表的定义。无法保证在分区键(主键的第一部分)中进行排序。
主键的其余部分用于对分区内的键进行排序。这是您的问题所在。您必须定义群集列。
这里描述: https://docs.datastax.com/en/cql/3.1/cql/ddl/ddl_compound_keys_c.html
插入的排序仍然很重要,但只有在有两个相同信息的意义上,最后一个获胜。我认为这不是这种情况。
另外,您可以考虑将“PT0H9M30S”中的信息放在群集列下,以便保留数据并且不会覆盖它。
答案 2 :(得分:1)
Cassandra是时间序列数据库。您应该设计表格,以免发生过度写入。或者如果要编写最早/最晚的时间戳,则应使用reduceByKey之类的转换来减少RDD,以仅保留特定键的最早/最新时间戳信息。