Для проекта, над которым я работал, мне нужна очередь, которая будет слишком большой для хранения в обычной памяти. Я реализовал его как простой файл, где он читал весь файл, забирал первые несколько (~ 100) строк, обрабатывал их, а затем записывал обновленную очередь с новыми добавленными инструкциями и удалял старые. Однако, поскольку очередь стала слишком большой для хранения в памяти, мне нужно что-то другое. Предпочтительно, кто-то может сказать мне способ очистить только первые несколько строк файла, не глядя на остальные данные. Я думал об использовании базы данных (MySQL, вероятно, с отсортированными временными метками вставки), но я бы предпочел сделать это без объяснения причин загрузки и пропускной способности (несколько серверов должны были бы отправлять и получать много данных из БД). Язык, на котором я работаю, - это PHP, но на самом деле этот вопрос больше касается файлов unix, я полагаю. Любая помощь будет оценена по достоинству.Реализация файла очереди PHP
ответ
Сосать первую строку файла довольно тривиально (fopen()
, а затем fgets()
). Повторная запись файла для удаления завершенных заданий будет очень болезненной, особенно если у вас есть несколько параллельных серверов, работающих с одним и тем же файлом очереди.
Один из вариантов - использовать отдельный файл для каждого задания. Если у вас есть метод параллельной работы для генерации инкрементирующего идентификатора для этих файлов, то было бы просто выбрать файл с наименьшим идентификатором для самого старого задания и создать новый идентификатор для каждого нового задания. Однако вам придется разобраться в блокировке файлов, однако, чтобы одновременно сохранить два + сервера, захватывающих один и тот же файл.
Я действительно использую блокировку - мне действительно нужен какой-то способ перемещения указателя, который означает начало файла вниз по уже выполненным строкам. – hackartist
вы можете использовать 'ftell()', чтобы получить позицию маркера 'start here' в файле очереди и сохранить это в отдельном файле. lock/read/update/write/unlock на небольшом ~ 10-байтовом файле будет довольно быстрым, и вы сможете легко прокручивать его прямо в нужное место в очереди. –
ok, который больше похож на то, что я ищу ... фактический размер файла очереди будет продолжать расти, поэтому я должен в какой-то момент выпустить его из одного объема памяти размером с один раз ... – hackartist
У меня были такие же проблемы, пока я работал на enqueue/fs транспорте. Я не смог изменить небольшую часть при попрошайничестве файла, не копируя его в память и не сохраняя обратно. Вместо этого, но это возможно сделать с концом файла. Вы можете прочитать часть, а затем усечь ее. Это не очередь, а стек. Поэтому, если вы полагаетесь на упорядочение сообщений, это не будет решением. В моем случае я блокирую файл, когда файл был прочитан из файла, блокировка освобождается.
Это, как вы можете писать сообщения в файл очереди:
<?php
$rawMessage = 'this your message to put to the queue as a string';
$queueFile = fopen('/path/to/queue/file', '+a');
// here it may add some spaces so the message length is multiples of modular.
// that make it easier to read messages from a file.
// lock file
$rawMessage = str_repeat(' ', 64 - (strlen($rawMessage) % 64)).$rawMessage;
fwrite($queueFile, $rawMessage);
// release lock
Это, как вы могли читать сообщения из файла очереди:
<?php
$queueFile = fopen('/path/to/queue/file', '+c');
// lock file
$frame = readFrame($file, 1);
ftruncate($file, fstat($file)['size'] - strlen($frame));
rewind($file);
$rawMessage = substr(trim($frame), 1);
// release lock
function readFrame($file, $frameNumber)
{
$frameSize = 64;
$offset = $frameNumber * $frameSize;
fseek($file, -$offset, SEEK_END);
$frame = fread($file, $frameSize);
if ('' == $frame) {
return '';
}
if (false !== strpos($frame, '|{')) {
return $frame;
}
return readFrame($file, $frameNumber + 1).$frame;
}
Для блокировки я предлагаю использовать Symfony LockHandler или просто взять enqueue/fs.
- 1. Реализация очереди PHP
- 2. Реализация очереди приоритетов PHP
- 3. Реализация очереди
- 4. Реализация очереди сообщений
- 5. Реализация простой очереди с PHP и MySQL?
- 6. реализация очереди с массивами
- 7. Реализация вектор в очереди
- 8. Реализация очереди приоритетов
- 9. Реализация очереди в java
- 10. LUA реализация очереди
- 11. реализация приоритета очереди python
- 12. приоритета реализация очереди объяснение
- 13. Реализация очереди как Array
- 14. реализация очереди (fifo)
- 15. Реализация более эффективной очереди
- 16. Реализация очереди приоритетов кучи
- 17. Реализация очереди LinkedList
- 18. реализация Массив из очереди
- 19. Реализация очереди в C
- 20. PostgreSQL - реализация надежной очереди
- 21. Реализация очереди потоков
- 22. Лучшая реализация очереди Java?
- 23. Реализация очереди в Java
- 24. Реализация очереди блоков (массив)?
- 25. Реализация очереди в C#
- 26. Реализация очереди в Python
- 27. Python Реализация очереди приоритетов
- 28. Реализация рельсов очереди 3
- 29. Реализация очереди Java FIFO
- 30. Реализация динамической очереди
«* несколько серверов должны будут отправлять и получать много данных из БД *». Это именно то, для чего предназначены серверы баз данных (и оптимизированы). – qJake
Я знаю, что база данных может справиться с этим, но меня больше беспокоит пропускная способность, связанная с постоянным запуском этого процесса и съемкой данных между всеми моими серверами ... Путь MySQL - это мое последнее средство, но мне бы очень хотелось, чтобы кто-то знает способ обновления файла для удаления первых нескольких строк без необходимости просмотра всех данных. – hackartist