Распараллелівать додатки для прискорення завантаження Linux

  1. Основні стадії завантаження Linux
  2. Малюнок 1. Тимчасова розгортка процесу завантаження Linux
  3. Завантаження ядра
  4. система init
  5. Лістинг 1. Витяг з файлу inittab
  6. Заміна демона init
  7. Initng
  8. Як працює initng
  9. Лістинг 2. Опис служби для initng
  10. Використання initng
  11. Upstart
  12. Як працює upstart
  13. Лістинг 3. Спрощений скрипт upstart для скрипта sysvinit rc 2
  14. Використання upstart
  15. Інші варіанти
  16. Моніторинг продуктивності init за допомогою bootchart
  17. Малюнок 2. Фрагмент діаграми завантаження, створеної bootchartd
  18. Ресурси для скачування

Робота з initng і upstart

Поширена претензія до GNU / Linux (не рахуючи відсутності коректного налагоджувача ядра) - це час, необхідний операційній системі для завантаження. Ви можете узагальнено назвати цей процес завантаженням, але насправді в розгортання системи з холодного стану до того моменту, з якого ви можете взаємодіяти з системою за допомогою оболонки або віконного менеджера, залучено кілька незалежних завдань. Давайте розглянемо завантаження Linux і процес ініціалізації.

Основні стадії завантаження Linux

Незважаючи на те, що завантаження Linux включає в себе багато ступенів, ви можете розбити процес на три основні кроки, які я називаю BIOS, завантаження ядра і ініціалізація системи (див. Малюнок 1).

Малюнок 1. Тимчасова розгортка процесу завантаження Linux
Робота з initng і upstart   Поширена претензія до GNU / Linux (не рахуючи відсутності коректного налагоджувача ядра) - це час, необхідний операційній системі для завантаження

BIOS

Коли ви включаєте або перезавантажувати комп'ютер, процесор комп'ютера починає виконувати команди з добре відомого адреси в BIOS (базова система введення / виведення, basic input / output system). BIOS зазвичай записаний на флеш-пам'ять на материнській платі. На BIOS покладено багато завдань, наприклад, початкове тестування основних компонент (таких як оперативна пам'ять) і визначення процедури завантаження операційної системи. Оскільки персональні комп'ютери можуть мати найрізноманітніші конфігурації, пристрій, з якого вантажиться система, може бути одним з багатьох пристроїв, підключених до материнської плати, таких як жорсткі диски, CD-ROM або інші пристрої, наприклад, мережевий інтерфейс.

Ви можете прискорити процес визначення завантажувального пристрою, вибираючи то пристрій, з якого ви, як правило, завантажуєтесь (зазвичай це жорсткий диск). Але то, на що BIOS витрачає найбільше часу - це тестування пам'яті. Відключення певних етапів цього тесту (наприклад, повного тестування пам'яті), безумовно, збільшить швидкість завантаження, жертвуючи тестом цілісності системи при завантаженні.

Завантаження ядра

Після того, як знайдено пристрій, з якого відбувається завантаження, Linux почне завантажувати ядра. Цей процес відбувається (приблизно) в два етапи - первинна завантаження і вторинна завантаження. Перша стадія складається з стандартного завантажувача (виявленого в головного завантажувального запису (master boot record, MBR) завантажувального пристрою), завданням якого є завантаження вторинного завантажувача операційної системи. Первинний завантажувач знаходить вторинний завантажувач, використовуючи таблицю розділів. Первинний завантажувач сканує таблицю в пошуках активного розділу; після виявлення цього розділу він завантажує вторинний завантажувач операційної системи в оперативну пам'ять і запускає його.

За допомогою вторинного завантажувача образ ядра Linux і вихідний образ RAM-диска (initrd) завантажуються в оперативну пам'ять. Після завантаження ядро ​​саморозпаковується в верхню область пам'яті і копіює initrd для подальшої установки і використання.

Первинний і вторинний завантажувачі більш відомі як LInux LOader (LILO) або GRand Unified Bootloader (GRUB), в залежності від того, що використовується у вашій системі.

