【问题标题】:Spark and cassandra, range query on clustering keySpark和cassandra,集群键的范围查询
【发布时间】:2016-07-21 12:07:46
【问题描述】:

我有以下结构的 cassandra 表:

创建 TABLE 表 ( 关键整数, 时间时间戳, 测量浮动, 主键(键、时间) );

我需要创建一个 Spark 作业,该作业将从上一个表中读取数据,在指定的开始和结束时间戳内进行一些处理,并将结果刷新回 cassandra。

所以我的 spark-cassandra-connector 将不得不对集群 cassandra 表列进行范围查询。

如果我这样做会有任何性能差异:

sc.cassandraTable(keyspace,table).
as(caseClassObject).
filter(a => a.time.before(startTime) && a.time.after(endTime).....

所以我正在做的是将所有数据加载到 Spark 并应用过滤

或者如果我这样做:

sc.cassandraTable(keyspace, table).
where(s"time>$startTime and time<$endTime)......

过滤 Cassandra 中的所有数据,然后将较小的子集加载到 Spark。

范围查询的选择性约为 1% 查询中不可能包含分区键。

这两种解决方案中的哪一种更受欢迎?

【问题讨论】:

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


    【解决方案1】:
    sc.cassandraTable(keyspace, table).where(s"time>$startTime and time<$endTime)
    

    会快得多。您基本上是在第一个命令中进行完全抓取的百分比(如果您只提取数据的 5% 的总工作的 5%)来获取相同的数据。

    在第一种情况下,你是

    1. 从 Cassandra 读取所有数据。
    2. 序列化每个对象,然后将其移动到 Spark。
    3. 然后最后过滤所有内容。

    在第二种情况下,你是

    1. 只从 C* 中读取您真正需要的数据
    2. 仅序列化这个微小的子集
    3. 没有第3步

    作为附加注释,您还可以将您的案例类类型直接放入调用中

    sc.cassandraTable[CaseClassObject](keyspace, table)
    

    【讨论】:

    • 我认为 1/20 会很夸张。主要是因为时间是集群的关键,所以 cassandra 无论如何都会进行全表扫描。但它确实会节省在将数据从 cassandra 移动到 spark 之间所花费的时间,这可能是很多数据。
    • 我绝对希望它与读取的数据量成正比。 1) 需要读取的 sstable 数量会少得多,因为范围扫描不需要读取所有 sstable,而不进行范围扫描。 2) 必须通过 C* Jvm 的对象数量会少得多,这同样是要分配和反序列化的对象数量要少得多。因此需要更少的垃圾收集和更少的对象分配。 3.) C* 进程和 Spark Executor 进程之间的流量最小化。这不是零拷贝系统。
    • 感谢您的回答。我预料到了这种行为,但想确定一下。我唯一担心的是 cassandra 必须进行全表扫描(因为我没有在分区键上指定任何条件),但无论如何,第二种解决方案要好得多..
    • 在这两种情况下都会进行全表扫描,但第二次表扫描非常吃力:)
    猜你喜欢
    • 1970-01-01
    • 2015-08-09
    • 2017-11-25
    • 1970-01-01
    • 2012-01-09
    • 2021-09-26
    • 2017-07-27
    • 2017-01-13
    • 2016-08-02
    相关资源
    最近更新 更多