Курс высокие нагрузки: сеть (отрывок)
Post on 02-Jun-2015
14.861 Views
Preview:
DESCRIPTION
TRANSCRIPT
© Copyright 2014 Andrey Smirnov
Сетевой ввод-вывод
• Блокирующийся
• Неблокирующийся
• Асинхронный
© Copyright 2014 Andrey Smirnov
UNIX (POSIX)• fd - файловый дескриптор
• socket()
• listen()/accept()
• read(fd, buf)
• write(fd, buf)
• close(fd)
© Copyright 2014 Andrey Smirnov
ВнутренностиДрайвер TCP/IP
стек
ПротоколHTTP
запрос/ответ
kernel
user-space
© Copyright 2014 Andrey Smirnov
Блокирующийся ввод-вывод
• accept(fd) - заблокируется, пока не будет нового входящего соединения
• read(fd, buf) - заблокируется, пока не прибудут данные в сокет
• write(fd, buf) - заблокируется, пока не освободится место в буфере TCP
© Copyright 2014 Andrey Smirnov
Неблокирующийся ввод-вывод
• Любая операция завершается немедленно
• Вместо того, чтобы заблокироваться, вызов возвращает EAGAIN/EWOULDBLOCK
© Copyright 2014 Andrey Smirnov
Опрос готовности• Нотификации:
• level-triggered (состояние)
• edge-triggered (изменение состояния)
• Механизмы:
• select(), poll()
• epoll(), kqueue()
© Copyright 2014 Andrey Smirnov
Неблокирующий ввод-вывод
• select(fds, timeout) ⇛ ready to read/write
• do read/write until EAGAIN
© Copyright 2014 Andrey Smirnov
Ядерный сервер
• kHTTPd
• http.sys
© Copyright 2014 Andrey Smirnov
Сеть в User-space
• Snab Switch
• netmap
© Copyright 2014 Andrey Smirnov
Реактор
• Design Pattern
• “Дай мне кучу сокетов, а я сделаю callback, когда они будут готовы”
• Таймер: “Вызови меня через X мс”
© Copyright 2014 Andrey Smirnov
Что внутри
• Отсортированный по времени срабатывания список таймеров + callback
• Список файловых дескрипторов для ожидания готовности + callback
• select(fds, min(timer)) ⇛ callbacks
© Copyright 2014 Andrey Smirnov
Многозадачность• Процесс
• Нить
• Кооперативная
• Явная
• Корутины
• Комбинированные варианты
© Copyright 2014 Andrey Smirnov
Процессы
• Исторически первый тип многозадачности
• Полная изоляция*
• Видимость для планировщика ОС
• Сложность коммуникации
© Copyright 2014 Andrey Smirnov
fork()
code
r/o
data
heap
code
r/o
data
heap
© Copyright 2014 Andrey Smirnov
fork()
• Копирование файловых дескрипторов
• Копирование mmap()-областей
• …
© Copyright 2014 Andrey Smirnov
Сервер на процессах
• Родитель делает listen()
• Родитель делает fork()
• Потомки делают accept() и обслуживают соединения
© Copyright 2014 Andrey Smirnov
Примеры
• Apache: mod_prefork
• FastCGI
• PostgreSQL:
• SysV IPC: shm, sem
© Copyright 2014 Andrey Smirnov
Плюсы и минусы• Простота* реализации
• Ресурсоемкость
• Возможность использования всех ядер процессоров
• Сложность обмена информацией
• Падение одного процесса не влияет на другие
© Copyright 2014 Andrey Smirnov
Нити (ОС)• Видны планировщику
• Имеют отдельный стек и TLS
• Более легковесные, чем процесс
• Отсутствует изоляция
• Сложность написания корректных программ
© Copyright 2014 Andrey Smirnov
Синхронизация
• Любой доступ к общим данным должен быть синхронизирован
• Атомарные операции (без синхронизации)
© Copyright 2014 Andrey Smirnov
Блокировки
• acquire(x.lock)
• x.field++
• release(x.lock)
© Copyright 2014 Andrey Smirnov
Deadlock
• acquire(A)
• acquire(B)
• …
• acquire(B)
• acquire(A)
• …
Thread 1 Thread 2
© Copyright 2014 Andrey Smirnov
Deadlock
?© Copyright 2014 Andrey Smirnov
Как избежать deadlock?
© Copyright 2014 Andrey Smirnov
Механизмы синхронизации• mutex
• semaphore
• rwlock
• spinlock
• condition variable
• …
© Copyright 2014 Andrey Smirnov
GIL
• Один mutex на все состояние
• Простой и надежный вариант
• Низкая конкурентность исполнения
© Copyright 2014 Andrey Smirnov
Worker
© Copyright 2014 Andrey Smirnov
Event Loop
© Copyright 2014 Andrey Smirnov
Примеры
• MySQL
• Apache: mpm_worker
© Copyright 2014 Andrey Smirnov
Кооперативная многозадачность
• “Невидима” для ОС, один процесс (нить)
• “Поток” добровольно передает управление другому
• Явная: callbackи
• Неявная: green threads
© Copyright 2014 Andrey Smirnov
Истоки
• Эффективное использование ресурсов ВС
• Пакетный режим исполнения задач
• Многопользовательские системы
• Планировщик интерактивных систем
© Copyright 2014 Andrey Smirnov
Сегодня
• Один сервер - один вариант использования
• Сервер - не многопользовательская система
• Использование процессора минимально
• Обслуживание большого числа соединений (C10k, C100k)
© Copyright 2014 Andrey Smirnov
JavaScript
• Явная кооперативная многозадачность
• Выполнение - в один поток
• XMLHTTPRequest ⇛ callback
• Таймеры ⇛ callback
© Copyright 2014 Andrey Smirnov
Python/Twisted• Одна из первых реализаций кооперативной многозадачности с неблокирующим вводом-выводом
• Большое количество протоколов, драйверов
• Влияние на другие реализации
• Четкие и ясные примитивы
© Copyright 2014 Andrey Smirnov
Deferred
• Отложенный результат
• “Я не могу дать результат сейчас, но я его помещу в Deferred, как только он будет доступен”
• 100 строк кода*
© Copyright 2014 Andrey Smirnov
Deferred
© Copyright 2014 Andrey Smirnov
Deferred
© Copyright 2014 Andrey Smirnov
Влияние
• jQuery: Deferred
• Ruby: EventMachine
• Python 3: AsyncIO
• C#: Task/async/await
© Copyright 2014 Andrey Smirnov
Green threads
• Любая блокирующая операция приводит к переключению
• Код выглядит последовательно
• Многозадачность на основе “согласия”
© Copyright 2014 Andrey Smirnov
gevent
def print_head(url):! print('Starting %s' % url)! data = urlopen(url).read()! print('%s: %s bytes: %r' % (url, len(data), data[:50]))!!jobs = [gevent.spawn(print_head, url) for url in urls]!!gevent.wait(jobs)!
© Copyright 2014 Andrey Smirnov
Примеры• Python: gevent, eventlet, …
• Ruby (<1.9)
• Lua
• Go*
• Erlang*
© Copyright 2014 Andrey Smirnov
Комбинированные
• 1:1
• N:1
• M:N
© Copyright 2014 Andrey Smirnov
Разработка надежных высоконагруженных систем
• 24, 25 и 26-‐го мая, Москва
• h4p://smira.highload.ru/
• Мастер-‐класс с практическими заданиями
top related