如何有效地使用spark来读取具有分区热点的cassandra数据?

时间:2017-06-09 19:36:57

标签: apache-spark cassandra spark-cassandra-connector

从我能说的一切,当从cassandra读取时,spark每个cassandra分区最多使用一个任务。不幸的是,我在cassandra中有一些非常不平衡的分区(糟糕的初始表设计)。我需要将这些数据读入一个新的表格,这个表格将更好地设计用于处理热点,但任何使用普通火花通道的尝试都无法有效地工作;我留下了一些永远运行的任务(10+),处理那些巨大的分区键。

为了让您了解规模,这是一个大约1.5TB的表,分布在5台服务器上,复制因子为3;每节点约500GB。

欢迎其他想法,但只是转储到CSV可能不是一个现实的选择。

到目前为止,物化视图创建也是一个禁忌;它需要花费很长时间,至少在3.0.8上,在创建过程中几乎没有监控。

1 个答案:

答案 0 :(得分:3)

这是一个难以自动解决的难题如果你知道你的数据是如何在真正庞大的文件中分发的,我可以给你一个选择。

不是使用单个RDD / DataFrame来表示您的表,而是将其拆分为多个已合并的调用。

基本上你想要这样做

鉴于我们最大的分区是这样设置的

Key1 -> C1, C2, C3, ..., C5000000

我们知道一般来说C的分发方式如

Min C = 0
Max C = 5000000
Average C = 250000

我们可以猜测,我们可以通过每100K C值进行范围下推来非常好地切割这些大型分区。

val interval = 100000
val maxValue = 500000
sc.union(
 (0 until maxValue by interval).map{ lowerBound => 
   sc.cassandraTable("ks", "tab")
     .where(s"c > $lowerBound AND c < ${lowerBound + interval}")
  }
)

我们最终得到了更小的分区(可能还有许多空分区),但这应该让我们成功地削减了这些巨大的分区。只有在可以计算出分区中值的分布时才能这样做。

注意::联合数据帧

也可以