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 .