Розподілене зберігання даних з допомогою git-annex

Матеріал з Вікіпідручника

Зауважте, ця книжка ще перебуває на дуже ранній стадії розвитку, і навіть може містити помилкові поради... Тому перевіряйте ці поради за офіційною документацією git-annex, і не забувайте поліпшувати цю книжку, якщо знайдете хиби чи просто вважатимете за доречне доповнити її.

Уявімо, що у вас є переносний комп'ютер з невеликим вінчестером. Також у вас є стаціонарний комп'ютер, на який і з якого ви можете пересувати через мережу файли. Ви працюєте, і в певний момент вам бракне місця на переносному комп'ютері — й ви пересуваєте частину файлів на стаціонарний. А ще частину — на зовнішній вінчестер. І ви опиняєтесь в становищі, коли ваші дані розпорошені між трьома різними пристроями.

Чи не чудово було б, якби в кожен такий момент ви могли продовжувати бачити перелік усіх ваших файлів, а також мали можливість легко отримати будь-який з них, не шукаючи перед тим півдня, на якому пристрої ви його розмістили? І якщо вам треба «розчистити» місце для отримання інших файлів, бути певними, що ви не вилучите файли, яких більше ніде немає? І ще: якщо ви змінюєте, переміщуєте чи перейменовуєте файли на одному з ваших пристроїв, щоб ці самі зміни автоматично відтворювались і на решті ваших пристроїв, на які ви скопіювали цю частину своїх файлів? Ви, мабуть, довго мріяли про таку можливість, чи не так?

Ваша мрія ось-ось здійсниться — варто вам лише спробувати git-annex (це, до речі, вільна й безкоштовна програма). Як нею користуватись? Через командний рядок, звичайно! А, забув сказати — вам потрібна для цього вільна unix’оподібна операційна система, або хоча б MacOS X. Запевняю — воно того варте (взагалі, якщо ви почнете використовувати якусь із unix’оподібних систем, вам відкриється багато дивовижних інструментів).

Можливості git-annex[ред.]

У вас є дерево тек, яке ми умовно назвемо «скринею». Також у вас є інші такі скрині, які пов'язані із цією (назвемо їх «клонами»), і відтворюють ту саму структуру тек. Кожна з таких скринь може містити увесь або частину вмісту файлів, які є в інших скринях. Git annex дає можливість:

  • відслідковувати фізичне розміщення вмісту файлів між скринями;
  • автоматично визначати, з якої скрині слід отримати вміст файлів, якщо їх немає в поточній;
  • пересувати вміст файлів між скринями;
  • слідкувати за тим, щоб вміст кожного з файлів був завжди наявний хоча б в одній зі скринь;
  • якщо в одній скрині файли редагуються, перейменовуються, переміщуються чи вилучаються (операція остаточного вилучення), git annex для вас відтворить всі ці дії і в інших скринях-клонах під час синхронізації скринь. Тобто дерево тек завжди узгоджене.

Таким чином git annex суттєво спрощує роботу із великими колекціями даних, які можуть бути розподілені по різних пристроях.

Початок роботи[ред.]

Отож, спробуймо. Спершу, нам треба заінсталювати git-annex. Для цього скористаймось інструментами, які надає система. Наприклад, у Debian Gnu/Linux треба запустити команду apt-get install git-annex (звичайно, від імені адміністратора). Також ви можете заінсталювати git-annex, скориставшись пакунком на сайті програми, але завжди ліпше інсталювати програму через «рідний» менеджер пакунків системи, якщо він містить інформацію про git-annex.


Коли програма заінсталювалася, нам треба вирішити, яку теку ми хочемо перетворити на таку магічну скриню. Візьмемо, до прикладу, ~/music/: уявімо, що ви музикант і вам потрібно зберігати великі об'єми некомпресованого звуку для проектів, над якими ви працюєте.

Відкриваємо термінал, заходимо в цю теку й запрошуємо до неї git-annex:

 cd ~/music/                                  # застрибнули в теку
 git init                                     # ініціaлізували git
 git annex init "Музичні проекти (notebook)"  # ініціaлізували git-annex

