我正在尝试通过最小化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工作进程中,并在内存中处理它,这将是一个巨大的速度提升,消除了存储/流出当前大量数据集的需要第一阶段。
- 编辑 -
为了澄清,作业必须从表格,数十亿个分区中读取所有数据。
答案 0 :(得分:1)
将所有分区数据保留在同一个spark worker而不进行洗牌的关键是使用spanByKey
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中订购,所有可行的跨度都必须 按照自然聚类键顺序。