Сжатие файла журнала JSON
Имеется файл с записями JSON с разделителями строк:
{"id": 1, "position": 1234}
{"id": 2, "position": 23}
{"id": 3, "position": 43}
{"id": 1, "position": 223}
Я хотел бы сжать такой файл, сохраняя только последнюю запись для идентификатора, например, для приведенного выше примера, который я хотел бы иметь в качестве вывода:
{"id": 2, "position": 23}
{"id": 3, "position": 43}
{"id": 1, "position": 223}
tldr; Есть ли uniq
что работает с JSON (и быстро)?
Входные файлы могут содержать 1 миллиард записей, из которых 10-20% записей могут быть выброшены.
Я пробовал разные подходы:
Увиденные идентификаторы
Храните набор "увиденных" идентификаторов в памяти. Это заканчивается памяти.
Сортировка и уникальность
Сначала отсортируйте файл по "id" (со стабильной сортировкой, поэтому порядок сохраняется). Затем снова запустите файл и сохраните последнюю запись. Это как обычный Unix
sort | uniq
подход. Сортировка здесь дорогая и, возможно, просто слишком много работы.Извлечь информацию о смещении и длине
Извлечь информацию о смещении и длине, а также идентификатор из файла, например
id offset length 1 0 27 2 27 25 3 52 25 1 77 26
и выяснить, какие записи будут принадлежать компактному набору. Затем найдите и прочитайте файл. Извлечение этой информации достаточно быстрое, но миллионы поисков и чтений для извлечения записей замедляют этот подход.
Что может быть лучше, быстрее (или быстрее)? Существуют ли инструменты, которые решают эту проблему?
1 ответ
Эта проблема может быть решена в три этапа:
- Извлекайте интересные значения (плюс номер строки) с помощью таких инструментов, как jq или ldjtab.
- использование
tac
а такжеsort -u
сохранить только соответствующие строки. - Фильтруйте исходный файл и сохраняйте только указанные строки (такие инструменты, как filterline или несколько других подходов, будут фильтровать файл и сохранять только определенные указанные строки).
Общий процесс довольно эффективен. Шаг 1 и 2 распараллеливаются. Шаг 3 можно сделать быстро.