Git annex складається з двох частин. Перша, git, є інструментом для відстежування версій файлів та для узгодження роботи кількох людей над одними файлами. Це дивовижний інструмент. Git annex є надбудовою до нього, яка дає можливість зберігати файли в різних місцях.

Отже, після того, як ми зайшли в нашу теку, ми спершу запросили до неї git (командою git init), а тоді програму git-annex (командою git annex init), якій подали ще й опис теки, щоб можна було відрізнити зберігання «Музичних проєктів» на переносному компуторі від «Музичних проєктів» на стаціонарному.

Тепер нам треба імпортувати усі файли в цій теці до «скрині» git-annex:

 git annex add .

В командному рядку крапка ( . ) означає «ця тека». Отже, ми імпортуємо увесь вміст теки до git annex. Гаразд. Імпортувалось? (Якщо файлів багато, і вони великі, воно трохи «подумає»).

Тепер треба зробити дуже важливу річ: записати наші зміни з якимось коментарем, наприклад «Імпортували всі файли»:

 git commit -m "Імпортували всі файли"

(Прапорець -m означає «message», повідомлення). Все. Наша початкова версія магічної скрині записана. Далі, коли ви робитимете якісь зміни в структурі вашої скрині, додаватимете чи вилучатимете з неї файли, вам треба буде або вручну, як зробили щойно (що охайніше), або автоматично записувати ці зміни як певні етапи вашої роботи. Тільки так git annex зможе знати, наскільки дані на пристрої A відстали від даних на пристрої B, і як не переписати вашу роботу старішою версією файлу. Це дуже важливо.

«Клонування» вашої скрині[ред.]

Гаразд. Тепер переходимо до найцікавішого.

Спробуймо організувати скриню-клон на зовнішньому вінчестері. Вона може містити всі або частину файлів з нашої основної скрині. Тут треба зауважити, що git-annex потребує для роботи підтримку символьних посилань (symbolic link), яка реалізована на всіх unix'оподібних системах, але якої не було у старих версіях Windows. Через те потрібно, щоб на зовнішньому вінчестері був розділ, сформатований не у файлову систему FAT32, а в одну з тих, які підтримують символьні посилання. Для Gnu/Linux оптимальним варіантом може бути ext3 чи ext4, але якщо ви плануєте використовувати цей розділ і в інших системах, то для сумісності ви можете скористатись файловою системою UDF. Файлова система NTFS теж підтримує символьні посилання, але можливість її використання із git-annex ми не перевіряли (реалізація символьних посилань в NTFS має деякі особливості).

Отож, коли ми впевнились, що маємо на зовнішньому вінчестері розділ з правильною файловою системою, можемо створити там нашу скриню-клон. Уявімо, що тека з нашими музичними проектами буде називатись music на зовнішньому вінчестері.

 cd /media/usb               # Наш зовнішній вінчестер
 git clone ~/music           # Дублюється ієрархія та відомощі про файли
 git annex init "Музичні проекти (зовнішній hdd)"

Що ми щойно зробили? Ми створили клон нашої теки з музичними проетами на зовнішньому вінчестері. Але! Клон цей не містить самих файлів — тільки інформацію про них. Це дає можливість завше мати інформацію про структуру всієї «скрині» в будь-якому з її часткових клонів, але зберігати тільки ті файли, які в цей момент часу потрібні.

Є ще одна важлива річ: треба сказати нашій початковій скрині, що створено її клон, за яким вона повинна слідкувати:

 cd ~/music/
 git add remote usbhdd /media/usb/music/
 #              usbhdd — довільна назва-ключ, яку ви собі придумуєте для звертання до клона

Тепер ми можемо вибирати, які власне файли ми хочемо зберігати на зовнішньому вінчестері. Якщо всі — дуже просто:

 cd /media/usb/music/
 git annex get .

Якщо не всі, теж дуже просто:

 cd /media/usb/music/
 git annex get Тека1 Тека2 Тека3...

В цей момент git annex завантажує власне сам зміст файлів із тих місць, де, за його версією, ці файли можна знайти. В цьому випадку із нашого компутора.

Робота з файлами[ред.]

Git annex може запропонувати вам два основні способи роботи з файлами в його «скрині».

«Непряма» скриня[ред.]

