Как повысить производительность приложения для передачи стоковых данных? - PullRequest
1 голос
/ 18 октября 2011

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

Мое приложение состоит из двух частей:

  1. Первый работает на сервере, который называется «ROOT server». Он будет получать данные о запасах в реальном времени от HKEx (биржи ценных бумаг и фьючерсов в Гонконге) и транслировать их на 5 других дочерних серверов. Он добавит метку времени к каждому элементу данных при трансляции.

  2. Вторые работают на «дочерних» серверах. Они получат данные о запасах от ROOT-сервера, проанализируют каждый из них и получат важную информацию. Наконец, они отправят их в новом текстовом формате клиентам. Число клиентов может составлять от сотен до тысяч, они могут зарегистрироваться на какие-то акции и получать информацию о них в реальном времени.

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

На данный момент, когда скорость передачи данных от HKEx составляет 200 КБ и имеется 5 дочерних серверов, первое приложение будет иметь задержку 10 мс для каждого элемента данных в среднем. И второе не легко проверить, это зависит от количества клиентов.

Что я использую:

  1. OpenSUSE 10
  2. Sun Java 5.0
  3. Мина 2,0

Аппаратное обеспечение сервера:

  1. 4-ядерный процессор (я не знаю тип)
  2. 4G баран

Я думаю о том, как улучшить производительность.

  1. Нужно ли использовать параллельный фреймворк как akka
  2. попробуйте другой язык, например Scala? C ++?
  3. использовать систему Java в реальном времени ?
  4. ваши советы ...

Нужна ваша помощь!


Обновление:

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

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

Как работает первое приложение

Первое приложение получит данные о запасах от HKEx и передаст их на несколько других серверов. Шаги:

  1. Соединяет HKEx
  2. логины
  3. читает данные. Данные представлены в двоичном формате, каждый элемент имеет заголовок, который составляет 2 байта целого числа, что означает длину тела, затем тело, затем следующий элемент.
  4. поместите их в хэш-карту в памяти. Ключ - это последовательность элементов, значение - байтовый массив.
  5. записать последовательность каждого полученного элемента на диск. Используйте буферное приложение log4j.
  6. поток демона пытается прочитать данные из hashmap и вставляет их в postgresql каждую 1 минуту. (это просто используется для резервного копирования данных)
  7. когда клиенты подключаются к этому серверу, он принимает их и пытается отправить все данные из hashmap из памяти. Я использовал пул потоков в минах, получатель и отправители находятся в разных потоках.

Я думаю, что логика очень проста. Когда было 5 клиентов, я следил за скоростью передачи не более 1,5 М / с. Я использовал java для написания простейшей сокетной программы и обнаружил, что она может быть 10M / s.

На самом деле, я потратил более 1 года, пробуя всевозможные решения для этого приложения, просто чтобы сделать его быстрее. Вот почему я чувствую отчаяние. Нужно ли использовать другой язык, кроме Java?


задержка около 10 мс

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

когда дочерние сервер получает данные, он отправляет сообщение корневому серверу, чтобы получить текущую временную метку, затем сравниваетих.

Итак, задержка 10 мс содержит:

  1. Корневой сервер получил данные ---> Дочерний сервер получил данные
  2. Дочерний сервер отправил запрос на rootотметка времени сервера ---> корневой сервер получил ее

Но вторая очень мала, поэтому мы можем ее игнорировать.

Ответы [ 3 ]

4 голосов
/ 18 октября 2011

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

Доступны профилировщики с открытым исходным кодом, такие как http://www.eclipse.org/tptp/,, или коммерческие профилировщики, такие как Yourkit Java Profiler.

Одна простая вещь дляЭто может быть сделано для обновления JVM до Java SE6 или Java 7. Общие характеристики JVM значительно улучшились в версии 6. Подробнее см. http://java.sun.com/performance/reference/whitepapers/6_performance.html.

1 голос
/ 19 октября 2011

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

  • Сервер HK Ex (вне вашего контроля)
  • Сеть между Exchange и вашей системой
  • «Корневой» сервер
  • Сеть между «корневым» и «дочерним» серверами
  • «Дочерний»серверы
  • Сеть между "дочерними" серверами и клиентом
  • Клиенты

Чтобы узнать, где провести время, деньги и энергию, я бы хотелменьше всего хочется посмотреть анализ этих компонентов, сколько времени занимает каждый компонент (min, max, avg) и какова спецификация каждого ресурса.

Самая простая вещь, которую можно изменить, - это аппаратное обеспечение - большие серверы, больше памяти и т. Д. Или более высокая пропускная способность.Можете ли вы увидеть, ограничен ли какой-либо из этих ресурсов?

Следующее, на что стоит обратить внимание, это изменить протокол связи, чтобы сделать его более эффективным - как клиенты получают акции?Можете ли вы уменьшить размер данных?1.5M только для 5 клиентов звучит очень много ...

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

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

В самом конце списка я бы рассмотрел другой стек технологий;Java - прекрасный язык программирования, но если ключевым приоритетом является абсолютная производительность, C / C ++ все еще быстрее.Понятно, что это огромное изменение, и хорошо написанное Java-приложение будет быстрее, чем плохо написанное приложение C / C ++ (и гораздо более стабильное).

1 голос
/ 19 октября 2011

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

То, что вы хотите получить, - это отметка времени на ключевых этапах вашего приложения 3-5, для начала достаточно. Обычно я бы использовал System.nanoTime (), потому что я искал микросекундные задержки, но в вашем случае System.currentTimeMillis (), вероятно, будет достаточно, особенно если вы усредняете по многим выборкам (вы все равно получите точность 0,1 мс средний, с Ubuntu)

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

Я бы проанализировал любую стадию, в которой для вашей ситуации была задержка более 1 мс.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...