在where子句中使用非索引列查询Cassandra时,Spark-Cassandra-Connector'} {/ 3}}说,
要过滤行,您可以使用Spark提供的过滤器转换。但是,此方法会导致从Cassandra获取所有行,然后通过Spark进行过滤。
我对此感到有点困惑。例如,如果我有十亿行此db结构:ID,City,State和Country,其中只有ID被索引。如果我使用City =' Chicago'在where子句中,Spark会首先下载所有十亿行,然后过滤出City =' Chicago&#39 ;?或者它会从Cassandra读取一些数据,运行过滤器,存储符合条件的行,然后获取更多数据块,获取与条件匹配的行,并将它们再次放在一边......并继续该过程。如果在任何时候,RAM和/或磁盘存储器运行不足,删除/卸载/删除不符合条件的数据,并获取新的数据块以继续该过程?
另外,有人可以告诉我一个通用的公式来计算保存一个大数字列和3个十亿行的文本列需要多少磁盘空间?
答案 0 :(得分:4)
过滤行可以在数据库中或在Spark中进行。文档推荐的是尽可能多地尝试过滤数据库中的记录,而不是在spark中进行。这意味着什么:
sc.cassandraTable("test", "cars")
.select("id", "model")
.where("color = ?", "black")
以上语句将在Cassandra(数据库)中运行color = 'black'
过滤器,因此Spark不会将任何记录带入黑色以外的其他记录。而不是将十亿条记录存入内存,Spark可能只会加载几千万在color
列中具有黑色值的数据。
相反,过滤可以在spark中完成:
sc.cassandraTable("test", "cars")
.select("id", "model")
.filter(car -> "black".equals(car.getColor()))
最后一个版本会将所有数十亿的记录加载到Spark的内存中,然后按Spark 中的颜色进行过滤。显然,这不能优先于最小化Spark集群所需内存量的先前版本。因此,对于可在数据库中处理的任何简单过滤,应使用数据库/驱动程序/查询过滤器。
关于估算内存需求,还有其他问题提出了各种方法,请查看this和this。 spark's documentation中还有一个很好的建议:
您需要多少内存取决于您的应用程序。要确定应用程序对特定数据集大小的使用量,请在Spark RDD中加载部分数据集,并使用Spark监视UI(http://:4040)的“存储”选项卡查看其在内存中的大小。请注意,内存使用率受存储级别和序列化格式的影响很大 - 有关如何减少内存的提示,请参阅调整指南。
答案 1 :(得分:2)
spark cassandra连接器将发出具有特定令牌范围的多个查询(每个spark任务1个)。总的来说,它将是一个全表扫描,但它将一次完成一个位,并行。如果在每个cassandra节点上运行spark worker,则连接器将选择与本地cassandra节点匹配的令牌范围。这将限制网络上的数据混乱。然而,全表扫描发生并不理想。