Непрямий (indirect) спосіб вмикається автоматично при створенні «скрині». Він означає, що сам зміст файлів зберігається в під-теці скрині .git/annex/, а те, що ви бачите — символьні лінки (symbolic link) на зміст файлів. Цей спосіб роботи є безпечнішим, бо коли ви змінюєте зміст файлів, git annex деякий час зберігає кілька попередніх версій файлів у своїй теці, і ви може їх, при потребі, відновити.

В непрямій скрині перед редагуванням файлу чи теки вам треба їх «відімкнути»:

 git annex unlock Файл-чи-тека1 Файл-чи-тека2 Файл-чи-тека3...

В цей момент git annex дає вам копію файлу, яку ви можете спокійно редагувати, а оригінал він зберігає в своїй теці. Ви працюєте над файлами, а тоді запускаєте

 git annex add Файл-чи-тека1 Файл-чи-тека2 Файл-чи-тека3...     # Вибираємо файли для запису змін (нові й редаговані)
 git commit -m "Додано нову партію"                             # Запис змін в історію скрині

Бачите? Ви ведете облік того, що ви робите, а git annex відслідковує, що́ й де розміщено, і в якій версії. Так нічого не загубиться. Ви також можете розділити різні редагування на окремі записи — тобто виконати команди «git annex add» та «git commit» окремо для різних файлів, якщо ваші редагування стосувались різних речей.

«Пряма» скриня[ред.]

Якщо ж у вас обмаль місця, а ваша програма й так зберігає попередні версії вашої роботи як окремі файли, зберігання додаткових резервних копій ваших файлів може бути вам зайвим.

При прямому способі роботи історія файлу не зберігається (якщо ви спеціально цього не увімкнете), і ви працюєте безпосередньо над оригінальними файлами. Git annex записує тільки зміни в структурі вашої скрині та відслідковує розміщення файлів між скринями.

Для цього вам треба перемкнути скриню на прямий режим:

 git annex direct

Решту дій ви виконуєте так само, як з непрямою скринею, тільки вам уже не треба запускати команду «git annex unlock» — всі файли в прямій скрині є «відімкнутими» (тобто ви редагуєте безпосередньо оригінали файлів).

Переміщення та вилучення файлів[ред.]

Git-annex дає можливість синхронізувати не тільки створення чи зміну, а й переміщення чи вилучення файлів між вашими «скринями». Тобто якщо ми переміщуємо якийсь файл на переносному компуторі, то він переміститься і на зовнішньому вінчестері, коли ви наступного разу синхронізуєте.

Але щоб це працювало, git-annex повинен знати, що файл перемістився, а не створився новий, який подібний до початкового. Є кілька способів це забезпечити. Найбільш охайний такий:

 git mv Стара-назва Нова-назва                  # Перейменування
 git mv Стара-тека/Файл1 Нова-тека/Файл1        # Переміщення
 git rm Файл-який-більше-не-потрібен-узагалі    # Вилучення (зі всіх скринь)

Майте на увазі: команда git rm вилучає файл зі всіх скринь (тобто змінює структуру скрині); вона використовується вона лише тоді, коли файл більше узагалі не потрібний. Натомість, якщо вам потрібно лише тимчасово вилучити файл із поточної скрині (і при тому мати можливість у майбутньому «відновити» його із якоїсь із ваших скринь), ви повинні скористатись командою git annex drop замість git rm (детальніше про це читайте в розділі Пересування файлів між скринями).

Після операцій з файлами зафіксуємо їх в історії змін:

 git commit -m "Трохи впорядкував файли"

Цей спосіб забезпечує впорядковану історію дій і сприяє систематизації вашої роботи. Тому радимо дотримуватись саме такого способу переміщення й вилучення файлів.

Альтернатива: git annex watch[ред.]

Але є й інший спосіб, можливо й зручніший, але менш охайний. Він передбачає вмикання «демона» git annex, який слідкуватиме за операціями над файлами, які ви виконуєте, і автоматично їх записуватиме:

 git annex watch

Ви робите із файлами все, що вам заманеться, а git annex подбає про те, щоб «помітити» й записати зміни в історію «скрині». Після того, як ви зробили все, що хотіли, можете вимкнути «демон» git annex:

 git annex watch --stop

