在where子句中使用非索引列查询Cassandra时,Spark-Cassandra-Connector的official documentation说,
要过滤行,可以使用Spark提供的过滤器转换 . 但是,此方法会导致从Cassandra获取所有行,然后通过Spark进行过滤 .
我对此有点困惑 . 例如,如果我有十亿行此db结构:ID,City,State和Country,其中只有ID被索引 . 如果我在where子句中使用City ='Chicago',Spark会先下载所有十亿行,然后过滤出City ='Chicago'的行吗?或者它会从Cassandra中读取一些数据,运行过滤器,存储符合条件的行,然后获取更多数据块,获取与条件匹配的行,并将它们再次放在一边......并继续该过程 . 如果在任何时候,RAM和/或磁盘存储器运行不足,删除/卸载/删除与条件不匹配的数据,并获取新的数据块以继续该过程?
此外,有人可以告诉我一个通用的公式来计算保存一个bigdecimal列和3个文本列十亿行所需的磁盘空间多少?
2 回答
过滤行可以在数据库中或在Spark中进行 . 文档推荐的是尽可能多地尝试过滤数据库中的记录,而不是在spark中进行 . 那意味着什么:
上面的语句将运行
color = 'black'
过滤器 in Cassandra, the database ,因此Spark不会将任何具有黑色以外颜色的记录提取到其内存中 . 而不是将十亿条记录存入内存,Spark可能只会加载几百万个碰巧在color
列中具有黑色值的数据 .相反,过滤可以在spark中完成:
最后一个版本将 all billions 记录加载到Spark的内存中,然后按颜色 in Spark 过滤它们 . 显然,这不能优先于最小化Spark集群所需内存量的先前版本 . 因此,对于可在数据库中处理的任何简单过滤,应使用数据库/驱动程序/查询过滤器 .
关于估计内存需求,还有其他问题提出了各种方法,请检查this和this . 在_2513743中也有一个很好的建议:
spark cassandra连接器将使用特定的令牌范围发出多个查询(每个spark任务1个) . 总的来说,它将是一个全表扫描,但它将一次完成一个位,并行 . 如果在每个cassandra节点上运行spark worker,则连接器将选择与本地cassandra节点匹配的令牌范围 . 这将限制网络上的数据混乱 . 然而,发生全表扫描并不理想 .