是否可以在一个Spark工作程序中读取所有Cassandra分区行?

时间:2016-03-31 00:23:02

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

我正在尝试通过最小化reduceByKey步骤的数量来优化Zipkin Dependencies Spark job以在更少的阶段中运行。数据从下表中读取:

CREATE TABLE IF NOT EXISTS zipkin.traces (
    trace_id  bigint,
    ts        timestamp,
    span_name text,
    span      blob,
    PRIMARY KEY (trace_id, ts, span_name)
)

在那里,单个分区trace_id包含完整的跟踪,并且包含从几行到几百行的任何位置。但是,整个分区由Spark作业转换为非常简单的RDD[((String, String), Long)],将条目数从数十亿减少到几百。

不幸的是,当前的代码是通过

独立读取所有行来实现的
sc.cassandraTable(keyspace, "traces")

并使用两个reduceByKey步骤来提出RDD[((String, String), Long)]。如果有一种方法可以一次性读取整个分区,在一个Spark工作进程中,并在内存中处理它,这将是一个巨大的速度提升,消除了存储/流出当前大量数据集的需要第一阶段。

- 编辑 -

为了澄清,作业必须从表格,数十亿个分区中读取所有数据

1 个答案:

答案 0 :(得分:1)

将所有分区数据保留在同一个spark worker而不进行洗牌的关键是使用spanByKey

https://github.com/datastax/spark-cassandra-connector/blob/master/doc/3_selection.md#grouping-rows-by-partition-key

CREATE TABLE events (year int, month int, ts timestamp, data varchar, PRIMARY KEY (year,month,ts));

sc.cassandraTable("test", "events")
  .spanBy(row => (row.getInt("year"), row.getInt("month")))

sc.cassandraTable("test", "events")
  .keyBy(row => (row.getInt("year"), row.getInt("month")))
  .spanByKey

如果没有shuffle,那么所有的修改都将在适当的位置完成,并作为迭代器一起流水线化。

请务必注意警告:

  

注意:这仅适用于按顺序排序的数据。因为数据是   通过聚类键在Cassandra中订购,所有可行的跨度都必须   按照自然聚类键顺序。