Python, PyTables, Java - связывая все вместе - PullRequest
25 голосов
/ 23 декабря 2009

Вопрос в двух словах

Каков наилучший способ заставить Python и Java хорошо играть друг с другом?

Более подробное объяснение

У меня несколько сложная ситуация. Я сделаю все возможное, чтобы объяснить как в картинках и словах. Вот текущая архитектура системы:

Current system architecture

У нас есть агентное моделирование, написанное на Java. У него есть возможность либо локальной записи в файлы CSV, либо удаленно через соединение с сервером Java в файл HDF5 . Каждый прогон симуляции выплевывает гигабайт данных, и мы запускаем симуляцию десятки раз. Нам нужно иметь возможность агрегировать по нескольким прогонам одного и того же сценария (с разными случайными начальными значениями), чтобы увидеть некоторые тренды (например, минимальное, максимальное, среднее, среднее). Как вы можете себе представить, попытка обойти все эти файлы CSV - это кошмар; за один прогон создается несколько файлов, и, как я уже сказал, некоторые из них огромны. Вот почему мы пытаемся перейти к решению HDF5, где все данные для исследования хранятся в одном месте, а не разбросаны по десяткам простых текстовых файлов. Кроме того, поскольку это двоичный формат файла, он должен иметь возможность значительно сэкономить пространство по сравнению с несжатым CSVS.

Как показано на диаграмме, текущая постобработка необработанных выходных данных, полученных при моделировании, также происходит в Java и считывается в файлы CSV, созданные при локальном выводе. Этот модуль постобработки использует JFreeChart для создания некоторых диаграмм и графиков, связанных с симуляцией.

Проблема

