Невозможно соединить Oracle с Apache Spark с помощью SSO Wallet - PullRequest
0 голосов
/ 04 декабря 2018

Мы пытаемся подключиться к удаленной базе данных Oracle, работающей в качестве AmazonRDS, используя настроенный на нашем конце кошелек SSO и Apache Spark.Мы можем загрузить данные с помощью утилиты spark-shell, как указано ниже

Запустите оболочку spark с jar-файлом jdbc и oraclepki, добавленным в classpath

 spark-shell --driver-class-path /path/to/ojdbc8.jar:/path/to/oraclepki.jar

Это URL-адрес JDBC:

 val JDBCURL="jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCPS)(HOST=www.example.aws.server.com)(PORT=1527))(CONNECT_DATA=(SID=XXX))(SECURITY = (SSL_SERVER_CERT_DN =\"C=US,ST=xxx,L=ZZZ,O=Amazon.com,OU=RDS,CN=www.xxx.aws.zzz.com\")))"

Ниже приведен вызов Spark jdbc для загрузки данных

 spark.read.format("jdbc").option("url",JDBCURL)
.option("user","USER")
.option("oracle.net.tns_admin","/path/to/tnsnames.ora")
.option("oracle.net.wallet_location","(SOURCE=(METHOD=file)(METHOD_DATA=(DIRECTORY=/path/to/ssl_wallet/)))")
.option("password", "password")
.option("javax.net.ssl.trustStore","/path/to/cwallet.sso")
.option("javax.net.ssl.trustStoreType","SSO")
.option("dbtable",QUERY)
.option("driver", "oracle.jdbc.driver.OracleDriver").load    

Но когда мы пытаемся запустить его с помощью команды spark-submit, мы получаем следующую ошибку:

    Exception in thread "main" java.sql.SQLRecoverableException: IO Error: The Network Adapter could not establish the connection
    at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:774)
    at oracle.jdbc.driver.PhysicalConnection.connect(PhysicalConnection.java:688)
    ...
    ...
    ...

    Caused by: oracle.net.ns.NetException: The Network Adapter could not establish the connection
    at oracle.net.nt.ConnStrategy.execute(ConnStrategy.java:523)
    at oracle.net.resolver.AddrResolution.resolveAndExecute(AddrResolution.java:521)
    at oracle.net.ns.NSProtocol.establishConnection(NSProtocol.java:660)
    at oracle.net.ns.NSProtocol.connect(NSProtocol.java:286)
    at oracle.jdbc.driver.T4CConnection.connect(T4CConnection.java:1438)
    at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:518)
    ... 28 more
    Caused by: oracle.net.ns.NetException: Unable to initialize ssl context.
    at oracle.net.nt.CustomSSLSocketFactory.getSSLSocketEngine(CustomSSLSocketFactory.java:597)
    at oracle.net.nt.TcpsNTAdapter.connect(TcpsNTAdapter.java:143)
    at oracle.net.nt.ConnOption.connect(ConnOption.java:161)
    at oracle.net.nt.ConnStrategy.execute(ConnStrategy.java:470)
    ... 33 more
    Caused by: oracle.net.ns.NetException: Unable to initialize the key store.
    at oracle.net.nt.CustomSSLSocketFactory.getKeyManagerArray(CustomSSLSocketFactory.java:642)
    at oracle.net.nt.CustomSSLSocketFactory.getSSLSocketEngine(CustomSSLSocketFactory.java:580)
    ... 36 more
    Caused by: java.security.KeyStoreException: SSO not found
    at java.security.KeyStore.getInstance(KeyStore.java:851)
    at oracle.net.nt.CustomSSLSocketFactory.getKeyManagerArray(CustomSSLSocketFactory.java:628)
    ... 37 more
    Caused by: java.security.NoSuchAlgorithmException: SSO KeyStore not available
    at sun.security.jca.GetInstance.getInstance(GetInstance.java:159)
    at java.security.Security.getImpl(Security.java:695)
    at java.security.KeyStore.getInstance(KeyStore.java:848)

Я новичок в искре и, возможно, здесь что-то не так.Вот как я пытаюсь настроить Config

    val conf = new SparkConf().setAppName(JOB_NAME)
    conf.set("javax.net.ssl.trustStore", "/path/to/cwallet.sso");
    conf.set("javax.net.ssl.trustStoreType", "SSO")
    conf.set("oracle.net.tns_admin", "/path/to/tnsnames.ora")
    conf.set("oracle.net.wallet_location", "(SOURCE=(METHOD=file)(METHOD_DATA=(DIRECTORY=/path/to/ssl_wallet/dir/)))")
    conf.set("user", "user")
    conf.set("password", "pass")

