Есть ли облегченная версия Chronicle Queue, в которой не используется зацикливание?

Я хочу использовать Chronicle Queuues в качестве входящих для пользовательских сообщений, чтобы каждый пользователь моего приложения имел своя очередь. Однако я столкнулся со следующими «проблемами»:

  1. Поскольку количество сообщений на одного пользователя не так велико, все сообщения для одного пользователя можно хранить в одном файле очереди без циклов. Как отключить зацикливание?

  2. Если можно отключить циклирование, может ли вся очередь храниться в одном файле вместо каталога, содержащего один файл очереди плюс directory-listing.cq4t ?

  3. В моей ОС Linux с файловой системой EXT4 пустая очередь занимает 83,9 МБ дискового пространства. Можно ли уменьшить его, чтобы он занимал только примерно размер содержимого?

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


person xpages-noob    schedule 13.01.2018    source источник
comment
Альтернативой является наличие карты хроник с последним сообщением для любого пользователя. Последнее сообщение может содержать индекс предыдущего сообщения и т. д. в виде связанного списка. Таким образом, вы можете получить все сообщения для идентификатора пользователя за линейное время.   -  person Peter Lawrey    schedule 19.01.2018
comment
@PeterLawrey: Спасибо за подсказку. Как описано в комментарии ниже, ваше решение похоже на то, как оно реализовано в настоящее время. Однако из-за того ограничения, что я должен заранее установить максимальное количество записей ChronicleMap, я хотел проверить, может ли очередь быть лучшим решением для хранения пользовательских почтовых ящиков/потоков сообщений.   -  person xpages-noob    schedule 19.01.2018
comment
вам нужен только один ключ для каждого пользователя, а не один для каждого сообщения, а размер Chronicle Map v3 изменяется по мере необходимости.   -  person Peter Lawrey    schedule 20.01.2018
comment
@PeterLawrey: (1.) Я неправильно истолковал ваш комментарий: вы предложили иметь карту хроник ТОЛЬКО для последнего сообщения каждого пользователя в ДОПОЛНЕНИЕ к очереди. Конечно, это тоже сработает. (2.) Если я правильно информирован, Chronicle Map v3 (я использую 3.14.5) позволяет определить коэффициент раздувания, который позволяет иметь гораздо больше ключей, чем изначально установлено. Однако, по словам г-на Левентова, производительность начинает снижаться, когда количество записей превышает исходное число более чем на 20% ( stackoverflow .com/a/48059859/1697566).   -  person xpages-noob    schedule 20.01.2018
comment
с другой стороны, карта достаточно эффективна, если она используется недостаточно. Например, сделайте это в 10 раз больше, чем вы думаете.   -  person Peter Lawrey    schedule 21.01.2018


Ответы (1)


Чтобы уменьшить размер файлов, вы можете уменьшить blockSize, используемый очередью:

try (final SingleChronicleQueue queue = SingleChronicleQueueBuilder.binary(tmpDir.newFolder()).
    blockSize(4096).
    build()) {

Вы можете сохранить имя почтового ящика как часть каждого события:

try (final DocumentContext documentContext = 
    queue.acquireAppender().writingDocument()) {
    documentContext.wire().getValueOut().
    text("user@mailbox").writeText(email);
}

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

final AtomicLong fixedClock = new AtomicLong(System.currentTimeMillis());
try (final SingleChronicleQueue queue = SingleChronicleQueueBuilder.binary(tmpDir.newFolder()).
        timeProvider(fixedClock::get).
        blockSize(4096).
        build()) {

Обратите внимание, что этот режим работы не поддерживается.

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

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

person Mark Price    schedule 15.01.2018
comment
Спасибо за ваш ответ и полезные фрагменты кода. О втором фрагменте: когда я добавляю имя почтового ящика в качестве идентификатора к событию, не означает ли это, что мне придется перебирать всю очередь и проверять каждое событие, чтобы получить все сообщения, связанные с данным почтовым ящиком? Если есть, например, 100 000 пользователей со 100 сообщениями каждый, мне в худшем случае придется повторять и проверять 10 миллионов событий каждый раз, когда я хочу получить почтовый ящик одного пользователя. Или в очереди Chronicle происходит какая-то индексация, о которой я не знаю? - person xpages-noob; 17.01.2018
comment
Да, вам нужно будет просмотреть всю очередь - извините, ваш вариант использования не ясен. Без лучшего представления о требованиях вашего приложения трудно предложить, как использовать Chronicle Queue. Учитывая, что у вас около 100 000 пользователей со 100 сообщениями, возможно, лучше подойдет база данных? - person Mark Price; 18.01.2018
comment
То, что вы предлагаете, на самом деле реализовано в настоящее время: все сообщения хранятся в ChronicleMap. Ключи генерируются из идентификатора почтового ящика плюс постоянно увеличивающийся порядковый номер. Таким образом, я могу легко получить n-е сообщение в каждом ящике или перебрать все сообщения в ящике. Основная проблема заключается в том, что ChronicleMap ограничен фиксированным количеством записей. Если я разрешаю раздувание, считается, что производительность снижается, как только появляется на 20 % больше записей, чем изначально установлено. Следовательно, я хотел проверить, может ли использование очередей быть альтернативным вариантом в моей ситуации. - person xpages-noob; 18.01.2018
comment
PS: я знаю, что мог бы заменить ChronicleMap любой базой данных типа «ключ-значение», но я выбрал ее из-за ее высокой производительности записи, надежной производительности чтения и простоты использования. - person xpages-noob; 18.01.2018
comment
Тогда я думаю, что ответ на ваш первоначальный вопрос заключается в том, чтобы уменьшить размер блока, использовать фиксированные часы и иметь каталог для каждого почтового ящика. Вы по-прежнему не сможете получить произвольный доступ к каждому почтовому ящику; вам придется реализовать что-то вроде бинарного поиска с использованием индексов ExcerptTailer. По-прежнему звучит так, что база данных может лучше подойти для вашего сценария. Если вам требуется более высокая производительность записи, вы всегда можете реализовать журнал упреждающей записи, используя очередь, которая сохраняется в базе данных в фоновом режиме. - person Mark Price; 19.01.2018
comment
Спасибо за вашу помощь. Поскольку очереди, похоже, не обеспечивают лучшего способа организации данных, с которыми я имею дело, я оставлю реализованное в настоящее время решение на основе ChronicleMap. - person xpages-noob; 19.01.2018