Процес завантаження ядра досить складний, але недовгий, оскільки код написаний переважно на системному машинному мовою. В кінці процедури завантаження ядра запускається процес init. Так як init - це перший процес, створений в системі Linux, то він є материнським для всіх інших процесів (всі процеси є дочірніми процесами по відношенню до init).

система init

Основна увага в даній статті приділено процесу init - першому процесу, створюваному після завершення процедури завантаження ядра. Linux використовує init для запуску служб і додатків, які роблять Linux зручним у використанні.

При запуску init відкриває файл під назвою / etc / inittab. Це конфігураційний файл процесу init, в якому визначено, як форматувати систему. У файлі також міститься інформація про те, що робити в разі порушення енергопостачання (якщо система підтримує такий режим) і як реагувати, якщо станеться натискання клавіш Ctrl-Alt-Delete. Щоб зрозуміти, для чого потрібен цей файл, погляньте на його маленький шматочок, наведений в лістингу 1 .

Конфігураційний файл inittab визначає кілька елементів із загальним форматом id: runlevels: action: process. id - це послідовність символів, яка унікальним чином ідентифікує елемент. runlevels визначає рівні запуску, для яких повинно бути виконано вказане дію. action задає дію, яке потрібно виконати. І, нарешті, process визначає процес, який повинен бути запущений.

Лістинг 1. Витяг з файлу inittab

# Рівень запуску за замовчуванням id: 2: initdefault # Завантажувальний скрипт конфігурації / ініціалізації si :: sysinit: /etc/init.d/rcS # Рівні запуску l0: 0: wait: /etc/init.d/rc 0 l1: 1 : wait: /etc/init.d/rc 1 l2: 2: wait: /etc/init.d/rc 2 l3: 3: wait: /etc/init.d/rc 3 l4: 4: wait: / etc /init.d/rc 4 l5: 5: wait: /etc/init.d/rc 5 l6: 6: wait: /etc/init.d/rc 6 z6: 6: respawn: / sbin / sulogin # Як реагувати на ctrl-alt-del ca: 12345: ctrlaltdel: / sbin / shutdown -t1 -a -r now

