我有一个MySQL数据库,其中一个表包含大约1亿条记录(~25GB,~5列)。使用Apache Spark,我通过JDBC连接器提取此数据并将其存储在DataFrame中。 从这里开始,我会对数据进行一些预处理(例如替换NULL值),所以我绝对需要遍历每条记录。 然后我想执行降维和特征选择(例如使用PCA),执行聚类(例如K-Means),然后在新数据上进行模型测试。
我已经在Spark的Java API中实现了这个,但它太慢了(为了我的目的),因为我做了大量的数据从DataFrame复制到java.util.Vector和java.util.List(到能够迭代所有记录并进行预处理),然后回到DataFrame(因为Spark中的PCA需要一个DataFrame作为输入)。
我尝试将数据库中的信息提取到org.apache.spark.sql.Column中,但无法找到迭代它的方法。 我还试图通过使用org.apache.spark.mllib.linalg。{DenseVector,SparseVector}来避免使用Java数据结构(例如List和Vector),但是也无法使用它。 最后,我还考虑使用JavaRDD(通过从DataFrame和自定义模式创建它),但无法完全解决它。
经过冗长的描述,我的问题是:有没有办法完成第一段中提到的所有步骤,而不将所有数据复制到Java数据结构中? 也许我试过的其中一个选项实际上可以工作,但我似乎无法弄清楚如何,因为关于Spark的文档和文献有点稀缺。
答案 0 :(得分:0)
从问题的措辞来看,似乎对Spark处理的各个阶段存在一些困惑。
首先,我们通过指定输入和转换告诉Spark要做什么。此时,唯一已知的事情是(a)处理的各个阶段的分区数量和(b)数据的模式。在此阶段使用org.apache.spark.sql.Column
来标识与列关联的元数据。但是,它不包含任何数据。事实上,现阶段根本没有数据。
其次,我们告诉Spark对数据框/数据集执行操作。这就是启动处理的原因。读取输入并流入各种转换并进入最终操作操作,无论是collect
还是save
还是其他操作。
因此,这就解释了为什么你不能“将数据库中的信息提取到”Column
。
至于你问题的核心,如果没有看到你的代码并且确切知道你想要完成什么,就很难评论,但可以肯定的是,在类型之间进行大量迁移是一个坏主意。
以下几个问题可能有助于指导您获得更好的结果:
为什么不能直接在Row
个实例上执行所需的数据转换?
将部分转换代码包装到UDF或UDAF中是否方便?
希望这有帮助。