我对HDFS和Spark还不熟悉。我有一些特定于地区(可能是一个国家或部分国家)和时间函数的模拟输入数据。
假设我有以下表格:
region:
id, name
-
population:
id, region_id, year_2020, year_2021, .... year_2050
-
sun_hours:
id, region_id, year_2020, year_2021, .... year_2050
(实际情况比较复杂,嵌套实体和外键关系较多)。
我想从MySQL导入所有数据到HDFS,并按区域id对其进行分区。
理想情况下,集群的每个节点负责一个区域,这样我就可以轻松地并行处理这些区域。如果我想考虑更多的区域,我可以通过添加更多的节点来缩放模拟。(我模拟的一个基本假设是区域之间不相互作用)。
我希望在模拟过程中,不需要在节点之间传递数据,因为一个特定区域所需的所有数据都已位于一个特定节点上。如果一些数据在拆分/分发过程中重复,对我来说没问题。我预计对单个区域的模拟要求很高,因此单个节点可能不希望并行计算多个区域。
我找到了一个sqoop命令来将几个表导入hdfs:
sqoop import-all-tables --connect jdbc:mysql://db.foo.com/corp
https://sqoop.apache.org/docs/1.4.2/SqoopUserGuide.html#_literal_sqoop_import_all_tables_literal
但是,我没有办法指定数据应该如何分区和分发。这个过程应该考虑一些“主要实体”(=区域)。
我可以用sqoop来做吗?如果是,请提供一个示例命令?
如果没有,是否有其他工具可供我使用?
如果我需要自己做,你建议
a)首先导入所有数据,然后重新组织它或
b)首先重新组织数据并将其写入特定区域的文本文件,然后将其导入HDF?
即使我设法重新组织(分层的)MySQL数据,我如何才能确保所有相关的数据都可以在单个节点上找到,并且不会在整个集群上被分割?
对于其他工作:hdfs、spark或其他一些大数据工具是否具有将相关内容放在一起的功能?假设我有一些包含RDD的种群和其他包含太阳时数的RDD。
区域1的人口和日照时数应位于节点x。。。区域2的人口和日照时数应该在节点y上,以此类推。
(为了减少出错的可能性,这是很好的,我想需要。。。在多个节点上复制数据。我只想确保在没有节点问题的模拟过程中,节点之间的流量尽可能低。)
编辑
我刚发现GeoSpark
地理公园空间划分方法可以显著加快
加入查询。有三种空间分区方法:
KDB树、四叉树和R树。两个空间RDD必须按
同样的方式。
如果首先对SpatialRDD A进行分区,则必须使用分区器
从A到分区B。
objectRDD.spatialPartitioning(GridType.KDBTREE)
queryWindowRDD.spacepartitioning(objectRDD.getPartitioner)
https://datasystemslab.github.io/GeoSpark/tutorial/rdd/
因此,也许我应该尝试将MySQL数据库转换为与GeoSpark兼容的格式(“可以从CSV、TSV、WKT、WKB、Shapefiles、GeoJSON和NetCDF/HDF格式加载”)。
相关文章:
https://sparkdatasourceapi.blogspot.com/2016/10/patitioning-in-spark-writing-custom.html
Spark - Is it possible to control placement of partitions to nodes?
How to control preferred locations of RDD partitions?
In Apache Spark, Is it possible to specify partition's preferred location for a shuffled RDD or a cogrouped RDD?
Enforce partition be stored on the specific executor
How to physically partition data to avoid shuffle in Spark SQL joins
最佳答案
sqoop(不是Spark)更适合于表。它可以使用视图,但有人指出,对于复杂视图,结果甚至可能不可靠。所以,那条大街是封闭的。
您需要使用spark.read JDBC连接来连接mySQL中的一个视图,该视图使用region_id作为分发的键(对于您的并行性),使用“driving”表中定义的numPartitions方法。与其他表的连接需要依赖mySQL引擎。
我不知道您的处理过程,但似乎很难强制执行1到1的区域id到分区方法。此外,超过1个分区可能存在于同一节点上,但独立地存在。
您可以独立获取所有表,然后进行连接,但会出现无序,因为无法保证所有单独读取的结果都会在同一个节点上结束。