З процесом init можна взаємодіяти, використовуючи утиліту telinit (яка пов'язана з утилітою init). Наприклад, якщо ви перебуваєте в розрахованому на багато користувачів режимі (рівень запуску 2) і хочете перейти в одного користувача режим, просто використовуйте команду telinit 1 (в режимі привілейованого користувача)

Після того як init завантажить / etc / inittab, система буде переведена на рівень запуску, який визначається дією initdefault. Як видно з лістингу 1 , Це рівень запуску 2 (runlevel 2). Розглядайте рівень запуску як стан системи. Наприклад, рівень запуску 0 визначає зупинку системи, рівень запуску 1 - це однокористувальницький режим. Рівні запуску від 2 до 5 - це багато користувачів режими, а рівень запуску 6 вказує на перезавантаження. (Зауважимо, що деякі дистрибутиви відрізняються визначенням рівнів запуску). Іншими словами, рівень запуску - це спосіб визначити, які процеси можуть бути запущені (процеси, які визначають стан системи).

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

Як показано в лістингу 1 , Initdefault задає за замовчуванням другий рівень запуску init (розрахований на багато користувачів режим). Після того як визначено початковий рівень запуску, для розгортання системи запускається сценарій rc з аргументом 2 (рівень запуску). Цей скрипт активізує різні службові та прикладні скрипти для запуску або зупинки певних елементів. В даному випадку файли знаходяться в /etc/rc2.d/. Наприклад, для запуску програми MySQL (при завантаженні системи) треба було б виконати /etc/rc2.d/S20mysql start. При виключенні системи той же самий набір сценаріїв виконувався б з аргументом stop.

Змінити процес ініціалізації досить просто. Щоб під час завантаження керувати вручну процесом ініціалізації системи, визначте новий процес, який повинен бути запущений (використовуючи LILO або GRUB). Для того щоб запустити цей процес замість init, прийнятого за замовчуванням, задайте в командному рядку завантаження ядра init = / sbin / mynewinit. Ви можете побачити це в исходнике ядра в ./linux/init/main.c. Якщо ви додали команду init в командний рядок завантаження ядра, то вона і буде використана. В іншому випадку ядро ​​спробує запустити один з чотирьох альтернативних процесів (перший з яких / sbin / init).

В кінцевому рахунку, для запуску різних необхідних служб багато скрипти виконуються послідовно (що, як правило, ви можете бачити на екрані завантаження Linux). Навіть коли служби не пов'язані один з одним, вони все одно стартують по черзі. В результаті процес може зайняти тривалий час (особливо в великий системі з великою кількістю служб).

Очевидне рішення цієї проблеми - позбутися від послідовної архітектури процесу init і замінити його чимось, що виконується паралельно. Використання такої моделі не обмежується лише багатопроцесорними системами. Одне з рішень, засноване на цій ідеї - це socket striping, або використання двох або більше сокетів для паралельної передачі даних. Також, для збільшення продуктивності введення / виведення, в системах RAID-масивів (масивів незалежних дисків з надмірністю) дані розщеплюються між дисками (зазвичай паралельно).

Заміна демона init

Найпростіший спосіб оптимізувати процес init - це відключити необов'язкові служби. Наприклад, якщо ви запускаєте звичайну машину (а не сервер), ви можете відключити такі служби як apache, sendmail і mysql, скоротивши таким чином процес init.

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

Initng

Перший варіант, initng (init наступного покоління), - це повна заміна init, яка для більш швидкого виконання процесу ініціалізації запускає процеси асинхронно. На момент написання даної статті initng був бета-продуктом, створеним Jimmy Wennlund.

Основна ідея, що лежить в основі initng, - запуск служб за умови задоволення їхніх залежностей. В результаті виходить краще співвідношення між навантаженням на CPU і систему введення / виведення. Поки один скрипт вантажиться з диска або очікує запуску апаратного забезпечення, інший скрипт може виконуватися і запустити іншу службу.

Як працює initng

Заснований на залежностях initng використовує свій власний набір ініціюючих скриптів, які визначають залежно демонів і служб. Приклад наведено в лістингу 2 . Цей скрипт описує службу, яка повинна бути запущена на даному рівні запуску. Ключ need задає для цього сервісу дві залежності - для system / initial і net / all. Ці служби повинні бути доступні перед тим, як буде запущена служба system / my_service. Якщо ці служби доступні, в гру вступає ключ exec. Ключове слово exec (з опцією start) визначає, як запустити сервіс, використовуючи будь-які доступні для цього сервісу опції. Якщо службу слід зупинити, ключове слово exec використовується з опцією stop.

Лістинг 2. Опис служби для initng

service system / my_service {need = system / initial net / all; exec start = / sbin / my_service --start --option; exec stop = / sbin / my_service --stop --option; }

Як показано в лістингу 2, шляхом завдання служб ви можете побудувати цілу систему. Служби, які не мають залежностей, можуть бути запущені відразу ж (і паралельно), тоді як служби, для яких залежності визначені, повинні запускатися акуратно. Ви можете уявити initng як цільову систему. Цілями є запуск служб. Явного планування подій тут не існує; навпаки, залежно просто визначають послідовність ініціалізації служб, з розпаралелюванням, закладеним в процесі.

Використання initng

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

Для стандартної установки потрібно дистрибутиви initng (вихідний або бінарний) і ifiles. Ви можете зібрати дистрибутив initng за допомогою ./configure, make і make install. За допомогою cmake ви повинні зібрати ifiles (які є скриптами). Залежно від ваших системних вимог, може знадобитися створити нові визначення служб / демонів (хоча, швидше за все, хтось із шанувальників initng це вже зробив). Потім, для того щоб вказати на новий / sbin / initng, вам слід змінити конфігурацію LILO або GRUB.

Для управління initng використовуйте ngc (за аналогією c telinit для традиційного init). Синтаксис подекуди відрізняється, але можливості залишилися ті ж самі.

Upstart

Ще один варіант заміни init, upstart, використовує підхід, трохи відмінний від того, з яким ви тільки що познайомилися, освоюючи initng. Upstart - це орієнтована на події заміна init, тобто запуск і зупинка служб заснована на обробці подій. Upstart був розроблений для дистрибутива Ubuntu Скотом Джеймсом ремнантов (Scott James Remnan), але годиться в якості повної заміни init в будь-якому дистрибутиві Linux.

Як працює upstart

Upstart вимагає заміни ініціюючих скриптів для підтримки подієво-орієнтованого режиму дій. Upstart підтримує свій власний процес init, який запускається при старті системи (як і при всіх інших методах). Спочатку init генерує подію startup (запуск) - одне з двох основних подій. Подія startup генерується процесом init при старті системи, а подія shutdown - при виключенні системи. Інші ключові події - це ctrlaltdel, яке вказує, на те, що ви натиснули клавіші Ctrl-Alt-Delete, і kbdrequest, яке генерується, якщо ви натиснули комбінацію Alt-Up (клавіші зі стрілкою вгору).

Для інших цілей ви можете створювати нові події. Наприклад, ви можете створити довільне подія під назвою myevent і сигналізувати про його отриманні за допомогою команди echo. Ось коротенький приклад виконуваної дії:

on myevent exec echo myevent received console output

У цьому лістингу певна задача очікує отримання події myevent. Потім буде виконано задану дію (виведений текст на консоль). При наявності даного файлу в складі upstart (/etc/event.d) ви можете його запустити, використовуючи утиліту initctl:

initctl emit myevent

Скрипти upstart працюють так само, як і звичайні rc init файли, за винятком того, що вони діють самостійно, грунтуючись на асинхронних події. В лістингу 3 наведено простий приклад скрипта, який приймає три події: startup - для запуску завдання, а shutdown і runlevel-3 - для зупинки виконання завдання. Оболонка виконує завдання, описану в script (використовуючи опцію -e для переривання виконання скрипта в разі помилки).

Лістинг 3. Спрощений скрипт upstart для скрипта sysvinit rc 2

start on startup stop on shutdown stop on runlevel-3 script set $ (runlevel --set 2 || true) exec /etc/init.d/rc 2 end script

Утиліта initctl пропонує такий же набір функціональних можливостей, що і telinit, але з деякими додатковими особливостями, притаманними upstart. Як ви бачили вище, для генерації події для upstart, ви можете використовувати initctl з опцією emit. Опція list дозволить вам бути в курсі дій системи, розпізнаючи стан завдань. Ви побачите, які операції в даний момент знаходяться в режимі очікування, а які активні. Утиліта initctl може так само відображати налагоджувальні події.

Upstart - це цікава альтернатива init, що володіє деякими явними перевагами. Відпадає реальна необхідність в рівнях запуску, оскільки завантаження системи буде визначатися доступним апаратним забезпеченням. Іншими словами: немає пристрою - не запуститься і процес, що вимагає його. Upstart так само може управляти пристроями "гарячої заміни". Наприклад, якщо ви підключили мережеву карту PCMCI через деякий час після завантаження системи, то буде генеруватися подія network-interface-added. Ця подія запустить процес конфігурації інтерфейсу, використовуючи протокол DHCP (Dynamic Host Configuration Protocol), генеруючи подія network-interface-up. Коли в новий інтерфейс буде доданий маршрут за замовчуванням, то результатом буде подія default-route-up. З цього моменту завдання, що вимагають використання мережевого інтерфейсу (такі як поштовий сервер або Web-сервер), будуть запускатися автоматично (і зупинятися в разі зникнення інтерфейсу).

Використання upstart

Збірка і інсталяція upstart не уявляють складності і проходять за стандартним шаблоном: configure, make і make install. Upstart надає набір демонстраційних завдань, сумісних зі звичайними рівнями запуску init. Подібно initng, нові додатки повинні мати свої власні завдання, що враховують їх вимоги (з можливістю додавання нових подій). У будь-якому випадку розгортання нової системи init може бути ризикованим. Але переваги, що надаються upstart, безумовно переважують ці ризики і додаткові зусилля, які можуть знадобитися.

Як показано вище, утиліта initctl має ті ж можливості, що і telinit. Однак initctl також надає додаткові можливості для трасування і налагодження.

Інші варіанти

Розглянуті в цій статті initng і upstart - це далеко не єдині варіанти. init так само може бути замінено, наприклад, на runit, pardus, minit і einit. Всі вони підтримуються і розвиваються Linux-спільнотою. На даний момент upstart - можливо кращий з варіантів, оскільки адаптований для заміни init в популярному дистрибутиві Ubuntu. Додаткову інформацію ви можете знайти в розділі ресурси .

Моніторинг продуктивності init за допомогою bootchart

Після того як ви змінили процес завантаження системи, корисно зрозуміти, що саме змінилося і як це відбивається на повному часу завантаження. Зіга Макіївці (Ziga Mahkovec) створив дуже корисний інструмент під назвою bootchart, призначений для візуалізації процесу завантаження. Він складається з декількох елементів, включаючи утиліту реєстрації даних і утиліту візуалізації.

Утіліта реєстрації Даних (bootchartd) запускається вместо процесса init (як правило, це задається в файлах grub або lilo.conf). После ініціалізації bootchartd Повертає управління процесса init (зазвічай / sbin / init). Bootchartd - це, по суті, програма для збору інформації, яка просто періодично сканує оточення (за замовчуванням раз в 200 мс). Під скануванням оточення я маю на увазі, що вона зчитує поточну статистику CPU, час введення / виведення і простою, а також інформацію про використання диска і про кожного активному процесі (використовуючи файлову систему proc). Ці дані зберігаються в тимчасовому файлі (var / log / bootchart.tgz) для подальшої обробки.

Після цього bootchart використовує інструмент подальшої обробки для перетворення вихідних даних в діаграму завантаження. Цей процес може виконуватися локально, за допомогою Java ™ додатки (частина дистрибутива bootchart), однак більш простий спосіб - використовувати Web-форму, що знаходиться на домашній сторінці bootchart. Як приклад на рисунку 2 приведена частина діаграми завантаження. Зауважимо, що ці діаграми, як правило, досить великі (в залежності від служб, що запускаються і додатків). Посилання на повний приклад шукайте в розділі ресурси .

Малюнок 2. Фрагмент діаграми завантаження, створеної bootchartd

резюме

Відповідно до загальної концепції Linux, існує безліч рішень і великі можливості для вибору при оптимізації часу завантаження. Варіантів маса: від рішень, заснованих на залежностях, подібних initng, до подієво-орієнтованих рішень, подібних upstart, і серед них існує ваш варіант оптимізації, який підійде саме для ваших потреб. Використовуючи пакет bootchart, ви зможете зрозуміти, на що саме ваша система витрачає свій завантажувальний час, і ще ефективніше оптимізувати процес завантаження.

Ресурси для скачування

Схожі тими

  • Оригінал цього навчального посібника на developerWorks.
  • Для огляду системного адміністрування на різних дистрибутивах Linux зверніть увагу на ресурс developerWorks на differentiating UNIX and Linux .
  • Кілька застарілий ресурс Red Hat досліджує різні рівні запуску для Linux.
  • Наступне покоління системи init (Initng) - заснований на залежностях варіант заміни системи init.
  • система upstart для Ubuntu - подієво-орієнтований варіант заміни системи init.
  • Bootchart - інструмент для аналізу ефективності та візуалізації процесу завантаження. Збирає дані про продуктивність під час процесу ініціалізації системи і потім обробляє їх розгорткою за часом.
  • пакет einit - ще один варіант скрипта ініціалізації, що використовує Extensible Markup Language (XML) для конфігураційних файлів.
  • Ще одна цікава схема для розпаралелювання init - це Pardus . Цей метод не тільки позбавляється від послідовної структури завантаження Linux, але також додає гнучкості, використовуючи мову Python.
  • пакет runit замінює схему init супервизором служб.
  • Пакет minit - маленька, але повна версія системи init. Ви так само можете досліджувати ресурс sysvinit. пакет minit - маленька, але повна версія системи init. Ви так само можете досліджувати ресурс sysvinit .
  • Додаткову інформацію для розробників Linux можна знайти в розділі Linux на developerWorks .
  • Використовуйте тестове програмне забезпечення IBM, IBM trial software , Доступне на developerWorks, і створіть свій наступний проект розробки в Linux.

Підпишіть мене на повідомлення до коментарів