Подтвердить что ты не робот

Python, PyTables, Java - связывание всех

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

Какой лучший способ заставить 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 не нужно передавать по сети, а гораздо меньшие, отфильтрованные представления будут передаваться клиентам. Поджигатель кажется интересным выбором - у кого-нибудь есть опыт с этим?

4b9b3361

Ответ 1

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Ответ 2

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

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

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

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

Ответ 4

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

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

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