我正在运行 Sqoop 命令以在启用 SSL 的情况下从 MS SQL 导入数据。 我已经创建了密钥库并将证书添加到密钥库。我正在使用 Sqoop 版本 1.4.6-cdh5.11.2
下面是我的 Sqoop 命令:
sqoop import -Dfile.encoding=UTF-8
--driver "com.microsoft.sqlserver.jdbc.SQLServerDriver"
--connect "jdbc:sqlserver://xxxxxx:1433;databaseName=xxx-example;encrypt=True;TrustServerCertificate=False;hostNameInCertificate=xxxxxx.xxxx.net;trustStore=/home/user1/trust.jks;trustStorePassword=xxxx"
--username User1
--password 'xxxxx'
--null-string '\N'
--null-non-string '\N' -delete-target-dir
--target-dir "/home/john/PROGRAMS"
--table programs
--fields-terminated-by " 01"
--hive-drop-import-delims
--split-by 'ID'
--outdir 'temp/john/tables'
--bindir '/usr/john/PROGRAMS' -m 1
我已将加密设置为 true,TrustServerCertificate 设置为 false,trustStore= 和 trustStorePassword 设置为密钥库密码。
encrypt=True;TrustServerCertificate=False
以下是我在运行sqoop命令时遇到的错误:
18/01/22 10:12:10 INFO mapreduce.Job: Task Id : attempt_1516292804343_13212_m_000001_0, Status : FAILED
Error: java.lang.RuntimeException: java.lang.RuntimeException: com.microsoft.sqlserver.jdbc.SQLServerException: The driver could not establish a secure connection to SQL Server by using Secure Sockets Layer (SSL) encryption. Error: "java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty".
at org.apache.sqoop.mapreduce.db.DBInputFormat.setDbConf(DBInputFormat.java:170)
at org.apache.sqoop.mapreduce.db.DBInputFormat.setConf(DBInputFormat.java:161)
at org.apache.hadoop.util.ReflectionUtils.setConf(ReflectionUtils.java:73)
at org.apache.hadoop.util.ReflectionUtils.newInstance(ReflectionUtils.java:133)
at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:755)
at org.apache.hadoop.mapred.MapTask.run(MapTask.java:341)
at org.apache.hadoop.mapred.YarnChild$2.run(YarnChild.java:164)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.java:422)
at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1920)
at org.apache.hadoop.mapred.YarnChild.main(YarnChild.java:158)
Caused by: java.lang.RuntimeException: com.microsoft.sqlserver.jdbc.SQLServerException: The driver could not establish a secure connection to SQL Server by using Secure Sockets Layer (SSL) encryption. Error: "java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty".
at org.apache.sqoop.mapreduce.db.DBInputFormat.getConnection(DBInputFormat.java:223)
at org.apache.sqoop.mapreduce.db.DBInputFormat.setDbConf(DBInputFormat.java:168)
... 10 more
Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: The driver could not establish a secure connection to SQL Server by using Secure Sockets Layer (SSL) encryption. Error: "java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty".
at com.microsoft.sqlserver.jdbc.SQLServerConnection.terminate(SQLServerConnection.java:1667)
at com.microsoft.sqlserver.jdbc.TDSChannel.enableSSL(IOBuffer.java:1668)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.connectHelper(SQLServerConnection.java:1323)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.login(SQLServerConnection.java:991)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.connect(SQLServerConnection.java:827)
at com.microsoft.sqlserver.jdbc.SQLServerDriver.connect(SQLServerDriver.java:1012)
at java.sql.DriverManager.getConnection(DriverManager.java:664)
at java.sql.DriverManager.getConnection(DriverManager.java:247)
at org.apache.sqoop.mapreduce.db.DBConfiguration.getConnection(DBConfiguration.java:302)
at org.apache.sqoop.mapreduce.db.DBInputFormat.getConnection(DBInputFormat.java:216)
... 11 more
Caused by: javax.net.ssl.SSLException: java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
at sun.security.ssl.Alerts.getSSLException(Alerts.java:208)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1949)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1906)
at sun.security.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1889)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1410)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)
at com.microsoft.sqlserver.jdbc.TDSChannel.enableSSL(IOBuffer.java:1618)
我该如何解决这个问题?
我尝试添加 -Djavax.net.ssl.trustStore= ,但它不起作用。
Microsoft文档说,要使SSL正常工作,绝对有必要为您正在使用的JRE正确配置JSSE提供程序。 这有两个步骤:
1) 查看 JRE 安装中的 java.security 文件 (通常位于 jre\lib\security 目录中)。 已安装的 安全提供程序在该文件中列为 security.provider.x=... 其中"x"是使用的优先级。 对于 Sun JRE 安装,第一个 优先提供商应该是Sun的。 例如:你应该有这条线 该文件中的"security.provider.1=sun.security.provider.Sun"。 为 其他 JRE,请参阅有关其 JRE 的文档 默认提供程序名称。 我们建议在使用 IBM JRE 时指定 "com.ibm.jsse.IBMJSSEProvider"作为第一个安全提供商 用。
2) 接下来,确保类路径指向正确的 JAR 文件(在 JRE\lib 目录中)用于这些提供程序。 为 Sun,类路径应包含 jsse.jar。 对于 IBM,应包括 IBMJSSE.jar.
请参阅此Microsoft文档,该文档由您收到的相同错误解释("驱动程序无法使用安全套接字层 (SSL) 加密建立与 SQL Server 的安全连接。错误)
看起来您必须在 sqoop 作业中传递以下 java 参数
-Djavax.net.ssl.trustStore=C:MyCertificatesstoreName
-Djavax.net.ssl.trustStorePassword=storePassword