У меня есть * много * исходных файлов для добавления в Git-репо, как сделать это быстро - PullRequest
1 голос
/ 28 мая 2019

Я ищу здесь , чтобы вдохновиться на быстрый импорт больших файлов в git-репо, но не уверен, что это так.

По сути, у меня> 100 миллионов файлов, которые я хочу зафиксировать в git-репо. Я разбил их на каталоги примерно на 5 глубин. До git add path/2/3 на некоторых уровнях требуется около 5 минут. Затем совершить, затем опубликовать. Это займет много времени и может занять месяцы, чтобы зафиксировать все эти файлы.

Пожалуйста, не удивляйтесь, почему я храню их в git, и являются ли они исходными файлами, и есть ли лучшее решение и т. Д. Я специально хочу узнать, сколько git может обработать и если это может обрабатывать такое количество файлов более оптимальным способом.

К вашему сведению, все это файлы конфигурации или файлы данных в формате CSV, некоторые очень большие, большинство из них маленькие.

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

Мне интересно, есть ли способ загрузить все эти вещи прямо в git одним махом, как если бы вы загружали в базу данных с дампом базы данных и обходили все вещи git, которые он делает при выполнении коммита? , Затем он создает коммит. Затем каким-то образом публикуйте, как это делает rsync, где он надежен и не разрывается, если разрывается интернет-соединение. Тогда это будет похоже на нормальную загрузку.

1 Ответ

2 голосов
/ 28 мая 2019

Существует несколько жестких ограничений на количество файлов (технически объекты BLOB-объектов ), которые может хранить база данных Git. 1 Однако существует несколько более мягких ограничений.

У меня есть два удобных репозитория - FreeBSD и Linux, которые весят 5,7 и 6,7 миллиона объектов.Это намного меньше, чем 100 миллионов файлов: репозиторий Linux примерно на 1/15 от этого размера, и даже тогда файлов не так много, так как многие объекты являются коммитами и деревьями.

Обратите внимание, что существует разница между помещением 100 миллионов файлов в один коммит и размещением 100 миллионов файлов в 100 миллионов коммитов, каждый из которых хранит один файл.Первый потребует создания индекса, в котором содержится 100 миллионов файлов, что составляет несколько гигабайт файла индекса и, вероятно, будет медленным, но затем в нем будет храниться 100 миллионов BLOB-объектов, плюс один объект дерева на каталог и один коммит.Последний будет создавать небольшой индекс (из 1 файла), делать один коммит, используя одно дерево, содержащее один большой двоичный объект, а затем повторять 100 миллионов раз: индекс никогда не будет большим, но в хранилище будет храниться 300 миллионов объектов: 100 миллионов коммитов, каждый с1 дерево и 1 капля.

Не сразу видно, куда все время идет.git add <path> требует:

  • сжатие содержимого файла и создание нового объекта BLOB-объекта или повторное использование существующего объекта BLOB-объекта, если сжатый идентификатор хеша является идентификатором существующего объекта;затем
  • обновляет индекс так, чтобы нулевой промежуточный слот соответствующего имени файла появлялся в правильной позиции.

Индекс сортируется, так что это обновление может быть очень быстрым, еслиновый файл идет в конце индекса, будет достаточно одного, однако, многобайтового добавления - или невероятно медленного: вставка впереди будет O (n 2 ) для числа записей, уже находящихся виндекс, так как все они должны будут двигаться вниз.На практике Git считывает индекс в память, выполняет там операцию и записывает индекс обратно, поэтому, вероятно, он будет очень медленным, когда индекс превысит некоторый порог размера (который будет варьироваться в зависимости от ОС и типа / скорости носителя данных)).

Вам также может понадобиться много дискового пространства между упаковываемыми объектами.Modern Git будет запускать git gc --auto после каждого коммита, но между ранним Git и 2.17.0 (когда он был исправлен), git commit случайно не сделал.Учитывая вашу ситуацию, вы, возможно, захотите отключить автоматический git gc в любом случае и запускать его через контролируемые интервалы - или, как в документации, которую вы связали, используйте git fast-import для создания файла пакета, не проходя по обычным каналам Git.Это позволит полностью избежать необходимости в индексе (пока вы не выполните от git checkout до извлечения одного из этих коммитов, т.е.).


1 единственное реальное жесткое ограничение - это только 2 160 возможных хеш-идентификаторов.Тем не менее, вы сталкиваетесь с заметно высокой вероятностью коллизий хеш-функции, порядка 1 в 10 -18 - это также является указанием коэффициента ошибок по битам, указанного изготовителями дисков, к тому времени, когда вы достигаете примерно1,7 квадриллиона объектов.

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