обзор
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 миллионов запросов и ответов превысили дисковый кеш.