PySpark带密码连接MongoDB失败的配置问题排查
从错误日志里的关键信息一眼就能定位问题:
UserNotFound: Could not find user "root" for db "spark"
com.mongodb.MongoSecurityException: Exception authenticating MongoCredential{mechanism=SCRAM-SHA-1, userName='root', source='spark', password=, mechanismProperties={}}
你的root是MongoDB的超级管理员用户,默认创建在admin数据库下——哪怕你在Docker Compose里设置了MONGO_INITDB_DATABASE: spark,这个参数只是指定初始化时默认连接的数据库,并不会把root用户迁移到spark库。但PySpark的Mongo连接器默认会用URI里指定的业务数据库(也就是spark)作为认证源,导致MongoDB找不到对应的用户。
至于你用pymongo能成功连接,大概率是因为pymongo默认会尝试用admin库做认证源,或者你在pymongo连接时隐式指定了认证数据库,而PySpark的连接器则是严格遵循URI配置的。
有两种修复方式,任选其一即可:
方案1:修改MongoDB连接URI,指定认证源为admin
在连接URI末尾加上?authSource=admin,明确告诉MongoDB要到admin库验证root用户身份。
调整代码中的URI:
把config.MONGO_URL_AUTH的取值改成:
config.MONGO_URL_AUTH = "mongodb://root:example@mongodb:27017?authSource=admin" # 加载数据时的完整URI会自动拼接为:mongodb://root:example@mongodb:27017?authSource=admin/spark.times df = sqlContext.read.format("com.mongodb.spark.sql.DefaultSource")\ .option("spark.mongodb.input.uri", config.MONGO_URL_AUTH + "/spark.times")\ .load()
同步修改Docker CMD中的spark-submit配置:
CMD [ "spark-submit" \ , "--conf", "spark.mongodb.input.uri=mongodb://root:example@mongodb:27017/spark.times?authSource=admin" \ , "--conf", "spark.mongodb.output.uri=mongodb://root:example@mongodb:27017/spark.output?authSource=admin" \ , "--packages", "org.mongodb.spark:mongo-spark-connector_2.11:2.4.1" \ , "./spark.py" ]
方案2:在Spark配置中单独指定认证源数据库
如果不想修改URI,可以额外添加spark.mongodb.authentication.source配置项,直接指定认证数据库为admin:
修改Docker CMD的spark-submit参数:
CMD [ "spark-submit" \ , "--conf", "spark.mongodb.input.uri=mongodb://root:example@mongodb:27017/spark.times" \ , "--conf", "spark.mongodb.output.uri=mongodb://root:example@mongodb:27017/spark.output" \ , "--conf", "spark.mongodb.authentication.source=admin" \ , "--packages", "org.mongodb.spark:mongo-spark-connector_2.11:2.4.1" \ , "./spark.py" ]
同时也可以在代码的SparkConf里加上这个配置(确保配置优先级覆盖):
sparkConf = SparkConf().setMaster("local").setAppName("MongoSparkConnectorTour").set("spark.app.id", "MongoSparkConnectorTour")\ .set("spark.mongodb.authentication.source", "admin")
修改完成后重启容器,PySpark就能正确到admin数据库验证root用户身份,顺利连接MongoDB并加载数据。
内容的提问来源于stack exchange,提问作者cnd

