SlideShare a Scribd company logo
1 of 65
Download to read offline
Разработка
        высокопроизводительных
       серверных приложений для
               Linux/UNIX
           Крижановский Александр
              ak@natsys-lab.com


10/21/12
Пример (front-end server)




10/21/12
Декомпозиция
●   Функциональная декомпозиция
●   Декомпозиция по данным




10/21/12
Декомпозиция по данным
                               Original:
                       for (int i = 0; i < 10; ++i)
                               foo(i);
           Thread 1:                                  Thread 2:
 for (int i = 0; i < 5; ++i)                 for (int i = 5; i < 10; ++i)
           foo(i);                                    foo(i);
●   Пример: рабочие потоки, “разгребающие” очередь задач
●   Хорошо масштабируется с ростом CPU.




10/21/12
Функциональная декомпозиция
                              Original:
                               foo();
                               bar();
           Thread 1:                               Thread 2:
            boo();                                  bar();


●   Пример: поток ввода, поток вывода, рабочий поток, поток
    реконфигурации и пр.
●   Не масштабируется.




10/21/12
Процессы vs Потоки
●   Один и тот же task_struct, один и тот же do_fork()
●   Потоки разделяют память, а процессы – нет.


PostgreSQL: процессы, shared memory для buffer pool, блокировки тоже в
shared memory




10/21/12
Потоки – много или мало?
●   Современные планировщики ОС обрабатывают N kernel-thread'ов за
    O(1) или O(log(N)) время
●   Kernel-thread ~ process: тяжелое создание и ~6 страниц памяти =>
    нужен пул тредов
●   M потоков на один CPU => ухудшается cache hit
    (поток должен завершить текущую задачу и только потом перейти к
    следующей)
●   Если нужен высокий параллелизм, то нужны coroutines; или events...




10/21/12
Hyper Threading
           и когда много потоков хорошо
●   Потоки делят один кэш
●   Если cache hit rate <50%, то всегда выгоднее 2 и более потока на ядро
●   Если у одного потока высокий hit rate, то добавление дополнительных
    потоков на ядро ухудшит производительность
●   На одно ядро желательно не планировать потоки, исполняющие
    разный код с разными данными




10/21/12
Синхронизация
●   pthread_mutex_lock() - только один поток владеет ресурсом
●   pthread_rwlock_wrlock()/pthread_rwlock_rdlock() - один писатель или
    много читателей
●   pthread_cond_wait() - ожидать наступления события
●   pthread_spin_lock() - проверяет блокировку в цикле
●   (первые 3 работают через futex(2))




