Как подключиться к SQL Server с помощью Pyspark, работающего на GCP, без использования Secure Sockets Layer?

Я пытаюсь подключиться к базе данных SQL Server с помощью PySpark, как показано ниже:

from pyspark.sql import SparkSession
import traceback

def connect_and_read(spark: SparkSession):
    url = 'jdbc:sqlserver://DUMMY1234.DUMMY.COM\DUMMY1234;databaseName=Dummy_DB;encrypt=false'
    driver = 'com.microsoft.sqlserver.jdbc.SQLServerDriver'
    try:
        dataframe = spark.read.format('jdbc').option('url', url). \
            option('driver', driver). \
            option('user', 'username'). \
            option('password', 'password'). \
            option('dbtable', 'TABLENAME'). \
            load()
        print(f'Count: {dataframe.count()}')
        dataframe.take(10)
    except Exception as ex:
        traceback.print_exc(type(ex), ex, ex.__traceback__)
    pass


if __name__ == '__main__':
    spark = SparkSession.builder.master('yarn').config('spark.app.name', 'read_data_sqlserver').config('spark.driver.extraClassPath', 'path_to_/mssql-jdbc-9.2.0.jre8.jar').config('spark.driver.extraClassPath', 'path_to_/spark-mssql-connector-1.0.1.jar').getOrCreate()
    connect_and_read(spark)

Я запускаю этот код из Google Cloud Platform. У меня есть экземпляр Dataproc, где я создал кластер для этой операции и отправил туда свою работу. Задание завершается с ошибкой со следующим исключением:

py4j.protocol.Py4JJavaError: произошла ошибка при вызове o70.load.
: com.microsoft.sqlserver.jdbc.SQLServerException: драйверу не удалось установить безопасное соединение с SQL Server с помощью шифрования Secure Sockets Layer (SSL). . Ошибка: сброс соединения ClientConnectionId: 1223412f-9879702-wfwd-134qq-2143d123e1q.

на com.microsoft.sqlserver.jdbc.SQLServerConnection.terminate(SQLServerConnection.java:3208)
на com.microsoft.sqlserver.jdbc.TDSChannel.enableSSL(IOBuffer.java:1916)
на com.microsoft .sqlserver.jdbc.SQLServerConnection.connectHelper(SQLServerConnection.java:2760)
на com.microsoft.sqlserver.jdbc.SQLServerConnection.login(SQLServerConnection.java:2418) на com.microsoft.sqlserver.jdbc.SQLServerConnection.connectInternal (SQLServerConnection.java:2265) в com.microsoft.sqlserver.jdbc.SQLServerConnection.connect(SQLServerConnection.java:1291) в com.microsoft.sqlserver.jdbc.SQLServerDriver.connect(SQLServerDriver.java:881) в java.lang. Thread.run(Thread.java:748) Причина: java.io.IOException: сброс соединения ClientConnectionId:1223412f-9879702-wfwd-134qq-2143d123e1q. в com.microsoft.sqlserver.jdbc.TDSChannel$SSLHandshakeInputStream.readInternal(IOBuffer.java:862) в com.microsoft.sqlserver.jdbc.TDSChannel$SSLHandshakeInputStream.read(IOBuffer.java:849) в com.microsoft.sqlserver.jdbc .TDSChannel$ProxyInputStream.readInternal(IOBuffer.java:1019) в com.microsoft.sqlserver.jdbc.TDSChannel$ProxyInputStream.read(IOBuffer.java:1009) в org.conscrypt.ConscryptEngineSocket$SSLInputStream.readFromSocket(ConscryptEngineSocket.java:920 ) в org.conscrypt.ConscryptEngineSocket$SSLInputStream.processDataFromSocket(ConscryptEngineSocket.java:884) в org.conscrypt.ConscryptEngineSocket$SSLInputStream.access$100(ConscryptEngineSocket.java:706) в org.conscrypt.ConscryptEngineSocket.doHandshake(ConscryptEngineSocket.java:230) ) в org.conscrypt.ConscryptEngineSocket.startHandshake(ConscryptEngineSocket.java:209) в com.microsoft.sqlserver.jdbc.TDSChannel.enableSSL(IOBuffer.java:1824) ... еще 28 Во время обработки указанного выше исключения возникло другое исключение :

