据我所知,spark 在从 cassandra 读取数据时,每个 cassandra 分区最多使用一个任务。不幸的是,我在 cassandra 中有几个非常不平衡的分区(糟糕的初始表设计)。我需要将该数据读取到一个新表中,该表将更好地设计用于处理热点,但任何使用正常 Spark 途径进行的尝试都不会有效;我只剩下一些永远运行的任务(10 多个),处理那几个巨大的分区键。
为了让您了解规模,这是在一个大小约为 1.5TB 的表上工作,分布在 5 个服务器上,复制因子为 3; ~ 每个节点 500GB。
欢迎提出其他想法,但仅转储到 CSV 可能不是一个现实的选择。
到目前为止,物化 View 的创建也是不行的;它花费的时间太长了,至少在 3.0.8 上,创建过程中几乎没有监控。
最佳答案
这是一个无法真正自动解决的难题,但是如果您知道您的数据在非常大的文件中是如何分布的,我可以给您一个选择。
与其使用单个 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}")
}
)
我们最终得到了更多更小的分区(可能还有很多空分区),但这应该让我们成功地减少了那些巨大的分区。但这只有在您可以计算出分区中值的分布时才能完成。
注意::合并数据帧也可能发生同样的事情
关于apache-spark - 如何有效地使用spark读取具有分区热点的cassandra数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44465516/