Как я упоминал ранее, CSV действительно несостоятельны и плохо масштабируются, так как мы генерируем все больше и больше данных из моделирования. Более того, код пост-обработки делает больше, чем должен был, по сути, выполняет работу реляционной базы данных очень, очень бедного человека (объединяет «таблицы» (файлы CSV) на основе внешних ключей (уникальных идентификаторов агентов). В этой системе также сложно визуализировать данные другими способами (например, Prefuse, Processing, JMonkeyEngine, получая некоторое подмножество необработанных данных для воспроизведения в MatLab или SPSS).

Решение?

Моя группа решила, что нам действительно нужен способ фильтрации и запросов к имеющимся у нас данным, а также выполнения объединений между таблицами. Учитывая, что это ситуация с однократной записью и многократным чтением, нам действительно не нужны издержки реальной реляционной базы данных; вместо этого нам просто нужен какой-то способ добавить лучший внешний вид в файлы HDF5. Я нашел несколько статей на эту тему, например, описывающих использование XQuery в качестве языка запросов для файлов HDF5 , но в статье описывается необходимость написания компилятора для преобразования из XQuery / XPath в собственные вызовы HDF5. , выход за рамки наших потребностей. Введите PyTables . Похоже, он делает именно то, что нам нужно (предоставляет два разных способа запроса данных: либо через понимание списка Python, либо через поиск в ядре (уровень C) .

Предложенная мной архитектура: Envisioned architecture

То, что я не совсем уверен, как это сделать, это связать воедино код Python, который будет написан для запросов, с кодом Java, который обслуживает файлы HDF5, и кодом Java, который выполняет постобработку данных. , Очевидно, что я захочу переписать большую часть кода постобработки, который неявно выполняет запросы, и вместо этого позволить превосходным PyTables сделать это намного более элегантно.

Параметры Java / Python

Простой поиск в Google выявляет несколько вариантов взаимодействия между Java и Python , но я настолько новичок в этой теме, что мне нужны реальные знания и критика предлагаемой архитектуры. Похоже, что процесс Python должен выполняться на том же компьютере, что и Datahose, так что большие файлы .h5 не нужно передавать по сети, а гораздо меньшие, отфильтрованные представления будут передаваться клиентам. Pyro представляется интересным выбором - у кого-нибудь есть опыт с этим?

Ответы [ 4 ]

13 голосов
/ 23 декабря 2009

Это эпический вопрос, и есть много соображений. Поскольку вы не упомянули какие-либо конкретные рабочие характеристики или архитектурные ограничения, я постараюсь предложить лучшие всесторонние предложения.

Первоначальный план использования PyTables в качестве промежуточного слоя между вашими другими элементами и файлами данных кажется надежным. Тем не менее, одно из конструктивных ограничений, которое не было упомянуто, является одним из наиболее важных из всех процессов обработки данных: какие из этих задач обработки данных могут быть выполнены в стиле пакетной обработки, а какие задачи обработки данных являются скорее живым потоком.

Это различие между «мы знаем точно наш ввод и вывод и можем просто выполнить обработку» (пакет) и «мы знаем наш ввод и то, что должно быть доступно для чего-то еще, чтобы спросить» (в режиме реального времени), имеет значение для архитектурный вопрос. Глядя на вашу диаграмму, есть несколько отношений, которые подразумевают разные стили обработки.

Кроме того, на диаграмме есть компоненты разных типов, использующие одни и те же символы. Это немного затрудняет анализ ожидаемой производительности и эффективности.

Еще одно существенное ограничение - ваша ИТ-инфраструктура. Есть ли у вас доступ к высокоскоростной сети? Если вы это сделаете, промежуточные файлы станут отличным, простым и быстрым способом обмена данными между элементами вашей инфраструктуры для всех задач пакетной обработки. Вы упомянули, что запускаете приложение PyTables-using-application на том же сервере, на котором выполняется симуляция Java. Однако это означает, что сервер будет испытывать нагрузку как для записи, так и для чтения данных. (То есть, на среду моделирования могут влиять потребности несвязанного программного обеспечения при запросе данных.)

Чтобы ответить на ваши вопросы напрямую:

  • PyTables выглядит как хороший матч.
  • Существует множество способов взаимодействия Python и Java, но рассмотрим метод связи, не зависящий от языка, чтобы эти компоненты можно было изменить позже, если это необходимо. Это так же просто, как найти библиотеки, которые поддерживают Java и Python, и попробовать их. API, который вы выбираете для реализации с любой библиотекой, должен быть одинаковым в любом случае. (XML-RPC отлично подойдет для создания прототипов, поскольку в стандартной библиотеке Google Protocol Buffers или Facebook Thrift делают хорошие производственные решения. Но не стоит недооценивать, насколько велика и проста простая «запись вещей в промежуточные файлы», если данные предсказуемый и пакетный.

Чтобы помочь в процессе проектирования и конкретизировать ваши потребности:

Легко взглянуть на небольшой кусочек головоломки, сделать некоторые разумные предположения и перейти к оценке решения. Но еще лучше взглянуть на проблему целостно с четким пониманием ваших ограничений. Могу ли я предложить этот процесс:

  • Создайте две диаграммы вашей текущей архитектуры, физической и логической.
    • На физической диаграмме создайте поля для каждого физического сервера и нарисуйте физические связи между ними.
      • Обязательно пометьте ресурсы, доступные для каждого сервера, а также тип и ресурсы, доступные для каждого соединения.
      • Включите физическое оборудование, которое не используется в текущей настройке, если это может быть полезно. (Если у вас есть доступная сеть SAN, но вы ее не используете, включите ее на случай, если решение захочет.)
    • На логической диаграмме создайте поля для каждого приложения , работающего в вашей текущей архитектуре.
      • Включите соответствующие библиотеки в виде блоков внутри блоков приложений. (Это важно, потому что ваша будущая схема решения в настоящее время содержит PyTables как блок, но это всего лишь библиотека и ничего не может сделать самостоятельно.)
      • Использование ресурсов диска (например, файлов HDF5 и CSV) в виде цилиндров.
      • При необходимости подключите приложения со стрелками к другим приложениям и ресурсам. Всегда рисуйте стрелку от «актера» до «цели». Так что, если приложение пишет и файл HDF5, стрелка идет из приложения в файл. Если приложение считывает файл CSV, стрелка переходит из приложения в файл.
      • Каждая стрелка должна быть помечена механизмом связи. Стрелки без метки показывают отношения, но они не показывают какие отношения, и поэтому они не помогут вам принимать решения или сообщать об ограничениях.

Как только вы сделаете эти диаграммы, сделайте несколько их копий, а затем прямо над ними начните рисовать наброски потока данных. С копией диаграммы для каждого приложения «конечная точка», которому нужны ваши исходные данные, начните с симуляции и закончите в конечной точке довольно сплошной плавной стрелкой. Каждый раз, когда стрелка ваших данных пересекает стрелку связи / протокола, запишите изменения данных (если они есть).

На этом этапе, если вы и ваша команда все согласны с тем, что написано на бумаге, тогда вы объяснили свою текущую архитектуру так, чтобы ее можно было легко донести до любого. (Здесь не только помощники по работе со стеком, но и боссы, менеджеры проектов и другие владельцы кошельков.)

Чтобы приступить к планированию своего решения, посмотрите на свои диаграммы потоков данных и пройдите назад от конечной точки к начальной точке и создайте вложенный список, который содержит все приложения и промежуточный формат на пути назад к началу. Затем перечислите требования для каждого приложения. Обязательно укажите:

  • Какие форматы данных или методы могут использовать это приложение для связи.
  • Какие данные он действительно хочет. (Это всегда одно и то же или меняется по прихоти в зависимости от других требований?)
  • Как часто это нужно.
  • Примерно сколько ресурсов требуется приложению.
  • Что делает приложение сейчас, когда оно работает не так хорошо.
  • Что теперь может сделать это приложение, которое могло бы помочь, но оно не работает.

Если вы хорошо поработали с этим списком, вы увидите, как это поможет определить, какие протоколы и решения вы выберете. Вы смотрите на ситуации, когда данные пересекают линию связи, и сравниваете список требований для обеих сторон связи.

Вы уже описали одну конкретную ситуацию, когда у вас есть довольно много кода пост-обработки java, который делает «соединения» с таблицами данных в файлах CSV, то есть «делай сейчас, но не делай этого хорошо» , Итак, вы смотрите на другую сторону этого общения, чтобы увидеть, может ли другая сторона сделать это хорошо. В этот момент другой стороной является CSV-файл, а до этого - симуляция, так что нет, ничто не может сделать это лучше в текущей архитектуре.

Итак, вы предложили новое приложение Python, которое использует библиотеку PyTables для улучшения этого процесса. Звучит хорошо, пока! Но на следующей диаграмме вы добавили множество других вещей, которые говорят о «PyTables». Теперь мы расширили понимание группы здесь, в StackOverflow, потому что мы не знаем требований этих других приложений. Но если вы составите список требований, как указано выше, вы точно будете знать, что следует учитывать. Возможно, ваше приложение Python, использующее PyTables для обеспечения запросов к файлам HDF5, может поддерживать все эти приложения. Может быть, он будет поддерживать только один или два из них. Возможно, он будет предоставлять запросы в реальном времени к постпроцессору, но периодически записывать промежуточные файлы для других приложений. Мы не можем сказать, но с планированием, вы можете.

Некоторые окончательные рекомендации:

  • Не усложняйте! Врагом здесь является сложность. Чем сложнее ваше решение, тем сложнее его реализовать и тем выше вероятность его отказа. Используйте наименьшее количество операций, используйте наименьшие сложные операции. Иногда просто одно приложение для обработки запросов для всех других частей вашей архитектуры является самым простым. Иногда лучше использовать приложение для обработки «живых» запросов и отдельное приложение для обработки «пакетных запросов».
  • Не усложняйте! Это большое дело! Не пишите ничего, что уже может быть сделано для вас. (Вот почему промежуточные файлы могут быть настолько хороши, что ОС обрабатывает все сложные части.) Кроме того, вы упомянули, что реляционная база данных требует слишком много времени, но учтите, что реляционная база данных также поставляется с очень выразительным и хорошо известным запросом. язык, сетевой протокол связи, который идет с ним, и вам не нужно ничего разрабатывать, чтобы использовать его! Какое бы решение вы ни предложили, оно должно быть лучше , чем использование готового решения, которое наверняка будет работать, очень хорошо, или это не лучшее решение.
  • Часто обращайтесь к документации по физическому уровню , чтобы вы понимали, как использовать ресурсы. Медленное сетевое соединение или слишком большая нагрузка на один сервер могут исключить хорошие решения.
  • Сохраните эти документы. Что бы вы ни решили, документация, которую вы сгенерировали в процессе, является ценной. Вики-им или подайте их, чтобы вы могли снова их достать, когда тема поднимется.

И ответ на прямой вопрос: «Как заставить Python и Java хорошо играть вместе?» это просто «использовать независимый от языка метод общения». Дело в том, что Python и Java не важны для описания проблем. Важны данные, проходящие через него. Все, что может легко и эффективно обмениваться данными, будет в порядке.

5 голосов
/ 23 декабря 2009

Не делайте это более сложным, чем нужно.

Ваш Java-процесс может - просто - создать отдельный подпроцесс для выполнения ваших запросов PyTables. Позвольте операционной системе делать то, что лучше всего работают ОС.

Ваше Java-приложение может просто обработать процесс, который имеет необходимые параметры в качестве параметров командной строки. Затем ваша Java может перейти к следующему шагу, пока Python работает в фоновом режиме.

Это имеет ОГРОМНЫЕ преимущества с точки зрения одновременной производительности. Ваш «бэкэнд» Python работает одновременно с вашим «внешним интерфейсом» симуляции Java.

0 голосов
/ 22 августа 2010

Не уверен, что это хороший этикет. Я не смог уместить все свои комментарии в обычный комментарий, и пост неактивен в течение 8 месяцев.

Просто хотел посмотреть, как у тебя дела? У нас очень и очень похожая ситуация, когда я работаю - только симуляция написана на C, а формат хранения - двоичные файлы. Каждый раз, когда начальник хочет другое резюме, мы должны сделать / изменить рукописный код, чтобы сделать резюме. Наши бинарные файлы имеют размер около 10 ГБ, и есть один из них на каждый год симуляции, так что, как вы можете себе представить, все становится волосатым, когда мы хотим запустить его с разными семенами и тому подобным.

Я только что обнаружил pyTables, и у меня была идея, похожая на вашу. Я надеялся изменить формат хранения на hdf5, а затем запустить наши сводные отчеты / запросы, используя pytables. Часть этого включает в себя объединение таблиц с каждым годом. Вам повезло, когда вы выполняли такие "объединения" с использованием pytables?

0 голосов
/ 23 декабря 2009

Вы можете попробовать Jython , интерпретатор Python для JVM, который может import Java-классы.

Домашняя страница проекта Jython

К сожалению, это все, что я знаю по этому вопросу.

...