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

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


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


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


Малюнок 1. Тимчасова розгортка процесу завантаження Linux

BIOS


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


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


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


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


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







 



LILO і GRUB

Первинний і вторинний завантажувачі більш відомі як 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 можна взаємодіяти, використовуючи утиліту 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.







 



Зміна процесу init

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


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


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


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







 



Простий спосіб оптимізації 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, Ви зможете зрозуміти, на що саме ваша система витрачає свій завантажувальний час, та ще ефективніше оптимізувати процес завантаження.

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*