10/21/12
Pthreads & futex(2)
       static volatile int val = 0;
       void lock() {
              int c;
              while ((c = __sync_fetch_and_add(&val, 1))
                         lll_futex_wait(&val, c + 1);
       }
       void unlock() {
              val = 0;
              lll_futex_wake(&val, 1);
       }



10/21/12
pthread_cond_broadcast:
                  гремящее стадо
●   Атомарные операции и, тем более, системный вызов – дорогие
    операции
●   Поэтому лучше использовать pthread_cond_signal()




10/21/12
Инвалидация кэшей на мьютексе
●   Если поток не может захватить мьютекс, то он уходит в сон
●   => на текущем процессоре будет запущен другой поток
●   => этот поток “вымоет кэш”
●   Когда мьютекс будет отпущен, то поток продолжит выполнение с
    “вымытым” кэшем или на другом процессоре




10/21/12
pthread_spin_lock (упрощенно)
       static volatile int lock = 0;


       void lock() {
              while (!__sync_bool_compare_and_swap(&lock, 0, 1));
       }


       void unlock() {
              lock = 0;
       }




10/21/12
pthread_spin_lock (scheduled)
               CPU0                                CPU1
             Thread0: lock()                   . . .
             Thread0: some work               Thread1: try lock() → loop
             . . .                            Thread2: try lock() → loop
             // Thread0 preempted             . . . (loop) . . .
             Thread1: try lock() → loop       Thread2: try lock() → loop
                               // 200% CPU usage
             . . .                            // Thread2 preempted
             . . .                            Thread0: unlock()
Ядро для этого использует preempt_disable()



10/21/12
pthread_rwlock
●   “дороже” pthread_mutex (больше сама структура данных ~ в 1.5 раза,
    сложнее операция взятия лока)
●   Снижает lock contention при превалировании числа читателей над
    писателями, но снижается производительность per-cpu




10/21/12
Lock contention
●   Один процесс удерживает лок, другие процессы ждут —
    система становится однопроцессной
●   Актуален с увеличением числа вычислительных ядер (или
    потоков исполнения) и числом блокировок в программе
●   Признак: ресурсы сервера используются слабо (CPU, IO
    etc), но число RPS невысокий
●   Методы борьбы: увеличение гранулярности блокировок,
    использование более легких методов синхронизации



10/21/12
Lock upgrade
       pthread_rwlock_rdlock(&lock);
       if (v > shared) { pthread_rwlock_unlock(&lock); return; }
       pthread_rwlock_unlock(&lock);
       pthread_rwlock_wrlock(&lock);
       if (v > shared) { pthread_rwlock_unlock(&lock); return; }
       shared = v;
       pthread_rwlock_unlock(&lock);




10/21/12
Иерархия кэшей




10/21/12
Типы кэшей
●   Data cache (L1d, L2d)
●   Instruction cache (L1i, L2i)
●   TLB – значения преобразований виртуальных адресов страниц в
    физические (L1, L2)
●   L3 часто бывает смешанного типа




10/21/12
getconf
       # getconf LEVEL1_DCACHE_SIZE
       65536
       # getconf LEVEL1_DCACHE_LINESIZE
       64
       # grep -c processor /proc/cpuinfo
       2




10/21/12
Когерентность кэшей
●   Непротиворечивость кэшированных данных на многопроцессорных
    системах
●   Обеспечивается протоколом MESI (Modified, Exclusive, Shared, Invalid)
●   RFO (Request For Ownership) := M → I
       –   CPU1 пишет по адресу X: X → M
       –   CPU2 пишет по адресу X:
              – CPU1: X → I
              – CPU2: X → M




10/21/12
Пример: std::shared_ptr
●   std::shared_ptr использует reference counter – целую переменную,
    разделяемую и модифицируемую всеми потоками




10/21/12
False sharing
●   MESI оперирует cacheline'ами
●   RFO довольно дорогая операция
●   Если две различные переменные находятся в одном cacheline, то
    возникает RFO




10/21/12
Выравнивание
●   Компилятор автоматически выравнивает элементы структур данных
●   GCC имеет специальные атрибуты, управляющие выравниванием
    данных




10/21/12
Кэш
1. Структура для хранения и быстрого поиска данных по некоторому
  ключу
   ●   общая структура для хранения и поиска (дерево или хэш)
   ●   две структуры: для индекса и для алгоритма вытеснения (обычно
       связный список)
2. Алгоритм вытеснения данных
3. Flush-потоки или вытеснение при записи




10/21/12
Примеры хранилищ
●   Состояния HTTP или IM сессий
●   Данные о пользователях по ID или логинам
●   Буфферный кэш СУБД




10/21/12
Цена доступа
●   Основное узкое место: время обращения к памяти
●   По мере роста структур, данные перестают помещаться в кэши (L1d,
    L2d, L3d, TLB L1d/L2d etc)
●   Выход их TLB (~1024 страницы) может стоить до 4х обращений к
    памяти вместо одного
=> Основные критерии к структурам данных:
●   малый объем вспомогательных данных
●   пространственная локальность обращений




10/21/12
Page Table




10/21/12
Структуры данных & page table

                             Application Tree



    Page table
                       a.1       a    b


                 a.0         c




                 c.0

                       c.1




10/21/12
Radix-tree
●   Гарантированность времени доступа
●   На практике использует больше всего памяти
Очень медленное: на тесте равномерного распределения IPv4 адресов
почти в 2 раза проигрывает хэшу с простой хэш-функцией времени и 4
раза по памяти
(Linux VMM выбирает ключи для сохранения пространственной
локальности)




10/21/12
{B,T}-tree
●   Хорошая пространственная локальность
●   Как правило, время поиска можно считать
    константным для RAM-only структур данных
●   Довольно дорогие вставки
●   На практике все равно медленнее хэшей




10/21/12
Бинарные деревья
●   В целом, слишком много обращений к памяти
●   Балнсировка может быть довольно дорогой




10/21/12
Хэш
●   Как правило, обладает лучшим средним временем доступа
●   На практике использует меньше всего памяти
●   Хорошая пространственная локальность: 1 случайное обращение и
    линейное сканирование
●   Тяжело выбрать достаточно хорошую хэш-функцию (зависит от
    ключей и нагрузки)
●   В некоторых случаях может обладать очень большим временем
    поиска




10/21/12
Хэш: оптимизация (1)
●   Двойное хэширование
●   Определение размера на старте, как процент от доступной памяти
    (без динамического рехэшинга)
●   Просто повысить гранулярность блокировок




10/21/12
Хэш: гранулярность блокировок




10/21/12
Алгоритмы вытеснения
●   LRU (Least Recently Used): наиболее простой (O(1)), fundamental
    locality
●   Clok: алгоритм «второй попытки» без перемещений элементов в
    списке (лучше concurrency)
●   LRFU: модификация LFU (Least Frequently Used), но работает за
    линейное время, cлишком долго “помнит” историю
●   CAR (Clock with Adaptive Replacement)/CART (CAR with Temporal
    filtering): объединяет fundamental и advanced locality, устойчив к
    линейному сканированию




10/21/12
Хэш: простое вытеснение




10/21/12
Способ вытеснения
1. Flushing-thread:
   ●   максимальная скорость записи и чтения
   ●   пробуждается по таймеру или при нехватке памяти
2. Во время чтения или записи:
   ●   чтение/запись медленее
   ●   подходит для soft-realtime
   ●   проще алгоритм




10/21/12
Lock-free структуры данных
●   Обычно простые структуры данных (односвязные списки,
    переменные)
●   Сущестуют сложные протоколы изменения деревьев и хэшей –
    достаточно дорогие из-за своей сложности
●   Наиболее актуальны в условиях высокого lock contention на
    многопроцессорных системах
●   Очень полезны в «горячих» структурах: очереди задач, аллокаторы и
    пр.




10/21/12
Очердь задач
●   Обычно 1 производитель, N потребителей
●   Реализует только операции push() и pop() (нет сканирований по
    списку)
●   Классический (наивный) вариант: std::queue, защищенный mutex'ом
●   Может быть реализована на атомарных операциях для снижения lock
    contention




10/21/12
Атомарные операции
                 (Read-Modify-Write)

       unsigned long a, b = 1;
       b = __sync_fetch_and_add(&a, 1);


       mov    $0x1,%edx
       lock xadd %rdx,(%rax)




10/21/12
Атомарные операции
                (Compare-And-Swap)

       unsigned long val = 5;
       __sync_val_compare_and_swap(&val, 5, 2);


       mov    $0x5,%eax
       mov    $0x2,%ecx
       lock cmpxchg %rcx,(%rdx)




10/21/12
Атомарные операции
                     (стоимость)
●   Реализуются через протокол cache coherency (MESI)
●   Писать в одну область памяти на разных процессорах дорого, т.к.
    процессоры должны обмениваться сообщениями RFO


Используются в shared_ptr для reference counting




10/21/12
Lock-free очередь (список):
                      push()

push (q: pointer to fifo, cl: pointer to cell):
       Loop:
               cl->next = q->tail
               if CAS (&q->tail, cl->next, cl):
                       break




10/21/12
Lock-free очередь (список):
                      pop()

pop (q: pointer to fifo):
       Loop:
               cl = q->head
               next = cl->next
               if CAS (&q->head, cl, next):
                       break
       return cl




10/21/12
ABA problem
●   Поток T1 читает значение A,
●   T1 вытесняется, позволяя выполняться T2,
●   T2 меняет значение A на B и обратно на A,
●   T1 возобновляет работу, видит, что
    значение не изменилось, и продолжает…




10/21/12
Lock-free очередь: ABA
pop (q: pointer to fifo):
       Loop:
               cl = q->head
               next = cl->next                # cl = A, next = B
               ------->scheduled              # pop(A), pop(B), push(A)
               if CAS (&q->head, cl, next):   # cl->head => B (вместо C)
                       break
       return cl




10/21/12
Решение ABA
●   Вводятся счетчики числа pop()'ов и push()'ей для всей структуры или
    отдельных элементов и атомарно сравниваются
●   Нужна операция CAS2 (Double CAS) для сравнения двух операндов:
    CMPXCHG16B на x86-64




10/21/12
Lock-free очередь на Ring-Buffer: (0)




10/21/12
Lock-free очередь на Ring-Buffer: (1)
●   Избавляемся от мьютекса
push():
          while (tail_ + Q_SIZE < head_)
                 sched_yield();
          Thread 1                 Thread 2
          read tail_               read tail_
          read head_               read head_
          ------->scheduled        push an element
          push an element




10/21/12
Lock-free очередь на Ring-Buffer: (2)
●   Резервируем место для вставки (→ одно чтение)
push():
          unsigned long tmp_head = __sync_fetch_and_add(&head_, 1);
          while (tail_ + Q_SIZE < tmp_head)
              sched_yield();
          ptr_array_[tmp_head & Q_MASK] = x;




10/21/12
Lock-free очередь на Ring-Buffer: (3)
●   Per-thread current LH & LT
push():
           volatile unsigned long last_head_;
           volatile unsigned long last_tail_;
           auto min = tail_;
           for (size_t i = 0; i < n_consumers_; ++i) {
                   if (thr_p_[i].tail < min)
                           min = thr_p_[i].tail;
           }
           last_tail_ = min;




10/21/12
Lock-free очередь на Ring-Buffer: (4)
●  Чтение tail i-го потока только один раз
push():
       auto min = tail_;
       for (size_t i = 0; i < n_consumers_; ++i) {
              auto tmp_t = thr_p_[i].tail;
              if (tmp_t < min)
                      min = tmp_t;
       }
       last_tail_ = min;




10/21/12
Lock-free очередь на Ring-Buffer: (5)
●   Не оставляем текущий tail i-го потока надолго
pop():
         thr_pos().tail = __sync_fetch_and_add(&tail_, 1);


         // ….........


         T *ret = ptr_array_[thr_pos().tail & Q_MASK];
         thr_pos().tail = ULONG_MAX;
         return ret;




10/21/12
Lock-free очередь на Ring-Buffer: (6)
●   Двойная запись текущего значения tail и синхронизация с
    инкрементом tail_

pop():
         thr_pos().tail = tail_;
         __sync_synchronize();
         thr_pos().tail = __sync_fetch_and_add(&tail_, 1);




10/21/12
Lock-free очередь
                (список vs ring-buffer)
●   Ring-buffer сложнее в реализации (требуется синхронизированное
    передвижение указателей на tail и head для каждого из потоков)
●   Список должен быть интрузивным для избежания аллокации узлов на
    каждой вставке
●   Для списка нужно отдельно реализовать контроль числа элементов
●   Локализация и выравнивание памяти - ?




10/21/12
Lock-free очередь (ограничения)
●   Работает только для очередей — сканировать такие структуры
    данных без блокировок нельзя
●   Для очереди нужна реализация ожидания:
           ●   usleep(1000) — помещение потока в wait queue на примерно
               один такт системного таймера
           ●   sched_yield() - busy loop на перепланирование (100% CPU
               usage)




10/21/12
Zero copy
●   Чем больше каждое из сообщений, обрабатываемых
    сервером, тем актуальнее
●   Решается через zero copy IO, zero copy алгоритмы и
    структуры данных и архитектуру сервера в целом
●   Недостатки: сильная связность между IO, аллокатором
    памяти, управлением потоками




10/21/12
Архитектура zero copy сервера




10/21/12
Zero-copy ввод-вывод
●   Сетевой (минуя Socket API/kernel копирования)
●   Дисковый (минуя буферы программы или буферный кэш ОС)


●   Не “вымывает” кэши процессоров
●   Имеет накладные расходы => актуально только при работе с
    большими блоками данных




10/21/12
Zero-copy Network (I)O




10/21/12
Zero-copy Network (I)O:
                vmsplice()/splice()
●   Только на Output, на Input memcpy() в ядре
●   Сетевой стек пишет данные напрямую со страницы =>
    перед использованием страницы снова нужно записать 2
    размера буфера отправки (double-buffer write)




10/21/12
Zero-copy Network (I)O: пример
void zcp_send(int sd, const struct iovec *iov, size_t num) {
        pipe(pipe_);
        size_t data_len = 0;
        for (size_t i = 0; i < num; ++i)
                data_len += iov[i].iov_len;
        vmsplice(pipe_[1], iov, num, 0);
        for (int r; data_len; data_len -= r)
                r = splice(pipe_[0], NULL, sd, NULL, data_len, 0);
}




10/21/12
Splice: производительность
(Тесты splice() от Jens Axboe):


        # ./nettest/xmit -s65536 -p1000000   127.0.0.1 5500
           xmit: msg=64kb, packets=1000000 vmsplice() -> splice()
           usr=9259, sys=6864, real=27973
        # ./nettest/xmit -s65536 -p1000000 -n 127.0.0.1 5500
           xmit: msg=64kb, packets=1000000 send()
           usr=8762, sys=25497, real=34261




10/21/12
Спасибо!



           ak@natsys-lab.com




10/21/12

More Related Content

What's hot

Что нового в nginx? / Максим Дунин (Nginx, Inc.)
Что нового в nginx? / Максим Дунин (Nginx, Inc.)Что нового в nginx? / Максим Дунин (Nginx, Inc.)
Что нового в nginx? / Максим Дунин (Nginx, Inc.)Ontico
 
Франкенштейнизация Voldemort или key-value данные в Одноклассниках. Роман Ан...
Франкенштейнизация Voldemort или key-value данные в Одноклассниках. Роман Ан...Франкенштейнизация Voldemort или key-value данные в Одноклассниках. Роман Ан...
Франкенштейнизация Voldemort или key-value данные в Одноклассниках. Роман Ан...odnoklassniki.ru
 
Chronicle Map — key-value хранилище для трейдинга на Java / Левентов Роман (C...
Chronicle Map — key-value хранилище для трейдинга на Java / Левентов Роман (C...Chronicle Map — key-value хранилище для трейдинга на Java / Левентов Роман (C...
Chronicle Map — key-value хранилище для трейдинга на Java / Левентов Роман (C...Ontico
 
DNS в условиях хостинг-провайдера / Константин Новаковский (Selectel)
DNS в условиях хостинг-провайдера / Константин Новаковский (Selectel)DNS в условиях хостинг-провайдера / Константин Новаковский (Selectel)
DNS в условиях хостинг-провайдера / Константин Новаковский (Selectel)Ontico
 
Кластеры баз данных делаем сложные вещи просто / Андрей Тихонов (Avito)
Кластеры баз данных делаем сложные вещи просто / Андрей Тихонов (Avito)Кластеры баз данных делаем сложные вещи просто / Андрей Тихонов (Avito)
Кластеры баз данных делаем сложные вещи просто / Андрей Тихонов (Avito)Ontico
 
Тюним память и сетевой стек в Linux: история перевода высоконагруженных серве...
Тюним память и сетевой стек в Linux: история перевода высоконагруженных серве...Тюним память и сетевой стек в Linux: история перевода высоконагруженных серве...
Тюним память и сетевой стек в Linux: история перевода высоконагруженных серве...odnoklassniki.ru
 
Хранение данных на виниле / Константин Осипов (tarantool.org)
Хранение данных на виниле / Константин Осипов (tarantool.org)Хранение данных на виниле / Константин Осипов (tarantool.org)
Хранение данных на виниле / Константин Осипов (tarantool.org)Ontico
 
Константин Осипов (Mail.Ru)
Константин Осипов (Mail.Ru)Константин Осипов (Mail.Ru)
Константин Осипов (Mail.Ru)Ontico
 
Строим сервисы на базе Nginx и Tarantool / Василий Сошников, Андрей Дроздов (...
Строим сервисы на базе Nginx и Tarantool / Василий Сошников, Андрей Дроздов (...Строим сервисы на базе Nginx и Tarantool / Василий Сошников, Андрей Дроздов (...
Строим сервисы на базе Nginx и Tarantool / Василий Сошников, Андрей Дроздов (...Ontico
 
Отказоустойчивый микрокластер своими руками, Виталий Гаврилов (Ленвендо)
Отказоустойчивый микрокластер своими руками, Виталий Гаврилов (Ленвендо)Отказоустойчивый микрокластер своими руками, Виталий Гаврилов (Ленвендо)
Отказоустойчивый микрокластер своими руками, Виталий Гаврилов (Ленвендо)Ontico
 
Как обслужить 60 миллионов абонентов, Артем Руфанов (ПЕТЕР-СЕРВИС)
Как обслужить 60 миллионов абонентов, Артем Руфанов (ПЕТЕР-СЕРВИС)Как обслужить 60 миллионов абонентов, Артем Руфанов (ПЕТЕР-СЕРВИС)
Как обслужить 60 миллионов абонентов, Артем Руфанов (ПЕТЕР-СЕРВИС)Ontico
 
"Кластеры баз данных: делаем сложные вещи просто" Андрей Тихонов (Avito)
"Кластеры баз данных: делаем сложные вещи просто" Андрей Тихонов (Avito)"Кластеры баз данных: делаем сложные вещи просто" Андрей Тихонов (Avito)
"Кластеры баз данных: делаем сложные вещи просто" Андрей Тихонов (Avito)AvitoTech
 
Кадры решают все, или стриминг видео в «Одноклассниках». Александр Тоболь
Кадры решают все, или стриминг видео в «Одноклассниках». Александр ТобольКадры решают все, или стриминг видео в «Одноклассниках». Александр Тоболь
Кадры решают все, или стриминг видео в «Одноклассниках». Александр Тобольodnoklassniki.ru
 
Платформа для видео сроком в квартал. Александр Тоболь.
Платформа для видео сроком в квартал. Александр Тоболь.Платформа для видео сроком в квартал. Александр Тоболь.
Платформа для видео сроком в квартал. Александр Тоболь.odnoklassniki.ru
 
Архитектура растущего проекта на примере ВКонтакте / Алексей Акулович (ВКонт...
 Архитектура растущего проекта на примере ВКонтакте / Алексей Акулович (ВКонт... Архитектура растущего проекта на примере ВКонтакте / Алексей Акулович (ВКонт...
Архитектура растущего проекта на примере ВКонтакте / Алексей Акулович (ВКонт...Ontico
 
Инструменты высоконагруженных проектов - кэширование и очереди, Вячеслав Моск...
Инструменты высоконагруженных проектов - кэширование и очереди, Вячеслав Моск...Инструменты высоконагруженных проектов - кэширование и очереди, Вячеслав Моск...
Инструменты высоконагруженных проектов - кэширование и очереди, Вячеслав Моск...Ontico
 
Марина Широчкина: Верстка. Вид снизу
Марина Широчкина: Верстка. Вид снизуМарина Широчкина: Верстка. Вид снизу
Марина Широчкина: Верстка. Вид снизуYandex
 
За гранью NoSQL: NewSQL на Cassandra
За гранью NoSQL: NewSQL на CassandraЗа гранью NoSQL: NewSQL на Cassandra
За гранью NoSQL: NewSQL на Cassandraodnoklassniki.ru
 
Вячеслав Бирюков - HTTP и HTTPS
Вячеслав Бирюков - HTTP и HTTPSВячеслав Бирюков - HTTP и HTTPS
Вячеслав Бирюков - HTTP и HTTPSYandex
 
Движок LMDB — особенный чемпион / Юрьев Леонид (Петер-Сервис R&D)
Движок LMDB — особенный чемпион / Юрьев Леонид (Петер-Сервис R&D)Движок LMDB — особенный чемпион / Юрьев Леонид (Петер-Сервис R&D)
Движок LMDB — особенный чемпион / Юрьев Леонид (Петер-Сервис R&D)Ontico
 

What's hot (20)

Что нового в nginx? / Максим Дунин (Nginx, Inc.)
Что нового в nginx? / Максим Дунин (Nginx, Inc.)Что нового в nginx? / Максим Дунин (Nginx, Inc.)
Что нового в nginx? / Максим Дунин (Nginx, Inc.)
 
Франкенштейнизация Voldemort или key-value данные в Одноклассниках. Роман Ан...
Франкенштейнизация Voldemort или key-value данные в Одноклассниках. Роман Ан...Франкенштейнизация Voldemort или key-value данные в Одноклассниках. Роман Ан...
Франкенштейнизация Voldemort или key-value данные в Одноклассниках. Роман Ан...
 
Chronicle Map — key-value хранилище для трейдинга на Java / Левентов Роман (C...
Chronicle Map — key-value хранилище для трейдинга на Java / Левентов Роман (C...Chronicle Map — key-value хранилище для трейдинга на Java / Левентов Роман (C...
Chronicle Map — key-value хранилище для трейдинга на Java / Левентов Роман (C...
 
DNS в условиях хостинг-провайдера / Константин Новаковский (Selectel)
DNS в условиях хостинг-провайдера / Константин Новаковский (Selectel)DNS в условиях хостинг-провайдера / Константин Новаковский (Selectel)
DNS в условиях хостинг-провайдера / Константин Новаковский (Selectel)
 
Кластеры баз данных делаем сложные вещи просто / Андрей Тихонов (Avito)
Кластеры баз данных делаем сложные вещи просто / Андрей Тихонов (Avito)Кластеры баз данных делаем сложные вещи просто / Андрей Тихонов (Avito)
Кластеры баз данных делаем сложные вещи просто / Андрей Тихонов (Avito)
 
Тюним память и сетевой стек в Linux: история перевода высоконагруженных серве...
Тюним память и сетевой стек в Linux: история перевода высоконагруженных серве...Тюним память и сетевой стек в Linux: история перевода высоконагруженных серве...
Тюним память и сетевой стек в Linux: история перевода высоконагруженных серве...
 
Хранение данных на виниле / Константин Осипов (tarantool.org)
Хранение данных на виниле / Константин Осипов (tarantool.org)Хранение данных на виниле / Константин Осипов (tarantool.org)
Хранение данных на виниле / Константин Осипов (tarantool.org)
 
Константин Осипов (Mail.Ru)
Константин Осипов (Mail.Ru)Константин Осипов (Mail.Ru)
Константин Осипов (Mail.Ru)
 
Строим сервисы на базе Nginx и Tarantool / Василий Сошников, Андрей Дроздов (...
Строим сервисы на базе Nginx и Tarantool / Василий Сошников, Андрей Дроздов (...Строим сервисы на базе Nginx и Tarantool / Василий Сошников, Андрей Дроздов (...
Строим сервисы на базе Nginx и Tarantool / Василий Сошников, Андрей Дроздов (...
 
Отказоустойчивый микрокластер своими руками, Виталий Гаврилов (Ленвендо)
Отказоустойчивый микрокластер своими руками, Виталий Гаврилов (Ленвендо)Отказоустойчивый микрокластер своими руками, Виталий Гаврилов (Ленвендо)
Отказоустойчивый микрокластер своими руками, Виталий Гаврилов (Ленвендо)
 
Как обслужить 60 миллионов абонентов, Артем Руфанов (ПЕТЕР-СЕРВИС)
Как обслужить 60 миллионов абонентов, Артем Руфанов (ПЕТЕР-СЕРВИС)Как обслужить 60 миллионов абонентов, Артем Руфанов (ПЕТЕР-СЕРВИС)
Как обслужить 60 миллионов абонентов, Артем Руфанов (ПЕТЕР-СЕРВИС)
 
"Кластеры баз данных: делаем сложные вещи просто" Андрей Тихонов (Avito)
"Кластеры баз данных: делаем сложные вещи просто" Андрей Тихонов (Avito)"Кластеры баз данных: делаем сложные вещи просто" Андрей Тихонов (Avito)
"Кластеры баз данных: делаем сложные вещи просто" Андрей Тихонов (Avito)
 
Кадры решают все, или стриминг видео в «Одноклассниках». Александр Тоболь
Кадры решают все, или стриминг видео в «Одноклассниках». Александр ТобольКадры решают все, или стриминг видео в «Одноклассниках». Александр Тоболь
Кадры решают все, или стриминг видео в «Одноклассниках». Александр Тоболь
 
Платформа для видео сроком в квартал. Александр Тоболь.
Платформа для видео сроком в квартал. Александр Тоболь.Платформа для видео сроком в квартал. Александр Тоболь.
Платформа для видео сроком в квартал. Александр Тоболь.
 
Архитектура растущего проекта на примере ВКонтакте / Алексей Акулович (ВКонт...
 Архитектура растущего проекта на примере ВКонтакте / Алексей Акулович (ВКонт... Архитектура растущего проекта на примере ВКонтакте / Алексей Акулович (ВКонт...
Архитектура растущего проекта на примере ВКонтакте / Алексей Акулович (ВКонт...
 
Инструменты высоконагруженных проектов - кэширование и очереди, Вячеслав Моск...
Инструменты высоконагруженных проектов - кэширование и очереди, Вячеслав Моск...Инструменты высоконагруженных проектов - кэширование и очереди, Вячеслав Моск...
Инструменты высоконагруженных проектов - кэширование и очереди, Вячеслав Моск...
 
Марина Широчкина: Верстка. Вид снизу
Марина Широчкина: Верстка. Вид снизуМарина Широчкина: Верстка. Вид снизу
Марина Широчкина: Верстка. Вид снизу
 
За гранью NoSQL: NewSQL на Cassandra
За гранью NoSQL: NewSQL на CassandraЗа гранью NoSQL: NewSQL на Cassandra
За гранью NoSQL: NewSQL на Cassandra
 
Вячеслав Бирюков - HTTP и HTTPS
Вячеслав Бирюков - HTTP и HTTPSВячеслав Бирюков - HTTP и HTTPS
Вячеслав Бирюков - HTTP и HTTPS
 
Движок LMDB — особенный чемпион / Юрьев Леонид (Петер-Сервис R&D)
Движок LMDB — особенный чемпион / Юрьев Леонид (Петер-Сервис R&D)Движок LMDB — особенный чемпион / Юрьев Леонид (Петер-Сервис R&D)
Движок LMDB — особенный чемпион / Юрьев Леонид (Петер-Сервис R&D)
 

Similar to Разработка высокопроизводительных серверных приложений для Linux/Unix (Александр Крижановский)

CUDA Course 2010 at MSU
CUDA Course 2010 at MSUCUDA Course 2010 at MSU
CUDA Course 2010 at MSUlarhat
 
Современная операционная система: что надо знать разработчику / Александр Кри...
Современная операционная система: что надо знать разработчику / Александр Кри...Современная операционная система: что надо знать разработчику / Александр Кри...
Современная операционная система: что надо знать разработчику / Александр Кри...Ontico
 
Что такое Postgresql (Максим Богук)
Что такое Postgresql (Максим Богук)Что такое Postgresql (Максим Богук)
Что такое Postgresql (Максим Богук)Ontico
 
BigMemory - работа с сотнями миллионов бизнес-объектов / Дмитрий Хмаладзе (Ag...
BigMemory - работа с сотнями миллионов бизнес-объектов / Дмитрий Хмаладзе (Ag...BigMemory - работа с сотнями миллионов бизнес-объектов / Дмитрий Хмаладзе (Ag...
BigMemory - работа с сотнями миллионов бизнес-объектов / Дмитрий Хмаладзе (Ag...Ontico
 
Максим Богук. Postgres-XC
Максим Богук. Postgres-XCМаксим Богук. Postgres-XC
Максим Богук. Postgres-XCPostgreSQL-Consulting
 
Другая виртуализация
Другая виртуализацияДругая виртуализация
Другая виртуализацияYandex
 
Hosting for forbes.ru_
Hosting for forbes.ru_Hosting for forbes.ru_
Hosting for forbes.ru_drupalconf
 
"YT — новая платформа распределённых вычислений". Максим Бабенко, Яндекс.
"YT — новая платформа распределённых вычислений". Максим Бабенко, Яндекс. "YT — новая платформа распределённых вычислений". Максим Бабенко, Яндекс.
"YT — новая платформа распределённых вычислений". Максим Бабенко, Яндекс. Yandex
 
ПВТ - весна 2015 - Лекция 2. POSIX Threads. Основные понятия многопоточного п...
ПВТ - весна 2015 - Лекция 2. POSIX Threads. Основные понятия многопоточного п...ПВТ - весна 2015 - Лекция 2. POSIX Threads. Основные понятия многопоточного п...
ПВТ - весна 2015 - Лекция 2. POSIX Threads. Основные понятия многопоточного п...Alexey Paznikov
 
Операционные системы
Операционные системыОперационные системы
Операционные системыyaevents
 
16 декабря, DEV {highload} - конференция о Highload веб-разработке, "Эксплуат...
16 декабря, DEV {highload} - конференция о Highload веб-разработке, "Эксплуат...16 декабря, DEV {highload} - конференция о Highload веб-разработке, "Эксплуат...
16 декабря, DEV {highload} - конференция о Highload веб-разработке, "Эксплуат...IT-Portfolio
 
Как построить высокопроизводительный Front-end сервер (Александр Крижановский)
Как построить высокопроизводительный Front-end сервер (Александр Крижановский) Как построить высокопроизводительный Front-end сервер (Александр Крижановский)
Как построить высокопроизводительный Front-end сервер (Александр Крижановский) Ontico
 
Константин Осипов
Константин ОсиповКонстантин Осипов
Константин ОсиповCodeFest
 
Архитектура и программирование потоковых многоядерных процессоров для научных...
Архитектура и программирование потоковых многоядерных процессоров для научных...Архитектура и программирование потоковых многоядерных процессоров для научных...
Архитектура и программирование потоковых многоядерных процессоров для научных...a15464321646213
 
Пути увеличения эффективности реализации алгоритмов машинного обучения
Пути увеличения эффективности реализации алгоритмов машинного обученияПути увеличения эффективности реализации алгоритмов машинного обучения
Пути увеличения эффективности реализации алгоритмов машинного обученияAndrew Babiy
 
MIPT Course - DAC and MAC
MIPT Course - DAC and MACMIPT Course - DAC and MAC
MIPT Course - DAC and MACAlexey Vasyukov
 
Machine learning c использованием нейронных сетей, Дмитрий Лапин
Machine learning c использованием нейронных сетей, Дмитрий ЛапинMachine learning c использованием нейронных сетей, Дмитрий Лапин
Machine learning c использованием нейронных сетей, Дмитрий ЛапинIT61
 
Евгений Лазин. Неизменяемая структура данных HAMT для создания БД в памяти
Евгений Лазин. Неизменяемая структура данных HAMT для создания БД в памятиЕвгений Лазин. Неизменяемая структура данных HAMT для создания БД в памяти
Евгений Лазин. Неизменяемая структура данных HAMT для создания БД в памятиFProg
 

Similar to Разработка высокопроизводительных серверных приложений для Linux/Unix (Александр Крижановский) (20)

Lab5
Lab5Lab5
Lab5
 
CUDA Course 2010 at MSU
CUDA Course 2010 at MSUCUDA Course 2010 at MSU
CUDA Course 2010 at MSU
 
Современная операционная система: что надо знать разработчику / Александр Кри...
Современная операционная система: что надо знать разработчику / Александр Кри...Современная операционная система: что надо знать разработчику / Александр Кри...
Современная операционная система: что надо знать разработчику / Александр Кри...
 
Что такое Postgresql (Максим Богук)
Что такое Postgresql (Максим Богук)Что такое Postgresql (Максим Богук)
Что такое Postgresql (Максим Богук)
 
BigMemory - работа с сотнями миллионов бизнес-объектов / Дмитрий Хмаладзе (Ag...
BigMemory - работа с сотнями миллионов бизнес-объектов / Дмитрий Хмаладзе (Ag...BigMemory - работа с сотнями миллионов бизнес-объектов / Дмитрий Хмаладзе (Ag...
BigMemory - работа с сотнями миллионов бизнес-объектов / Дмитрий Хмаладзе (Ag...
 
Максим Богук. Postgres-XC
Максим Богук. Postgres-XCМаксим Богук. Postgres-XC
Максим Богук. Postgres-XC
 
Другая виртуализация
Другая виртуализацияДругая виртуализация
Другая виртуализация
 
Hosting for forbes.ru_
Hosting for forbes.ru_Hosting for forbes.ru_
Hosting for forbes.ru_
 
"YT — новая платформа распределённых вычислений". Максим Бабенко, Яндекс.
"YT — новая платформа распределённых вычислений". Максим Бабенко, Яндекс. "YT — новая платформа распределённых вычислений". Максим Бабенко, Яндекс.
"YT — новая платформа распределённых вычислений". Максим Бабенко, Яндекс.
 
ПВТ - весна 2015 - Лекция 2. POSIX Threads. Основные понятия многопоточного п...
ПВТ - весна 2015 - Лекция 2. POSIX Threads. Основные понятия многопоточного п...ПВТ - весна 2015 - Лекция 2. POSIX Threads. Основные понятия многопоточного п...
ПВТ - весна 2015 - Лекция 2. POSIX Threads. Основные понятия многопоточного п...
 
Операционные системы
Операционные системыОперационные системы
Операционные системы
 
16 декабря, DEV {highload} - конференция о Highload веб-разработке, "Эксплуат...
16 декабря, DEV {highload} - конференция о Highload веб-разработке, "Эксплуат...16 декабря, DEV {highload} - конференция о Highload веб-разработке, "Эксплуат...
16 декабря, DEV {highload} - конференция о Highload веб-разработке, "Эксплуат...
 
HBase on Dev{Highload}
HBase on Dev{Highload}HBase on Dev{Highload}
HBase on Dev{Highload}
 
Как построить высокопроизводительный Front-end сервер (Александр Крижановский)
Как построить высокопроизводительный Front-end сервер (Александр Крижановский) Как построить высокопроизводительный Front-end сервер (Александр Крижановский)
Как построить высокопроизводительный Front-end сервер (Александр Крижановский)
 
Константин Осипов
Константин ОсиповКонстантин Осипов
Константин Осипов
 
Архитектура и программирование потоковых многоядерных процессоров для научных...
Архитектура и программирование потоковых многоядерных процессоров для научных...Архитектура и программирование потоковых многоядерных процессоров для научных...
Архитектура и программирование потоковых многоядерных процессоров для научных...
 
Пути увеличения эффективности реализации алгоритмов машинного обучения
Пути увеличения эффективности реализации алгоритмов машинного обученияПути увеличения эффективности реализации алгоритмов машинного обучения
Пути увеличения эффективности реализации алгоритмов машинного обучения
 
MIPT Course - DAC and MAC
MIPT Course - DAC and MACMIPT Course - DAC and MAC
MIPT Course - DAC and MAC
 
Machine learning c использованием нейронных сетей, Дмитрий Лапин
Machine learning c использованием нейронных сетей, Дмитрий ЛапинMachine learning c использованием нейронных сетей, Дмитрий Лапин
Machine learning c использованием нейронных сетей, Дмитрий Лапин
 
Евгений Лазин. Неизменяемая структура данных HAMT для создания БД в памяти
Евгений Лазин. Неизменяемая структура данных HAMT для создания БД в памятиЕвгений Лазин. Неизменяемая структура данных HAMT для создания БД в памяти
Евгений Лазин. Неизменяемая структура данных HAMT для создания БД в памяти
 

More from Ontico

One-cloud — система управления дата-центром в Одноклассниках / Олег Анастасье...
One-cloud — система управления дата-центром в Одноклассниках / Олег Анастасье...One-cloud — система управления дата-центром в Одноклассниках / Олег Анастасье...
One-cloud — система управления дата-центром в Одноклассниках / Олег Анастасье...Ontico
 
Масштабируя DNS / Артем Гавриченков (Qrator Labs)
Масштабируя DNS / Артем Гавриченков (Qrator Labs)Масштабируя DNS / Артем Гавриченков (Qrator Labs)
Масштабируя DNS / Артем Гавриченков (Qrator Labs)Ontico
 
Создание BigData-платформы для ФГУП Почта России / Андрей Бащенко (Luxoft)
Создание BigData-платформы для ФГУП Почта России / Андрей Бащенко (Luxoft)Создание BigData-платформы для ФГУП Почта России / Андрей Бащенко (Luxoft)
Создание BigData-платформы для ФГУП Почта России / Андрей Бащенко (Luxoft)Ontico
 
Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...
Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...
Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...Ontico
 
Новые технологии репликации данных в PostgreSQL / Александр Алексеев (Postgre...
Новые технологии репликации данных в PostgreSQL / Александр Алексеев (Postgre...Новые технологии репликации данных в PostgreSQL / Александр Алексеев (Postgre...
Новые технологии репликации данных в PostgreSQL / Александр Алексеев (Postgre...Ontico
 
PostgreSQL Configuration for Humans / Alvaro Hernandez (OnGres)
PostgreSQL Configuration for Humans / Alvaro Hernandez (OnGres)PostgreSQL Configuration for Humans / Alvaro Hernandez (OnGres)
PostgreSQL Configuration for Humans / Alvaro Hernandez (OnGres)Ontico
 
Inexpensive Datamasking for MySQL with ProxySQL — Data Anonymization for Deve...
Inexpensive Datamasking for MySQL with ProxySQL — Data Anonymization for Deve...Inexpensive Datamasking for MySQL with ProxySQL — Data Anonymization for Deve...
Inexpensive Datamasking for MySQL with ProxySQL — Data Anonymization for Deve...Ontico
 
Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...
Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...
Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...Ontico
 
ProxySQL Use Case Scenarios / Alkin Tezuysal (Percona)
ProxySQL Use Case Scenarios / Alkin Tezuysal (Percona)ProxySQL Use Case Scenarios / Alkin Tezuysal (Percona)
ProxySQL Use Case Scenarios / Alkin Tezuysal (Percona)Ontico
 
MySQL Replication — Advanced Features / Петр Зайцев (Percona)
MySQL Replication — Advanced Features / Петр Зайцев (Percona)MySQL Replication — Advanced Features / Петр Зайцев (Percona)
MySQL Replication — Advanced Features / Петр Зайцев (Percona)Ontico
 
Внутренний open-source. Как разрабатывать мобильное приложение большим количе...
Внутренний open-source. Как разрабатывать мобильное приложение большим количе...Внутренний open-source. Как разрабатывать мобильное приложение большим количе...
Внутренний open-source. Как разрабатывать мобильное приложение большим количе...Ontico
 
Подробно о том, как Causal Consistency реализовано в MongoDB / Михаил Тюленев...
Подробно о том, как Causal Consistency реализовано в MongoDB / Михаил Тюленев...Подробно о том, как Causal Consistency реализовано в MongoDB / Михаил Тюленев...
Подробно о том, как Causal Consistency реализовано в MongoDB / Михаил Тюленев...Ontico
 
Балансировка на скорости проводов. Без ASIC, без ограничений. Решения NFWare ...
Балансировка на скорости проводов. Без ASIC, без ограничений. Решения NFWare ...Балансировка на скорости проводов. Без ASIC, без ограничений. Решения NFWare ...
Балансировка на скорости проводов. Без ASIC, без ограничений. Решения NFWare ...Ontico
 
Перехват трафика — мифы и реальность / Евгений Усков (Qrator Labs)
Перехват трафика — мифы и реальность / Евгений Усков (Qrator Labs)Перехват трафика — мифы и реальность / Евгений Усков (Qrator Labs)
Перехват трафика — мифы и реальность / Евгений Усков (Qrator Labs)Ontico
 
И тогда наверняка вдруг запляшут облака! / Алексей Сушков (ПЕТЕР-СЕРВИС)
И тогда наверняка вдруг запляшут облака! / Алексей Сушков (ПЕТЕР-СЕРВИС)И тогда наверняка вдруг запляшут облака! / Алексей Сушков (ПЕТЕР-СЕРВИС)
И тогда наверняка вдруг запляшут облака! / Алексей Сушков (ПЕТЕР-СЕРВИС)Ontico
 
Как мы заставили Druid работать в Одноклассниках / Юрий Невиницин (OK.RU)
Как мы заставили Druid работать в Одноклассниках / Юрий Невиницин (OK.RU)Как мы заставили Druid работать в Одноклассниках / Юрий Невиницин (OK.RU)
Как мы заставили Druid работать в Одноклассниках / Юрий Невиницин (OK.RU)Ontico
 
Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)
Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)
Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)Ontico
 
100500 способов кэширования в Oracle Database или как достичь максимальной ск...
100500 способов кэширования в Oracle Database или как достичь максимальной ск...100500 способов кэширования в Oracle Database или как достичь максимальной ск...
100500 способов кэширования в Oracle Database или как достичь максимальной ск...Ontico
 
Apache Ignite Persistence: зачем Persistence для In-Memory, и как он работает...
Apache Ignite Persistence: зачем Persistence для In-Memory, и как он работает...Apache Ignite Persistence: зачем Persistence для In-Memory, и как он работает...
Apache Ignite Persistence: зачем Persistence для In-Memory, и как он работает...Ontico
 
Механизмы мониторинга баз данных: взгляд изнутри / Дмитрий Еманов (Firebird P...
Механизмы мониторинга баз данных: взгляд изнутри / Дмитрий Еманов (Firebird P...Механизмы мониторинга баз данных: взгляд изнутри / Дмитрий Еманов (Firebird P...
Механизмы мониторинга баз данных: взгляд изнутри / Дмитрий Еманов (Firebird P...Ontico
 

More from Ontico (20)

One-cloud — система управления дата-центром в Одноклассниках / Олег Анастасье...
One-cloud — система управления дата-центром в Одноклассниках / Олег Анастасье...One-cloud — система управления дата-центром в Одноклассниках / Олег Анастасье...
One-cloud — система управления дата-центром в Одноклассниках / Олег Анастасье...
 
Масштабируя DNS / Артем Гавриченков (Qrator Labs)
Масштабируя DNS / Артем Гавриченков (Qrator Labs)Масштабируя DNS / Артем Гавриченков (Qrator Labs)
Масштабируя DNS / Артем Гавриченков (Qrator Labs)
 
Создание BigData-платформы для ФГУП Почта России / Андрей Бащенко (Luxoft)
Создание BigData-платформы для ФГУП Почта России / Андрей Бащенко (Luxoft)Создание BigData-платформы для ФГУП Почта России / Андрей Бащенко (Luxoft)
Создание BigData-платформы для ФГУП Почта России / Андрей Бащенко (Luxoft)
 
Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...
Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...
Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...
 
Новые технологии репликации данных в PostgreSQL / Александр Алексеев (Postgre...
Новые технологии репликации данных в PostgreSQL / Александр Алексеев (Postgre...Новые технологии репликации данных в PostgreSQL / Александр Алексеев (Postgre...
Новые технологии репликации данных в PostgreSQL / Александр Алексеев (Postgre...
 
PostgreSQL Configuration for Humans / Alvaro Hernandez (OnGres)
PostgreSQL Configuration for Humans / Alvaro Hernandez (OnGres)PostgreSQL Configuration for Humans / Alvaro Hernandez (OnGres)
PostgreSQL Configuration for Humans / Alvaro Hernandez (OnGres)
 
Inexpensive Datamasking for MySQL with ProxySQL — Data Anonymization for Deve...
Inexpensive Datamasking for MySQL with ProxySQL — Data Anonymization for Deve...Inexpensive Datamasking for MySQL with ProxySQL — Data Anonymization for Deve...
Inexpensive Datamasking for MySQL with ProxySQL — Data Anonymization for Deve...
 
Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...
Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...
Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...
 
ProxySQL Use Case Scenarios / Alkin Tezuysal (Percona)
ProxySQL Use Case Scenarios / Alkin Tezuysal (Percona)ProxySQL Use Case Scenarios / Alkin Tezuysal (Percona)
ProxySQL Use Case Scenarios / Alkin Tezuysal (Percona)
 
MySQL Replication — Advanced Features / Петр Зайцев (Percona)
MySQL Replication — Advanced Features / Петр Зайцев (Percona)MySQL Replication — Advanced Features / Петр Зайцев (Percona)
MySQL Replication — Advanced Features / Петр Зайцев (Percona)
 
Внутренний open-source. Как разрабатывать мобильное приложение большим количе...
Внутренний open-source. Как разрабатывать мобильное приложение большим количе...Внутренний open-source. Как разрабатывать мобильное приложение большим количе...
Внутренний open-source. Как разрабатывать мобильное приложение большим количе...
 
Подробно о том, как Causal Consistency реализовано в MongoDB / Михаил Тюленев...
Подробно о том, как Causal Consistency реализовано в MongoDB / Михаил Тюленев...Подробно о том, как Causal Consistency реализовано в MongoDB / Михаил Тюленев...
Подробно о том, как Causal Consistency реализовано в MongoDB / Михаил Тюленев...
 
Балансировка на скорости проводов. Без ASIC, без ограничений. Решения NFWare ...
Балансировка на скорости проводов. Без ASIC, без ограничений. Решения NFWare ...Балансировка на скорости проводов. Без ASIC, без ограничений. Решения NFWare ...
Балансировка на скорости проводов. Без ASIC, без ограничений. Решения NFWare ...
 
Перехват трафика — мифы и реальность / Евгений Усков (Qrator Labs)
Перехват трафика — мифы и реальность / Евгений Усков (Qrator Labs)Перехват трафика — мифы и реальность / Евгений Усков (Qrator Labs)
Перехват трафика — мифы и реальность / Евгений Усков (Qrator Labs)
 
И тогда наверняка вдруг запляшут облака! / Алексей Сушков (ПЕТЕР-СЕРВИС)
И тогда наверняка вдруг запляшут облака! / Алексей Сушков (ПЕТЕР-СЕРВИС)И тогда наверняка вдруг запляшут облака! / Алексей Сушков (ПЕТЕР-СЕРВИС)
И тогда наверняка вдруг запляшут облака! / Алексей Сушков (ПЕТЕР-СЕРВИС)
 
Как мы заставили Druid работать в Одноклассниках / Юрий Невиницин (OK.RU)
Как мы заставили Druid работать в Одноклассниках / Юрий Невиницин (OK.RU)Как мы заставили Druid работать в Одноклассниках / Юрий Невиницин (OK.RU)
Как мы заставили Druid работать в Одноклассниках / Юрий Невиницин (OK.RU)
 
Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)
Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)
Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)
 
100500 способов кэширования в Oracle Database или как достичь максимальной ск...
100500 способов кэширования в Oracle Database или как достичь максимальной ск...100500 способов кэширования в Oracle Database или как достичь максимальной ск...
100500 способов кэширования в Oracle Database или как достичь максимальной ск...
 
Apache Ignite Persistence: зачем Persistence для In-Memory, и как он работает...
Apache Ignite Persistence: зачем Persistence для In-Memory, и как он работает...Apache Ignite Persistence: зачем Persistence для In-Memory, и как он работает...
Apache Ignite Persistence: зачем Persistence для In-Memory, и как он работает...
 
Механизмы мониторинга баз данных: взгляд изнутри / Дмитрий Еманов (Firebird P...
Механизмы мониторинга баз данных: взгляд изнутри / Дмитрий Еманов (Firebird P...Механизмы мониторинга баз данных: взгляд изнутри / Дмитрий Еманов (Firebird P...
Механизмы мониторинга баз данных: взгляд изнутри / Дмитрий Еманов (Firebird P...
 

Разработка высокопроизводительных серверных приложений для Linux/Unix (Александр Крижановский)

  • 1. Разработка высокопроизводительных серверных приложений для Linux/UNIX Крижановский Александр ak@natsys-lab.com 10/21/12
  • 3. Декомпозиция ● Функциональная декомпозиция ● Декомпозиция по данным 10/21/12
  • 4. Декомпозиция по данным Original: for (int i = 0; i < 10; ++i) foo(i); Thread 1: Thread 2: for (int i = 0; i < 5; ++i) for (int i = 5; i < 10; ++i) foo(i); foo(i); ● Пример: рабочие потоки, “разгребающие” очередь задач ● Хорошо масштабируется с ростом CPU. 10/21/12
  • 5. Функциональная декомпозиция Original: foo(); bar(); Thread 1: Thread 2: boo(); bar(); ● Пример: поток ввода, поток вывода, рабочий поток, поток реконфигурации и пр. ● Не масштабируется. 10/21/12
  • 6. Процессы vs Потоки ● Один и тот же task_struct, один и тот же do_fork() ● Потоки разделяют память, а процессы – нет. PostgreSQL: процессы, shared memory для buffer pool, блокировки тоже в shared memory 10/21/12
  • 7. Потоки – много или мало? ● Современные планировщики ОС обрабатывают N kernel-thread'ов за O(1) или O(log(N)) время ● Kernel-thread ~ process: тяжелое создание и ~6 страниц памяти => нужен пул тредов ● M потоков на один CPU => ухудшается cache hit (поток должен завершить текущую задачу и только потом перейти к следующей) ● Если нужен высокий параллелизм, то нужны coroutines; или events... 10/21/12
  • 8. Hyper Threading и когда много потоков хорошо ● Потоки делят один кэш ● Если cache hit rate <50%, то всегда выгоднее 2 и более потока на ядро ● Если у одного потока высокий hit rate, то добавление дополнительных потоков на ядро ухудшит производительность ● На одно ядро желательно не планировать потоки, исполняющие разный код с разными данными 10/21/12
  • 9. Синхронизация ● pthread_mutex_lock() - только один поток владеет ресурсом ● pthread_rwlock_wrlock()/pthread_rwlock_rdlock() - один писатель или много читателей ● pthread_cond_wait() - ожидать наступления события ● pthread_spin_lock() - проверяет блокировку в цикле ● (первые 3 работают через futex(2)) 10/21/12
  • 10. Pthreads & futex(2) static volatile int val = 0; void lock() { int c; while ((c = __sync_fetch_and_add(&val, 1)) lll_futex_wait(&val, c + 1); } void unlock() { val = 0; lll_futex_wake(&val, 1); } 10/21/12
  • 11. pthread_cond_broadcast: гремящее стадо ● Атомарные операции и, тем более, системный вызов – дорогие операции ● Поэтому лучше использовать pthread_cond_signal() 10/21/12
  • 12. Инвалидация кэшей на мьютексе ● Если поток не может захватить мьютекс, то он уходит в сон ● => на текущем процессоре будет запущен другой поток ● => этот поток “вымоет кэш” ● Когда мьютекс будет отпущен, то поток продолжит выполнение с “вымытым” кэшем или на другом процессоре 10/21/12
  • 13. pthread_spin_lock (упрощенно) static volatile int lock = 0; void lock() { while (!__sync_bool_compare_and_swap(&lock, 0, 1)); } void unlock() { lock = 0; } 10/21/12
  • 14. pthread_spin_lock (scheduled) CPU0 CPU1 Thread0: lock() . . . Thread0: some work Thread1: try lock() → loop . . . Thread2: try lock() → loop // Thread0 preempted . . . (loop) . . . Thread1: try lock() → loop Thread2: try lock() → loop // 200% CPU usage . . . // Thread2 preempted . . . Thread0: unlock() Ядро для этого использует preempt_disable() 10/21/12
  • 15. pthread_rwlock ● “дороже” pthread_mutex (больше сама структура данных ~ в 1.5 раза, сложнее операция взятия лока) ● Снижает lock contention при превалировании числа читателей над писателями, но снижается производительность per-cpu 10/21/12
  • 16. Lock contention ● Один процесс удерживает лок, другие процессы ждут — система становится однопроцессной ● Актуален с увеличением числа вычислительных ядер (или потоков исполнения) и числом блокировок в программе ● Признак: ресурсы сервера используются слабо (CPU, IO etc), но число RPS невысокий ● Методы борьбы: увеличение гранулярности блокировок, использование более легких методов синхронизации 10/21/12
  • 17. Lock upgrade pthread_rwlock_rdlock(&lock); if (v > shared) { pthread_rwlock_unlock(&lock); return; } pthread_rwlock_unlock(&lock); pthread_rwlock_wrlock(&lock); if (v > shared) { pthread_rwlock_unlock(&lock); return; } shared = v; pthread_rwlock_unlock(&lock); 10/21/12
  • 19. Типы кэшей ● Data cache (L1d, L2d) ● Instruction cache (L1i, L2i) ● TLB – значения преобразований виртуальных адресов страниц в физические (L1, L2) ● L3 часто бывает смешанного типа 10/21/12
  • 20. getconf # getconf LEVEL1_DCACHE_SIZE 65536 # getconf LEVEL1_DCACHE_LINESIZE 64 # grep -c processor /proc/cpuinfo 2 10/21/12
  • 21. Когерентность кэшей ● Непротиворечивость кэшированных данных на многопроцессорных системах ● Обеспечивается протоколом MESI (Modified, Exclusive, Shared, Invalid) ● RFO (Request For Ownership) := M → I – CPU1 пишет по адресу X: X → M – CPU2 пишет по адресу X: – CPU1: X → I – CPU2: X → M 10/21/12
  • 22. Пример: std::shared_ptr ● std::shared_ptr использует reference counter – целую переменную, разделяемую и модифицируемую всеми потоками 10/21/12
  • 23. False sharing ● MESI оперирует cacheline'ами ● RFO довольно дорогая операция ● Если две различные переменные находятся в одном cacheline, то возникает RFO 10/21/12
  • 24. Выравнивание ● Компилятор автоматически выравнивает элементы структур данных ● GCC имеет специальные атрибуты, управляющие выравниванием данных 10/21/12
  • 25. Кэш 1. Структура для хранения и быстрого поиска данных по некоторому ключу ● общая структура для хранения и поиска (дерево или хэш) ● две структуры: для индекса и для алгоритма вытеснения (обычно связный список) 2. Алгоритм вытеснения данных 3. Flush-потоки или вытеснение при записи 10/21/12
  • 26. Примеры хранилищ ● Состояния HTTP или IM сессий ● Данные о пользователях по ID или логинам ● Буфферный кэш СУБД 10/21/12
  • 27. Цена доступа ● Основное узкое место: время обращения к памяти ● По мере роста структур, данные перестают помещаться в кэши (L1d, L2d, L3d, TLB L1d/L2d etc) ● Выход их TLB (~1024 страницы) может стоить до 4х обращений к памяти вместо одного => Основные критерии к структурам данных: ● малый объем вспомогательных данных ● пространственная локальность обращений 10/21/12
  • 29. Структуры данных & page table Application Tree Page table a.1 a b a.0 c c.0 c.1 10/21/12
  • 30. Radix-tree ● Гарантированность времени доступа ● На практике использует больше всего памяти Очень медленное: на тесте равномерного распределения IPv4 адресов почти в 2 раза проигрывает хэшу с простой хэш-функцией времени и 4 раза по памяти (Linux VMM выбирает ключи для сохранения пространственной локальности) 10/21/12
  • 31. {B,T}-tree ● Хорошая пространственная локальность ● Как правило, время поиска можно считать константным для RAM-only структур данных ● Довольно дорогие вставки ● На практике все равно медленнее хэшей 10/21/12
  • 32. Бинарные деревья ● В целом, слишком много обращений к памяти ● Балнсировка может быть довольно дорогой 10/21/12
  • 33. Хэш ● Как правило, обладает лучшим средним временем доступа ● На практике использует меньше всего памяти ● Хорошая пространственная локальность: 1 случайное обращение и линейное сканирование ● Тяжело выбрать достаточно хорошую хэш-функцию (зависит от ключей и нагрузки) ● В некоторых случаях может обладать очень большим временем поиска 10/21/12
  • 34. Хэш: оптимизация (1) ● Двойное хэширование ● Определение размера на старте, как процент от доступной памяти (без динамического рехэшинга) ● Просто повысить гранулярность блокировок 10/21/12
  • 36. Алгоритмы вытеснения ● LRU (Least Recently Used): наиболее простой (O(1)), fundamental locality ● Clok: алгоритм «второй попытки» без перемещений элементов в списке (лучше concurrency) ● LRFU: модификация LFU (Least Frequently Used), но работает за линейное время, cлишком долго “помнит” историю ● CAR (Clock with Adaptive Replacement)/CART (CAR with Temporal filtering): объединяет fundamental и advanced locality, устойчив к линейному сканированию 10/21/12
  • 38. Способ вытеснения 1. Flushing-thread: ● максимальная скорость записи и чтения ● пробуждается по таймеру или при нехватке памяти 2. Во время чтения или записи: ● чтение/запись медленее ● подходит для soft-realtime ● проще алгоритм 10/21/12
  • 39. Lock-free структуры данных ● Обычно простые структуры данных (односвязные списки, переменные) ● Сущестуют сложные протоколы изменения деревьев и хэшей – достаточно дорогие из-за своей сложности ● Наиболее актуальны в условиях высокого lock contention на многопроцессорных системах ● Очень полезны в «горячих» структурах: очереди задач, аллокаторы и пр. 10/21/12
  • 40. Очердь задач ● Обычно 1 производитель, N потребителей ● Реализует только операции push() и pop() (нет сканирований по списку) ● Классический (наивный) вариант: std::queue, защищенный mutex'ом ● Может быть реализована на атомарных операциях для снижения lock contention 10/21/12
  • 41. Атомарные операции (Read-Modify-Write) unsigned long a, b = 1; b = __sync_fetch_and_add(&a, 1); mov $0x1,%edx lock xadd %rdx,(%rax) 10/21/12
  • 42. Атомарные операции (Compare-And-Swap) unsigned long val = 5; __sync_val_compare_and_swap(&val, 5, 2); mov $0x5,%eax mov $0x2,%ecx lock cmpxchg %rcx,(%rdx) 10/21/12
  • 43. Атомарные операции (стоимость) ● Реализуются через протокол cache coherency (MESI) ● Писать в одну область памяти на разных процессорах дорого, т.к. процессоры должны обмениваться сообщениями RFO Используются в shared_ptr для reference counting 10/21/12
  • 44. Lock-free очередь (список): push() push (q: pointer to fifo, cl: pointer to cell): Loop: cl->next = q->tail if CAS (&q->tail, cl->next, cl): break 10/21/12
  • 45. Lock-free очередь (список): pop() pop (q: pointer to fifo): Loop: cl = q->head next = cl->next if CAS (&q->head, cl, next): break return cl 10/21/12
  • 46. ABA problem ● Поток T1 читает значение A, ● T1 вытесняется, позволяя выполняться T2, ● T2 меняет значение A на B и обратно на A, ● T1 возобновляет работу, видит, что значение не изменилось, и продолжает… 10/21/12
  • 47. Lock-free очередь: ABA pop (q: pointer to fifo): Loop: cl = q->head next = cl->next # cl = A, next = B ------->scheduled # pop(A), pop(B), push(A) if CAS (&q->head, cl, next): # cl->head => B (вместо C) break return cl 10/21/12
  • 48. Решение ABA ● Вводятся счетчики числа pop()'ов и push()'ей для всей структуры или отдельных элементов и атомарно сравниваются ● Нужна операция CAS2 (Double CAS) для сравнения двух операндов: CMPXCHG16B на x86-64 10/21/12
  • 49. Lock-free очередь на Ring-Buffer: (0) 10/21/12
  • 50. Lock-free очередь на Ring-Buffer: (1) ● Избавляемся от мьютекса push(): while (tail_ + Q_SIZE < head_) sched_yield(); Thread 1 Thread 2 read tail_ read tail_ read head_ read head_ ------->scheduled push an element push an element 10/21/12
  • 51. Lock-free очередь на Ring-Buffer: (2) ● Резервируем место для вставки (→ одно чтение) push(): unsigned long tmp_head = __sync_fetch_and_add(&head_, 1); while (tail_ + Q_SIZE < tmp_head) sched_yield(); ptr_array_[tmp_head & Q_MASK] = x; 10/21/12
  • 52. Lock-free очередь на Ring-Buffer: (3) ● Per-thread current LH & LT push(): volatile unsigned long last_head_; volatile unsigned long last_tail_; auto min = tail_; for (size_t i = 0; i < n_consumers_; ++i) { if (thr_p_[i].tail < min) min = thr_p_[i].tail; } last_tail_ = min; 10/21/12
  • 53. Lock-free очередь на Ring-Buffer: (4) ● Чтение tail i-го потока только один раз push(): auto min = tail_; for (size_t i = 0; i < n_consumers_; ++i) { auto tmp_t = thr_p_[i].tail; if (tmp_t < min) min = tmp_t; } last_tail_ = min; 10/21/12
  • 54. Lock-free очередь на Ring-Buffer: (5) ● Не оставляем текущий tail i-го потока надолго pop(): thr_pos().tail = __sync_fetch_and_add(&tail_, 1); // …......... T *ret = ptr_array_[thr_pos().tail & Q_MASK]; thr_pos().tail = ULONG_MAX; return ret; 10/21/12
  • 55. Lock-free очередь на Ring-Buffer: (6) ● Двойная запись текущего значения tail и синхронизация с инкрементом tail_ pop(): thr_pos().tail = tail_; __sync_synchronize(); thr_pos().tail = __sync_fetch_and_add(&tail_, 1); 10/21/12
  • 56. Lock-free очередь (список vs ring-buffer) ● Ring-buffer сложнее в реализации (требуется синхронизированное передвижение указателей на tail и head для каждого из потоков) ● Список должен быть интрузивным для избежания аллокации узлов на каждой вставке ● Для списка нужно отдельно реализовать контроль числа элементов ● Локализация и выравнивание памяти - ? 10/21/12
  • 57. Lock-free очередь (ограничения) ● Работает только для очередей — сканировать такие структуры данных без блокировок нельзя ● Для очереди нужна реализация ожидания: ● usleep(1000) — помещение потока в wait queue на примерно один такт системного таймера ● sched_yield() - busy loop на перепланирование (100% CPU usage) 10/21/12
  • 58. Zero copy ● Чем больше каждое из сообщений, обрабатываемых сервером, тем актуальнее ● Решается через zero copy IO, zero copy алгоритмы и структуры данных и архитектуру сервера в целом ● Недостатки: сильная связность между IO, аллокатором памяти, управлением потоками 10/21/12
  • 59. Архитектура zero copy сервера 10/21/12
  • 60. Zero-copy ввод-вывод ● Сетевой (минуя Socket API/kernel копирования) ● Дисковый (минуя буферы программы или буферный кэш ОС) ● Не “вымывает” кэши процессоров ● Имеет накладные расходы => актуально только при работе с большими блоками данных 10/21/12
  • 62. Zero-copy Network (I)O: vmsplice()/splice() ● Только на Output, на Input memcpy() в ядре ● Сетевой стек пишет данные напрямую со страницы => перед использованием страницы снова нужно записать 2 размера буфера отправки (double-buffer write) 10/21/12
  • 63. Zero-copy Network (I)O: пример void zcp_send(int sd, const struct iovec *iov, size_t num) { pipe(pipe_); size_t data_len = 0; for (size_t i = 0; i < num; ++i) data_len += iov[i].iov_len; vmsplice(pipe_[1], iov, num, 0); for (int r; data_len; data_len -= r) r = splice(pipe_[0], NULL, sd, NULL, data_len, 0); } 10/21/12
  • 64. Splice: производительность (Тесты splice() от Jens Axboe): # ./nettest/xmit -s65536 -p1000000 127.0.0.1 5500 xmit: msg=64kb, packets=1000000 vmsplice() -> splice() usr=9259, sys=6864, real=27973 # ./nettest/xmit -s65536 -p1000000 -n 127.0.0.1 5500 xmit: msg=64kb, packets=1000000 send() usr=8762, sys=25497, real=34261 10/21/12
  • 65. Спасибо! ak@natsys-lab.com 10/21/12