Ниже используется команда spark-submit

    spark-submit --class fully.qualified.path.to.main \
    --jars /path/to/ojdbc8.jar,/path/to/oraclepki.jar,/path/to/osdt_cert.jar,/path/to/osdt_core.jar \
    --deploy-mode client --files /path/to/hive-site.xml --master yarn  \
    --driver-memory 12G \
    --conf "spark.executor.extraJavaOptions=-Djavax.net.ssl.trustStore=/path/to/cwallet.sso -Djavax.net.ssl.trustStoreType=SSO" \
    --executor-cores 4 --executor-memory 12G \
    --num-executors 20 /path/to/application.jar /path/to/application_custom_config.conf

Также попытался добавить

--conf 'spark.executor.extraJavaOptions=-Djavax.net.ssl.trustStore=/path/to/cwallet.sso -Djavax.net.ssl.trustStoreType=SSO'

и

--files /path/to/cwallet.sso,/path/to/tnsnames.ora

на команду spark-submit, но без удачи.Что именно я здесь делаю не так?Также попробовал решение, упомянутое в этом посте , но получаю ту же ошибку. Мне нужно убедиться, что trustStore should be accessible on each executor node?Если это так, то почему команда spark-shell работает нормально?Означает ли это, что в spark-cli нет рабочих узлов для выполнения команды?

Пожалуйста, советуйте

ОБНОВЛЕНИЕ:

Похоже, вы используете драйвер JDBC из 12.1.0.2.Пожалуйста, обновите до 18.3, который вы можете загрузить с oracle.com/technetwork/database/application-development/jdbc/…. Некоторые изменения были сделаны, чтобы упростить использование кошельков.- @Джан де Лаварен

После того, как предложенное @Jean de Lavarene изменение избавило от первоначальной ошибки, но вот то, что я получаю сейчас

    org.apache.spark.SparkException: Job aborted due to stage failure: Task 0 in stage 0.0 failed 4 times, most recent failure: Lost task 0.3 in stage 0.0 (TID 3, example.server.net, executor 2): java.sql.SQLException: PKI classes not found. To use 'connect /' functionality, oraclepki.jar must be in the classpath: java.lang.NoClassDefFoundError: oracle/security/pki/OracleWallet
    at oracle.jdbc.driver.PhysicalConnection.getSecretStoreCredentials(PhysicalConnection.java:3058)
    at oracle.jdbc.driver.PhysicalConnection.parseUrl(PhysicalConnection.java:2823) 

Когда язапустите его в локальном режиме spark: --master local[*] он работает нормально, но не работает в режиме yarn.

Я уже использую команду --jars со списком jar через запятую.Я нашел следующее:

1) --jars ожидаем, что путь будет локальным, а затем скопирует их в путь HDFS.2) использование file:/// в начале не работает3) Если я не укажу параметр --jars, программа запросит отсутствующий класс драйвера JDBC.Когда я указываю ojdbc8.jar с помощью --jars, ошибки исчезают и начинают выдавать ошибку oraclepki.jar not found.У меня есть NO CLUE , почему это происходит.4) Также попытался использовать : в качестве разделителя при указании нескольких банок, но без какой-либо удачи

ОБНОВЛЕНИЕ 2

Мне удалось разрешить oraclepki.jar не найденоисключение с помощью

    --driver-class-path /path/to/oraclepki.jar:/path/to/osdt_cert.jar:/path/to/others.jar 

, но как только мы запускаем режим --master yarn, тогда показывается следующее исключение

    Caused by: oracle.net.ns.NetException: Unable to initialize the key store.
    at oracle.net.nt.CustomSSLSocketFactory.getKeyManagerArray(CustomSSLSocketFactory.java:617)
    at oracle.net.nt.CustomSSLSocketFactory.createSSLContext(CustomSSLSocketFactory.java:322)
    ... 32 more
    Caused by: java.io.FileNotFoundException: /path/to/cwallet.sso (No such file or directory)

Насколько я понимаю, это выглядит при запускезадание от рабочего узла, путь к файлу cwallet.sso на этих узлах недоступен.Мы попытались указать путь HDFS для кошелька, но утилита ожидает, что при создании кошелька будет указан локальный путь.

Так нужно ли нам вручную копировать файл кошелька на все рабочие узлы?Или есть ли лучшие альтернативы для достижения этого?

Пожалуйста, совет

1 Ответ

0 голосов
/ 03 июня 2019

По сути, это то, как мы можем это решить.Здесь следует помнить одну важную вещь: файл SSO должен присутствовать на всех узлах, на которых будет работать Spark (узел исполнителя spark)

    val SOURCE_DF = spark.read.format("jdbc")
        .option("url", "jdbc:oracle:thin:@...full string here")
        .option("oracle.net.wallet_location", "(SOURCE=(METHOD=file)(METHOD_DATA=(DIRECTORY=/path/to/sso/dir)))")
        ...
        ...

В случае, если вам необходимо передать дополнительную информацию, вы можете добавить больше .options параметры

   .option("oracle.net.tns_admin", "oracle/tns/file/path"))
   .option("javax.net.ssl.trustStoreType", "sso")
...