Traceback (последний последний вызов):

Файл /tmp/portw/pattern.py, строка 24, в
connect_and_read(spark)

Файл /tmp/portw/pattern.py, строка 18, в connect_and_read
traceback.print_exc(type(ex), ex, ex.traceback)

Файл /opt/conda/default/lib/python3.8/traceback.py, строка 163, в print_exc
print_exception(*sys.exc_info(), limit=limit, file=file, chain=chain)

Файл /opt/conda/default/lib/python3.8/traceback.py, строка 103, в print_exception
для строки в TracebackException(

Файл /opt/conda/default/lib/python3.8/traceback.py, строка 509, в init
self.stack = StackSummary.extract(

Файл /opt/conda/default/lib/python3.8/traceback.py, строка 340, в экстракте
, если лимит ›= 0:

TypeError: '›=' не поддерживается между экземплярами 'type' и 'int'

02.21.09 13:59:59 ИНФОРМАЦИЯ org.sparkproject.jetty.server.AbstractConnector: Stopped Spark@1aa73a6d{HTTP/1.1, (http/1.1)}

Раньше URL-адрес не содержал encrypt=false, и я добавил его после просмотра некоторых ссылок.

Я могу подключиться к тому же хосту для своих API-интерфейсов в простом коде Python, но не в Spark.

Может ли кто-нибудь сообщить мне, какую ошибку я делаю здесь и как ее исправить.

Любая помощь приветствуется.


person Metadata    schedule 09.02.2021    source источник
comment
Пожалуйста, посмотрите на этот stackoverflow.com/a/58848735/11866104   -  person Mahboob    schedule 09.02.2021
comment
@Mahboob Это не решило. Я проверил этот вопрос, прежде чем прийти сюда.   -  person Metadata    schedule 11.02.2021
comment
Это исключение, вероятно, вызвано несовместимостью с драйвером MS SQL JDBC и Conscrypt, которые Dataproc использует по умолчанию. Чтобы решить эту проблему, вы можете отключить Conscrypt, используя dataproc:dataproc.conscrypt.provider.enable=false свойство кластера при создании кластера Dataproc. Если это решит вашу проблему, не стесняйтесь повторно опубликовать свой вопрос для потомков, и я также могу опубликовать ответ там.   -  person Igor Dvorzhak    schedule 13.02.2021
comment
@Метаданные для вашего сведения ^   -  person Igor Dvorzhak    schedule 16.02.2021
comment
@IgorDvorzhak Итак, я должен добавить параметр в команду создания моего кластера, например: --properties=dataproc:dataproc.conscrypt.provider.enable=false .... я прав?   -  person Metadata    schedule 16.02.2021
comment
@ Метаданные да, ты прав.   -  person Igor Dvorzhak    schedule 16.02.2021
comment
@IgorDvorzhak Создает ли упомянутое вами свойство небезопасное соединение с базой данных? В любом случае, ваше предложение сработало. Можешь сделать ответ?   -  person Metadata    schedule 19.02.2021
comment
@Metadata нет, речь идет не о безопасности, а о производительности - Conscrypt - это более быстрая реализация некоторых криптографических алгоритмов, чем у JDK 8, но драйвер MS SQL JDBC имеет некоторые ошибки, которые приводят к несовместимости с ним. Я больше не могу публиковать в качестве ответа, потому что этот вопрос уже помечен как дубликат.   -  person Igor Dvorzhak    schedule 19.02.2021
comment
Опубликовано как ответ на новый аналогичный вопрос: stackoverflow.com/a/66282915/3227693   -  person Igor Dvorzhak    schedule 19.02.2021