这不是Usage of custom Python object in Pyspark UDF的重复,因为虽然这会解决外部文件的使用问题,但这是对最佳做法的请求。
首先,我确信这在Scala中会更有效,但为我的生态系统添加新语言是不可行的。
我的问题是我有一个包含IP地址的Hive数据库,我想将每个数据库映射到其父自治系统编号(ASN)。
MaxMind提供several downloadable databases包含各种IP元数据,包括地理位置,ASN等,以及另外几个reference implementations代码来读取这些数据库。数据库本身是MaxMind DB Format中高效打包的二叉树,很难展开成适合数据库连接的东西。
我做这个映射的计划是围绕他们的Python数据库阅读器创建一个PySpark UDF,如下所示:
def mmdbv(x):
import maxminddb
reader = maxminddb.open_database(SparkFiles.get("GeoIP2-ISP.mmdb"))
try:
foo = reader.get(x)['autonomous_system_number']
except:
foo = None
finally:
reader.close()
return foo
if __name__== "__main__":
spark = (SparkSession
.builder
.enableHiveSupport()
.config("hive.exec.dynamic.partition", "true")
.config("hive.exec.dynamic.partition.mode", "nonstrict")
.getOrCreate())
spark.sparkContext.setLogLevel("WARN")
spark.sparkContext.addPyFile('maxminddb-1.3.0-py3.6.egg')
spark.sparkContext.addFile('GeoIP2-ISP.mmdb')
mf = F.udf(mmdbv, T.IntegerType())
main()
spark.stop()
这是非常低效的,基本上是元素创建文件句柄,打开,读取和关闭。还有更好的方法吗?