我试图将所有杂货店的文件读入RDD。目标是为特定的杂货店找出最近的500家商店并进行一些处理。 例如,如果商店被占用,我将不得不找到该城市的所有商店。如果我在RDD上进行映射,我会获得单个存储到转换函数。如何获得该功能中的所有商店。
片段
def getNearestStores(store):
stores_city = stores.filter("city="+store.city)
return (store.id,stores_city.count())
stores = sc.textFile("stores.json").map(getNearestStores).count()
这是简单的代码段。 Stores.json是一个巨大的文件
1)如何在getNearestStores函数中使用stores.json获取最近的500个商店?
2)PySpark中的最大广播变量大小是多少?
答案 0 :(得分:2)
~2GB是广播变量的最大大小,因为任何广播变量在序列化期间变为java字节数组且java数组的最大大小为Integer.MAX_VALUE。
这些是与PySpark 2.x相关的较旧(类似)问题
Is there any limit on size of a spark broadcast variable?
Evaluate the max size for a spark broadcast variable
用于跟踪此问题的JIRA:https://issues.apache.org/jira/browse/SPARK-6235
编辑: 使用SparkSession + DataFrame(因为这是PySpark - 大概是2.x)连接如下。
from pyspark.sql import SparkSession
spark = SparkSession \
.builder \
.appName("Python Spark SQL basic example") \
.config("spark.some.config.option", "some-value") \
.getOrCreate()
df = spark.read.json("stores.json")
nearest_stores_df = df.join(df, "city") # self-join
答案 1 :(得分:0)
回复上面的评论,详细说明您真正要完成的工作。
我不在spark中使用python,但在scala中我会这样开始。大多数重要的东西都是特定于spark的,应该很容易转换为python。
商店类:
class Store(val id: String,
val city: String,
val lat: Double,
val lon: Double) extends Haversine {
// distance in km
def distance(that: Store) = {
val radius = 6371 // earth in km
val dlat = toRadians(that.lat - this.lat)
val dlon = toRadians(that.lon - this.lon)
val a = sin(dlat/2) * sin(dlat/2) +
cos(toRadians(this.lat)) * cos(toRadians(that.lat)) * sin(dlon/2) * sin(dlon/2)
val c = 2 * atan2(sqrt(a), sqrt(1-a))
val d = radius * c
d
}
}
因为你无论如何都在使用python,我会留给你让你的JSON解析到你的班级。
// read JSON into class Store
val rdd_store: RDD[Store] = ???
这是重要的部分......在我调试之前我会看起来像这样......但是如果我打算将它用于调试,那么我会将难以读取的部分移动到辅助函数或类中实。
// result
val rdd2: RDD[(Store, List[Store])] = {
rdd_store
.keyBy(_.city) // RDD[(city, store)] (one row per store)
.groupByKey // RDD[(city, all stores in city)] (one row per city)
.flatMap { case (city, iter_stores) =>
iter_stores.map(one_store => {
// up-to 500 closest stores in same city as 'one_store'
val top500: List[Store] = {
iter_stores
.toList
.map { s =>
val dist = one_store distance s
(dist, s)
}
}.sorted.take(500).map{ case (dist, that_store) => that_store }
// result
(one_store, top500)
})
} // RDD[(store, list of top 500 stores in same city)] (one row per store)
}