обзор
Java Chronicle
— это постоянная межпроцессная система обмена сообщениями, которая очень быстро работает при низком уровне. Однако, если вам не нужна эта предельная скорость, есть несколько простых способов использовать эту библиотеку с открытым исходным кодом. Один из них использовать распределенные коллекции Chronicle. Это очень просто в использовании, но довольно медленно.
Этот пост исследует промежуточное решение. Это быстрый (менее 10 микросекунд, 99,9% времени), сверхнизкий ГХ и работает хорошо, даже если у вас есть пакет данных больше, чем объем основной памяти.
Этот пост продолжается от сервисов с
малой задержкой, и демонстрация представляет собой реализацию шлюзов и механизма обработки на диаграмме.
Сервис по контракту
Чтобы смоделировать службу, нужно иметь интерфейс для методов / запросов / событий, которые вы хотите поддерживать, и другой интерфейс для событий вне механизма обработки. Демонстрация была добавлена, чтобы продемонстрировать этот подход.
Простая просьба перейти к процессору от шлюза. Вы можете иметь любое количество аргументов и использовать примитивы вместо командных объектов, но мы пытаемся быть простыми, а не сверхбыстрыми.
public interface Gw2PeEvents { public void small(MetaData metaData, SmallCommand command); } public class SmallCommand implements ExcerptMarshallable { public StringBuilder clientOrderId = new StringBuilder(); public String instrument; public double price; public int quantity; public Side side;
public interface Pe2GwEvents { public void report(MetaData metaData, SmallReport smallReport); } public class SmallReport implements ExcerptMarshallable { public CharSequence clientOrderId = new StringBuilder(); public ReportStatus status; public CharSequence rejectedReason = new StringBuilder();
Класс MetaData оборачивает временные метки для сквозного процесса. Он записывает десятую часть микросекунды времени, когда
- запрос написан
- запрос прочитан
- ответ написан
- ответ прочитан.
- Включает в себя sourceId и eventId, запускающий ответ, необходимый для перезапуска
Как это работает?
Пропускная способность на i8 3,8 ГГц с двумя шлюзами, генерирующими по 10 миллионов входящих и 10 миллионов исходящих сообщений, занимает 12,2 секунды для возврата к шлюзам, которые их отправляют, или 1,6 миллиона запросов / ответов в секунду. Для 200 миллионов сообщений скорость SSD начинает иметь значение, поскольку размер дискового кэша превышен, а производительность упала до 200 миллионов за 176 секунд или 1,1 миллиона в секунду.
Критические задержки, на которые нужно смотреть, — это не средние или типичные задержки, а более высокие процентили. В этом тесте 90-й, 99-й и 99,9-й процентили (наихудшие 10%, 1% и 0,1%) составляли 3,3
мкс, 4,9
мкс, 9,8
мкс. При более высокой нагрузке с 200 миллионами запросов и 200 миллионами ответов, при превышении объема основной памяти задержки увеличились до 4,2 мкс, 6,8 мкс и 28,8 мкс
Очень мало систем, которые могут обрабатывать всплески активности, которые превышают объем основной памяти, не слишком снижая производительность. (В 1,5–3 раза хуже)
Как выглядит профиль памяти?
Что такое ExcerptMarshallable?
@Override public void readMarshallable(Excerpt in) throws IllegalStateException { // changes often. clientOrderId.setLength(0); in.readUTF(clientOrderId); // cachable. instrument = in.readEnum(String.class); price = in.readDouble(); quantity = in.readInt(); side = in.readEnum(Side.class); } @Override public void writeMarshallable(Excerpt out) { out.writeUTF(clientOrderId); out.writeEnum(instrument); out.writeDouble(price); out.writeInt(quantity); out.writeEnum(side); }
Другие преимущества
Если вы считаете, что выполняется запись каждого отправленного сообщения, включая подробные отметки времени 0,1 мкс, вы получаете большую поддержку для очень точного отслеживания времени с минимальными затратами для приложения.
Что еще более важно, вы получаете детерминированный сервис, который можно воспроизвести, чтобы обеспечить воспроизводимость поведения и производительности.
Например, вы можете взять шлюз Chroincles из производства и воспроизвести его в своей тестовой среде без необходимости запуска реалистичных тестовых шлюзов.
Вы можете реплицировать хроники в тестовую систему в режиме реального времени, точно так же, как вы можете производить и видеть, что ваша тестовая система работает правильно с реальными данными.
Вывод
В то время как кодирование для Chronicle для получения максимальной производительности является очень низким уровнем, слишком низким для большинства разработчиков, вы все равно можете получить очень хорошую производительность с проектами более высокого уровня, которые облегчают использование.
Резюме производительности
- 20 миллионов: 1,6 миллиона в секунду, задержки 90/99 / 99,9%: 3,3 мкс, 4,9 мкс, 9,8 мкс.
- 200 миллионов: 1,1 миллиона в секунду, задержки 90/99 / 99,9%: 4,2 мкс, 6,8 мкс, 28,8 мкс
20 миллионов запросов и ответов помещаются в дисковый кеш и не оказали существенного влияния на производительность дисковой подсистемы.
200 миллионов запросов и ответов превысили дисковый кеш.