Рубрики
Без рубрики

Введение в Большую очередь

Узнайте о Большой очереди, Java-реализации постоянной очереди.

Автор оригинала: baeldung.

1. Обзор

В этом уроке мы быстро рассмотрим Big Queue , Java-реализацию постоянной очереди .

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

2. Использование

Нам нужно будет добавить зависимость big queue в наш проект:


    com.leansoft
    bigqueue
    0.7.0

Нам также нужно добавить его репозиторий:


    github.release.repo
    https://raw.github.com/bulldog2011/bulldog-repo/master/repo/releases/

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

2.1. Инициализация

Мы можем инициализировать нашу очередь, просто вызвав ее конструктор:

@Before
public void setup() {
    String queueDir = System.getProperty("user.home");
    String queueName = "baeldung-queue";
    bigQueue = new BigQueueImpl(queueDir, queueName);
}

Первый аргумент – это домашний каталог для нашей очереди.

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

Мы должны не забыть закрыть нашу очередь, когда закончим, чтобы предотвратить утечку памяти:

bigQueue.close();

2.2. Вставка

Мы можем добавить элементы в хвост, просто вызвав метод enqueue :

@Test
public void whenAddingRecords_ThenTheSizeIsCorrect() {
    for (int i = 1; i <= 100; i++) {
        bigQueue.enqueue(String.valueOf(i).getBytes());
    }
 
    assertEquals(100, bigQueue.size());
}

Следует отметить, что Большая очередь поддерживает только тип данных byte [] , поэтому мы несем ответственность за сериализацию наших записей при вставке.

2.3. Чтение

Как мы и ожидали, чтение данных так же просто с помощью метода dequeue :

@Test
public void whenAddingRecords_ThenTheyCanBeRetrieved() {
    bigQueue.enqueue(String.valueOf("new_record").getBytes());

    String record = new String(bigQueue.dequeue());
 
    assertEquals("new_record", record);
}

Мы также должны быть осторожны, чтобы правильно десериализовать наши данные при чтении.

Чтение из пустой очереди вызывает Исключение NullPointerException .

Мы должны убедиться, что в нашей очереди есть значения, используя метод isEmpty :

if(!bigQueue.isEmpty()){
    // read
}

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

bigQueue.removeAll();

2.4. Подглядывание

Когда мы подглядываем, мы просто читаем запись, не потребляя ее:

@Test
public void whenPeekingRecords_ThenSizeDoesntChange() {
    for (int i = 1; i <= 100; i++) {
        bigQueue.enqueue(String.valueOf(i).getBytes());
    }
 
    String firstRecord = new String(bigQueue.peek());

    assertEquals("1", firstRecord);
    assertEquals(100, bigQueue.size());
}

2.5. Удаление Использованных Записей

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

Это потенциально может заполнить наш диск ненужными данными.

К счастью, мы можем удалить использованные записи с помощью gc метод:

bigQueue.gc();

Точно так же, как сборщик мусора в Java очищает несвязанные объекты из кучи, gc очищает использованные записи с нашего диска.

3. Архитектура и особенности

Что интересно в большой очереди, так это то, что ее кодовая база чрезвычайно мала — всего 12 исходных файлов, занимающих около 20 КБ дискового пространства.

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

3.1. Обработка больших объемов данных

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

Нашим узким местом будет дисковый ввод-вывод, а это означает, что SSD значительно повысит среднюю пропускную способность по сравнению с жестким диском.

3.2. Чрезвычайно Быстрый Доступ К Данным

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

Даже если наша очередь станет чрезвычайно большой и займет терабайты дискового пространства, мы все равно сможем считывать данные в O(1) временной сложности.

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

3.3. Преимущества

Большим преимуществом является его способность расти очень большими размерами. Мы можем масштабировать его до теоретической бесконечности, просто добавив больше памяти, отсюда и его название “Большой”.

В параллельной среде Большая очередь может производить и потреблять около 166 Мбит/с данных на одной машине.

Если наш средний размер сообщения составляет 1 КБ, он может обрабатывать 166 тыс. сообщений в секунду.

Он может передавать до 333 тысяч сообщений в секунду в однопоточной среде- довольно впечатляюще!

3.4. Недостатки

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

Мы также несем ответственность за сериализацию и десериализацию наших сообщений.

4. Заключение

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

Как всегда, код доступен на Github .