Как удалить дубликаты 130 миллионов файлов и отсортировать их по размеру на относительно ограниченном сервере?

Их около 130 миллионов (129923145, точнее, на find. -Name "*. *" | Wc -l ) картинки на сервере. Их необходимо исключить из дубликатов и упаковать в zip-архивы от самых маленьких до самых больших на каждый миллион для дальнейшего использования. (скажем, если это 500 000 уникальных изображений 8 КБ, 600 000 уникальных изображений 16 КБ, 950 000 уникальных изображений 24 КБ, я должен упаковать 500 000 изображений 8 КБ и 500 000 изображений 16 КБ в первый файл zip, затем упаковать 100 000 изображений 16 КБ и 900 000 изображений 24 КБ во второй файл. , и остальное к третьему), имя файла должно быть сохранено, и лучше сохранить информацию об иерархии.

Сервер оснащен 32 ГБ памяти, 5,5 ТБ на жестком диске (доступно 122 ГБ), ЦП выглядит как E5-2680v4 , Я не знаю, физическая это или виртуальная машина. Я мог бы попросить товарищей по ИТ добавить память до 512 ГБ, но потребуется как минимум одна неделя, чтобы получить одобрение нашего технического директора, специалистов по цепочке поставок, бюджетного комитета и ИТ-отдела, возможно, потребуется дополнительное время, чтобы убедить их.

Нет лишнего дискового пространства, которое можно было бы использовать из-за рейда или чего-то подобного (айтишниками). Это интрасеть без интернета, и я предпочитаю не отправлять файл, чем подавать приложение. Это Ubuntu 16.04, я уверен, что можно использовать vim, python (2 и 3) и оболочку. Я могу использовать только ssh и не могу sudo .

Мое решение - использовать du -a для создания списка файлов, используя md5sum для de -дупликация, переименование всех файлов с абсолютным путем (замените / на __ DIVIDER __ ) и переместите весь файл в SIZE / MD5 / (fileNameWithAbsPath) , чем выберите один для каждого каталога. Во время этого я встретил "Ошибка индекса H-дерева" . Есть ли способ лучше (быстрее, проще и т. Д.) Закончить это и, если возможно, избежать ошибки индекса H-дерева?

Кстати, я шестой по долгу службы. Первые пятеро уволились с работы: (

2
задан 22 March 2019 в 19:00
1 ответ

Таким образом, один из способов обойти ошибку, с которой вы столкнулись - это разделить размер и md5 на несколько подполей. Для размера сначала нужно разбить его на фиксированное количество цифр.

Итак, допустим, вы создадите имя файла типа:

#size / md5              / name
12345 / aabbccddeeffgghh / foo__DIVIDER__bar__DIVIDER__baz.jpg

Измените его на:

# size        /md5                    /name
00/00/01/23/45/aa/bb/cc/dd/ee/ff/gg/hh/foo__DIVIDER__bar__DIVIDER__baz.jpg

...и вы ограничили уровень фанаута в любой заданной точке дерева, и таким образом избежали ошибки, о которой идет речь.


На самом деле, чтобы создать дерево имен файлов в этом формате, вы можете выглядеть как:

inDir=/path/to/tree/with/input/files
while IFS= read -r -d '' name; do
  sp=$(stat --format=%010s -- "$name") # sp as short for "size padded"

  size_dir=${sp:0:2}/${sp:2:2}/${sp:4:2}/${sp:6:2}/${sp:8:2}

  { read -r md5 _ < <(md5sum "$name") && [[ $md5 ]]; } || continue
  md5_left=$md5
  while [[ $md5_left ]]; do
    md5_dir+="/${md5_left:0:2}"
    md5_left=${md5_left:2}
  done

  sep=/
  final_name="${size_dir}${md5_dir}/${name//$sep/__DIVIDER__}"

  final_dir="${final_name%/*}"
  if [[ -d "$final_dir" ]]; then
    # Hardlink new file to existing ones (deduplication)
    # Be sure to use an archiver that understands hardlinks (not zip)!
    existing_files=( "$final_dir"/* )
    if [[ -e "${existing_files[0]}" || -L "${existing_files[0]}" ]]; then
      ln -- "${existing_files[0]}" "$final_name"
      ln -f -- "$final_name" "$file"  # and make our input file a hardlink as well
      continue
    fi
  fi

  # if we get here, the continue was not invoked
  mkdir -p -- "${final_name%/*}"
  ln -- "$name" "$final_name"
done < <(find "$inDir" -printf '%P\0')

Конечно, если у вас есть файлы размером более 9,999,999,999 байт, вы захотите добавить дополнительную подкладку (возможно, используя %012s вместо %010s, и соответствующим образом изменив вычисление size_dir).

.
4
ответ дан 3 December 2019 в 09:56

Теги

Похожие вопросы