#scala #apache-spark #apache-spark-sql #orientdb
Вопрос:
Я запускаю приложение spark(2.3.4) для заполнения базы данных orientdb (3.0.34).
Конфигурации: spark : локальный[*]
OrientDB
this.context = new OrientDB(remoteConnexionCommand, dbUser, dbPwd, dbConfig)
this.pool = new ODatabasePool(this.context, globalConfig.getString("db.name"), dbUser, dbPwd)
Затем в какой-то момент я пытаюсь сделать вставку на каком-то краю, и всплывающее окно с ошибкой:
The current database instance (com.orientechnologies.orient.core.db.ODatabaseDocumentRemotePooled@737aa62f) is not active on the current thread (Thread[Executor task launch worker for task 319,5,main]). Current active database is: com.orientechnologies.orient.core.db.ODatabaseDocumentRemotePooled@265d0416
Я не мог поместить весь код здесь для этой проблемы, но одна из отправных точек для меня, чтобы попытаться ее решить, — это понять, что может вызвать эту ошибку, а также как ее воспроизвести, похоже, это происходит непредсказуемым образом.
Также я заметил, что пул объектов создается дважды в приложении, не знаю почему, но будет ли это причиной ?
Редактировать
Код для создания подключения к бд выполняется внутри метода rdd.foreach, как описано здесь:
rdd.repartition(20).foreach(row => {
try {
DBManager session = DBManager.getSession() // which init a new Session given an initialized pool
session.command(statement, params)
} catch {
case t: Throwable => ...
}
Поэтому код, инициализирующий подключение к базе данных, выполняется в рабочих узлах.
Комментарии:
1. Похоже, что соединение с БД создается на узле драйвера и повторно используется с рабочих узлов. Подключение к БД должно быть создано на каждом рабочем узле.
2. случается, что трассировка стека приводит нас внутрь rdd.foreach, который инициализирует новый сеанс, поэтому соединение с бд, похоже, создается на рабочих. Мне было интересно, будут ли у foreachPartitions какие-либо преимущества в отношении этой проблемы.
3. Создается ли пул также для каждого работника?
4. Тогда это означает, что вы создаете пул на главном узле и пытаетесь использовать этот пул с узлов драйверов, верно? Это не может сработать. Каждому рабочему узлу нужен свой собственный пул.
5. Не могу сказать с уверенностью или точными деталями, но все, что открывает/управляет ресурсами (подключения к БД здесь), не может быть разделено между узлами, потому что оно каким-то образом связано с исходным JVM/узлом.