У меня есть приложение, представляющее собой смесь Java и C++ на Solaris. Аспекты кода Java запускают веб-интерфейс и устанавливают состояние на устройствах, с которыми мы разговариваем, а код C++ выполняет обработку данных, возвращаемых с устройств, в реальном времени. Общая память используется для передачи информации о состоянии устройства и контекста из кода Java в код C++. Код Java использует базу данных PostgreSQL для сохранения своего состояния.
Мы сталкиваемся с довольно серьезными узкими местами в производительности, и сейчас единственный способ масштабирования - это увеличить количество памяти и ЦП. Мы застряли на одной физической коробке из-за дизайна с общей памятью.
По-настоящему большой успех здесь получил код C++. Веб-интерфейс довольно легко используется для настройки устройств; где мы действительно боремся, так это с обработкой объемов данных, которые устройства доставляют после настройки.
Каждый фрагмент данных, который мы получаем от устройства, имеет идентификатор, который указывает на контекст устройства, и нам нужно его найти. Прямо сейчас существует ряд объектов общей памяти, которые поддерживаются кодом Java / UI и упоминаются кодом C++, и это узкое место. Из-за этой архитектуры мы не можем перенести обработку данных C++ на другую машину. Нам нужно иметь возможность масштабирования, чтобы различные подмножества устройств могли обрабатываться на разных машинах, но тогда мы теряем возможность выполнять этот поиск контекста, и это проблема, которую я пытаюсь решить: как разгрузить реальную время обработки данных в другие блоки, сохраняя при этом возможность ссылаться на контекст устройства.
Следует отметить, что мы не контролируем протокол, используемый самими устройствами, и нет никаких шансов, что ситуация изменится.
Мы знаем, что нам нужно отойти от этого, чтобы иметь возможность масштабировать, добавляя больше машин в кластер, и я нахожусь на ранних этапах работы над тем, как именно мы это сделаем.
Прямо сейчас я смотрю на Terracotta как на способ масштабирования кода Java, но я еще не дошел до разработки того, как масштабировать C++ для соответствия.
Помимо масштабирования производительности, нам также необходимо учитывать высокую доступность. Приложение должно быть доступно практически все время - не на 100%, что неэффективно с точки зрения затрат, но нам нужно проделать разумную работу по выживанию в случае сбоя машины.
Если бы вам пришлось выполнить порученное мне задание, что бы вы сделали?
Обновлено: Основываясь на данных, предоставленных @john channing, я смотрю как на GigaSpaces, так и на Gemstone. Oracle Coherence и IBM ObjectGrid, похоже, предназначены только для java.




Вам нужно масштабироваться в стороны и наружу. Может быть, что-то вроде очередь сообщений могло бы быть бэкэндом между интерфейсом и кранчем.
Первое, что я сделал бы, - это построил бы модель системы, чтобы отобразить поток данных и попытаться точно понять, где находится узкое место. Если вы можете смоделировать свою систему как трубопровод, тогда вы сможете использовать теорию ограничений (большая часть литературы посвящена оптимизации бизнес-процессов, но она в равной степени применима к программному обеспечению) для постоянного повышения производительности и устранения узких мест.
Затем я хотел бы собрать некоторые достоверные эмпирические данные, которые точно характеризуют производительность вашей системы. Это что-то вроде клише: вы не можете управлять тем, что не можете измерить, но я видел, как многие люди пытались оптимизировать систему программного обеспечения, основываясь на догадках, и терпели неудачу.
Затем я бы использовал Принцип Парето (правило 80/20), чтобы выбрать небольшое количество вещей, которые принесут наибольший выигрыш, и сосредоточился бы только на них.
Чтобы масштабировать Java-приложение по горизонтали, я широко использовал Oracle Coherence. Хотя некоторые считают его очень дорогим распределенная хеш-таблица, функциональность намного богаче, и вы можете, например, напрямую обращаться к данным в кэше из Код C++.
Другими альтернативами горизонтального масштабирования вашего Java-кода могут быть Гигапространства, IBM Object Grid или Драгоценный камень Драгоценный огонь.
Если ваш код C++ не имеет состояния и используется исключительно для обработки чисел, вы можете рассмотреть возможность распределения процесса с помощью ICE Grid, который имеет привязки для всех языков, которые вы используете.
Эндрю, (в дополнение к моделированию в виде конвейера и т. д.) Измерения важны. Вы запустили профилировщик кода и получили показатели того, на что тратится большая часть времени?
Что касается кода базы данных, как часто он меняется? Вы сейчас смотрите на кеширование? Я предполагаю, что вы просмотрели индексы и т. д. По данным, чтобы ускорить Db?
Какие уровни трафика у вас есть на интерфейсе? Вы кешируете веб-страницы? (Нетрудно сказать, что для связи между компонентами используется api типа JMS. Затем вы можете разместить компонент веб-страницы на одном компьютере (или нескольких), а затем поместить код интеграции (C++) на другой, а для многих JMS продукты, как правило, это собственные C++ api, т. е. ActiveMQ приходит на ум), но это действительно помогает узнать, сколько времени уходит на Web (JSP?), C++, Database ops.
Хранит ли база данных бизнес-данные или она также используется для передачи данных между Java и C++? Вы говорите, что используете общую память, а не JNI? Какой уровень многопоточности в настоящее время существует в приложении? Вы бы описали код как синхронный по своей природе или асинхронный?
Существует ли физическая связь между кодом Solaris и устройствами, которые необходимо поддерживать (т. Е. Все ли устройства регистрируются с помощью кода C++, или это можно указать)? т.е. Если бы вы поставили балансировщик веб-нагрузки на интерфейс и просто поставили сегодня 2 машины, то есть ли связь между устройствами, управляемыми блоком, инициализированным заранее или заранее?
Каковы требования к высокой доступности? т.е. просто указать информацию? Можно ли выполнить HA только на веб-уровне путем кластеризации данных сеанса?
БД работает на другом компьютере?
Насколько велика БД? Вы оптимизировали свои запросы, т.е. Попытка использовать явные внутренние / внешние соединения иногда помогает по сравнению с вложенными подзапросами (иногда). (снова посмотрите статистику sql).