«Неохайність» полягає тут у тому, що кожна, навіть найдрібніша операція із файлом записується як окрема дія, та ще й без коментаря (адже тільки людина може давати абстрактні назви діям, які вона робить). При перегляді історії змін вашої «скрині» вам буде дуже важко зорієнтуватись, бо там не буде ніякого порядку. Тому ми все-таки радимо використовувати «git commit» для записування ваших змін із коментарем. «git watch» існує для тих випадків, коли впорядкована історія дій вам неважлива.

Вилучення застарілих даних[ред.]

Під час різноманітних операцій з файлами поступово накопичуються дані про попередні версії редагованих файлів, чи вміст файлів, які було вилучено зі скрині (здебільшого це відбувається в непрямій скрині). Якщо такі дані вам більше не потрібні, ви можете скористатись командою git annex unused, щоб побачити перелік даних, на які більше не посилається жоден файл (тобто файли оновились, і їхній вміст записано в інших блоках даних):

 git annex unused
 unused . (checking for unused data...) (checking master...) (checking serenus/master...) (checking serenus/synced/master...) 
   Some annexed data is no longer used by any files:
     NUMBER  KEY
     1       SHA256E-s6148--bbd26b31949081573deab9d08b9a021da4a1c4bdf66c150c053b5b09d42f6236
     2       SHA256E-s6148--d65165279105ca6773180500688df4bdc69a2c7b771752f0a46ef120b7fd8ec3
     3       SHA256E-s6148--8ec1e2dfde5b4cd11a086867d0f7dcf6e2a012fc29309af64ee0a8ba22c13770
   (To see where data was previously used, try: git log --stat -S'KEY')
 
   To remove unwanted data: git-annex dropunused NUMBER
 
 ok

Як підказує програма, щоб вилучити такі дані, ви можете скористатись командою

git annex dropunused 1       # Щоб вилучити один об'єкт
git anenx dropunused [1-100] # Щоб вилучати багато об'єктів одразу

Пересування файлів між скринями[ред.]

Після того, як ви зробили якийсь обсяг роботи та записали її в git annex, ви може пересувати її між вашими «скринями».

Спробуймо завантажити щойно зроблену роботу на ваш зовнішній вінчестер. Під'єднаймо його, а тоді:

 cd /media/usb/music/     # Перестрибнули в теку на зовнішньому вінчестері
 git annex sync origin    # Узгодили структуру з основною скринею
                          # (origin — скриня, від якої утворено клон)

При тому програма не копіює нікуди сам зміст файлів, тільки інформацію про зміни в структурі скрині та про оновлення файлів.

Отож, час навчитись переносити власне файли між скринями. Крім способу з git annex get, який ми описали в розділі «Розмноження вашої скрині» є ще інші зручні команди для перенесення змісту. Ось ця команда копіює зміст вашої скрині в іншу скриню:

 git annex copy Файл-чи-тека1 Файл-чи-тека2 Файл-чи-тека3... --to=usbhdd
 #         usbhdd — це та назва-ключ, за яким ви приєднали скриню-клон

Або перенести в іншу скриню, звільнивши місце на основній:

 git annex move Файл-чи-тека1 Файл-чи-тека2 Файл-чи-тека3... --to=usbhdd

Щоб отримати файл чи теку, які є в будь-якій з інших скринь (git annex знає, в якій), вистачить запустити

 git annex get Файл-чи-тека1 Файл-чи-тека2 Файл-чи-тека3

Програма сама попросить вставити той носій, який містить потрібні вам файли, і скопіює звідти дані. Таким чином ви не мусите тримати в голові інформацію про те, на якому носії збережена та чи інша частина вашої скрині.

І останнє, найголовніше.

Якщо ви бажаєте звільнити місце, вилучивши якийсь файл зі скрині в безпечний спосіб (тобто тільки якщо він збережений ще десь), запустіть команду

 git annex drop Файл-чи-тека1 Файл-чи-тека2 Файл-чи-тека3

Програма перевірить, чи ці файли є хоча б в одній скрині крім цієї, і якщо небезпеки втратити файл немає, вилучить його із цієї скрині.

Приємної роботи з git-annex!

Посилання[ред.]