По каким причинам дерево времени neo4j будет зависать?
У меня странная проблема в Neo4j. Недавно я работал с GraphAware TimeTree и заполнял его до вчерашнего дня. Мне пришлось перестроить дерево из-за ошибки, которую я сделал, поэтому я оставил скрипт работающим всю ночь (nohup).
Возвращаясь сегодня, я обнаружил, что мой сценарий работал всего 3 минуты!
$ ps aux | grep timetreepop
root 21840 0.0 0.0 195952 2816 ? S Jul28 0:00 sudo nohup python timetreepop.py
root 21841 0.0 0.2 381416 75016 ? S Jul28 0:03 python timetreepop.py
Я заметил это поведение, когда работал, но решил, что если оставить его на ночь, пока я не активен, это поможет. Я также отключил другой процесс на Java-сервере в случае возможного конфликта. На этом этапе мой сервер будет работать только на сервере торнадо Python в фоновом режиме, который не очень большой и не получает много трафика (пара посещений в день).
В общем, в моей системе достаточно оперативной памяти, процессоры больше не используются, и на моей машине нет других процессов, выполняющих интенсивный ввод-вывод. С помощью top
/ atop
показать здоровую систему с доступными ресурсами.
Вот высокий уровень того, что делает мой скрипт:
neo = neopop.handler()
for i, meta_id in enumerate(meta_gen(ship='KAOU')):
neo.populate_timetree(record=meta_id)
Мой обработчик создает драйвер и сессию в __init__
конструктор:
self.driver = graphdb.driver(config.NEO4J_HTTP_LINK)
self.session = self.driver.session()
Мой генератор обеспечивает meta_id
значения, которые являются уникальными значениями свойств в узлах моего графа.
populate_timetree()
Функция создает следующий оператор:
MATCH (r:record {meta:"KAQP_20120101v20001_0001"}) WITH r
CALL ga.timetree.events.attach({node: r, time: r.time, relationshipType: "observedOn", resolution:"Minute"})
YIELD node RETURN node.meta;
Все работало нормально, мой первый раз. После испорченных значений времени я удалил базу данных, перезапустил и попытался снова. Только на этот раз моя программа зависает, когда я звоню, чтобы закрыть сеанс:
neo.session.close()
Примечание: я на самом деле называю это в моем __del__
деконструктор, (который я знаю, вероятно, считается плохой практикой, но он работал для меня до сих пор и соответствует моим потребностям.)
Я дважды проверил весь мой код на наличие мошеннических операторов readline / всего, что может привести к его приостановке. Также перекомпилировал мой пакет со всем этим кодом в нем. Я точно знаю, что это застревает в этом session.close()
заявление.
Поэтому я попытался поиграть с инструментом Neo4j-shell, чтобы увидеть, не было ли что-то другим. Сначала быстрая проверка реагирования:
$ neoc 'schema'
Indexes
ON :record(meta) ONLINE (for uniqueness constraint)
Constraints
ON (record:record) ASSERT record.meta IS UNIQUE
Хорошо все хорошо. Теперь я пытаюсь вызвать timetree для одного значения:
$ ./neo4j-shell -c '
> MATCH (r:record {meta:"KAOU_20110613v20001_0000"}) WITH r
> CALL ga.timetree.events.attach({node: r, time: r.time, relationshipType: "observedOn", resolution:"Minute"})
> YIELD node RETURN node.meta;
> '
БУМ. Neo4j застрял! Чтобы быть ясным, я знаю, что оператор MATCH здесь не вечен, потому что на этот раз я поместил только около 2 миллионов узлов в свою базу данных, и вызов одного оператора match выполняется абсолютно нормально. У меня даже есть индекс, настроенный для этого уникального свойства (см. Вызов схемы выше).
и так, что здесь происходит? Я полагаю, что первоначальное создание дерева не должно быть слишком большой проблемой, если я вставляю только один узел. Моя первая попытка, кажется, работает без нареканий. Я не уверен, что я сделал по-другому, за исключением того, что заполнил свою базу данных 2 миллионами из 58 миллионов записей, которые у меня были. (Так должно быть намного быстрее).
Я фактически оставил эту команду запущенной на несколько часов, и она также выполнялась в моей системе всего несколько минут. Я так смущен тем, что здесь происходит. У кого-нибудь есть какие-либо идеи? Могу ли я увидеть, что neo4j активно делает с этой командой? (Имейте в виду, я использую издание сообщества)
Я использую версию 3.0.3 neo4j и 3.0.3.39 timetree / graphaware на сервере CentOS 7.
Единственная идея, которая у меня есть, заключается в том, что я вызывал операторы шифрования и отменял их, прежде чем они совершали столько раз, будь то через python или инструмент командной строки cmd. Возможно ли, что я слишком много работаю с менеджером транзакций, отменив крупные транзакции до их завершения?
Например:
/neo4j-shell -c 'MATCH (r:record) CALL ga.timetree.events.attach(....) ....'
А потом ударил control-C
после этого работает около 2 часов без отделки.
ОБНОВИТЬ:
Итак, я исследовал свои файлы журнала и обнаружил некоторые проблемы. Кажется, мои темы были заблокированы из-за нехватки памяти. Я предполагаю, что мой максимальный размер кучи был искусственно ограничен и не использовал доступные ресурсы на моей машине. (Может быть??). Поэтому я вручную установил dbms.memory.heap.max_size=16000
,
Проблема, кажется, уходит сейчас! Я думаю, я был сбит с толку, так как я ожидал, что OOM Java появится в ответе neo4j-shell
инструмент вместо холостого хода, как будто прогресс.
1 ответ
$ ./neo4j-shell -c '
> MATCH (r:record {meta:"KAOU_20110613v20001_0000"}) WITH r
> CALL ga.timetree.events.attach({node: r, time: r.time, relationshipType: "observedOn", resolution:"Minute"})
> YIELD node RETURN node.meta;
> '
Сколько узлов этот запрос должен привязать к временному дереву?
Эта процедура не использует пакетную обработку, поэтому она ограничена тем, что ваша память может сделать за одну транзакцию (теперь это в нашем бэклоге).
Тем не менее, обычно нет смысла прикреплять события вручную к дереву, эта процедура предназначена для удобства, но мы рекомендуем использовать автоматическое вложение событий:
https://github.com/graphaware/neo4j-timetree
Таким образом, повторное присоединение полной базы данных (или только узлов, настроенных для присоединения) будет являться вопросом перезапуска вашей базы данных, и этот процесс будет выполняться с пакетными транзакциями, что значительно ускорит затрачиваемое время.