SlideShare a Scribd company logo
1 of 52
Download to read offline
Распределенные системы в Одноклассниках
Олег Анастасьев
@m0nstermind
oa@ok.ru
1. Абсолютно надежная сеть
2. Мизерная сетевая задержка
3. Практически безлимитная пропускная способность
4. Полностью однородна
5. Изменение топологии сети незаметны
6. Полностью защищена
7. Управляется одним администратором
8. Транспортировка данных почти ничего не стоит
2
В Одноклассниках
1. Абсолютно надежная сеть
2. Мизерная сетевая задержка
3. Практически безлимитная пропускная способность
4. Полностью однородна
5. Изменение топологии сети незаметны
6. Полностью защищена
7. Управляется одним администратором
8. Транспортировка данных почти ничего не стоит
3
Заблуждения разработчиков распределенных систем
https://en.wikipedia.org/wiki/Fallacies_of_distributed_computing
[Peter Deutsch, 1994; James Gosling 1997]
4
4
ЦОД
150
типов
сервисов
8000
серверов
В Одноклассниках
5
инженеры
сетевики
админы
разработчики
6
Страница друзей
1. Получить список друзей
2. Применить фильтр
3. Подавить ЧС
4. Получить профили
5. Отсортировать
6. Получить наклейки
7. Посчитать счетчики
7
Простой способ
SELECT * FROM friendlist f, users u
JOIN ON f.vertexId=u.userId

WHERE u.userId=? AND f.kind=?
AND NOT EXISTS( SELECT * FROM blacklist …)
…
• Дружбы
• 12 млрд. связей, 300GB
• 500 000 запросов в сек
8
Простой способ не работает
• Профили пользователей
• > 350 млн. штук,
• 3 500 000 запросов в сек, 50 Gbit
9
Работает так
web frontend API frontend
app server
one-graph user-cache black-list
(микро) сервисы
10
Анатомия (микро) сервиса
Ремотный интерфейс
Логика , Кеши
[ Локальное хранилище ]
1 JVM
11
Анатомия (микро) сервиса
Ремотный интерфейс
https://github.com/odnoklassniki/one-nio
interface GraphService extends RemoteService {
@RemoteMethod
long[] getFriendsByFilter(@Partition long vertexId, long relationMask);
}
interface UserCache {

@RemoteMethod
User getUserById(long id);
}
12
App Server code
https://github.com/odnoklassniki/one-nio
long []friendsIds = graphService.getFriendsByFilter(userId, mask);
List<User> users = new ArrayList<>(friendsIds.length);
for (long id : friendsIds) {
if(blackList.isAllowed(userId,id)) {
users.add(userCache.getUserById(id));
}
}
…
return users;
• По таким значениям партиционируем
• У сервиса есть стратегия
• long id -> int partitionId(id) -> node1,node2,…
• Стратегии разные
• Cassandra ring, Voldemort partitions
• или…
13
interface GraphService extends RemoteService {
@RemoteMethod
long[] getFriendsByFilter(@Partition long vertexId, long relationMask);
}
14
Взвешенный квадрат
p = id % 16
p = 0
p = 15
p = 1
N01 N02 N03 . . . 019 020
W=1
W=100
N11
node = wrr(p)
SET
15
Проблема в коде
https://github.com/odnoklassniki/one-nio
long []friendsIds = graphService.getFriendsByFilter(userId, mask);
List<User> users = new ArrayList<>(friendsIds.length);
for (long id : friendsIds) {
if(blackList.isAllowed(userId,id)) {
users.add(userCache.getUserById(id));
}
}
…
return users;
16
Цена сетевого запроса
0.1-0.3 ms
0.7-1.0 ms
Другой ЦОД
* цена сильно зависит от конкретной инфраструктуры и фреймворков.
задержка 

= 1.0ms * 2 reqs * 200 друзей

= 400 ms

10k друзей задержка = 20 seconds
17
Решение: пакетные запросы
public interface UserCache {

@RemoteMethod( split = true )
Collection<User> getUsersByIds(long[] keys);
}
long []friendsIds = graphService.getFriendsByFilter(userId, mask);


friendsIds = blackList.filterAllowed(userId, friendsIds );
List<User> users = userCache.getUsersByIds(friendsIds);
…
return users;
18
split & merge
split ( ids by p )
-> ids0, ids1
p = 0
p = 1
N01 N02 N03 . . .
N11
ids0
ids1
users = merge (users0, users1)
19
1. Пропажа клиента
2. Пропажа сервера
3. Потеря исходящего сообщения
4. Потеря входящего сообщения
5. Таймаут сервера
6. Неправильный ответ
7. Произвольный отказ
Что может пойти не так ?
Отказы
Распределенные системы в Одноклассниках
• Отказы невозможно предотвратить, только скрыть
• Отказ произойдет обязательно.
• Ключ к скрытию отказов - избыточность:
• Информации (коды защиты от ошибок)
• Железа (резервирование, реплики, дублирующие схемы)
• Времени (транзакции, retries)
21
Что делать с отказами ?
22
Что сервер сделал ?
Сдаваться
нельзя ,
повторить !
Сдаваться ,
нельзя
повторить !
? ?
Добавить друга
• Со стороны клиента - неизвестно
• Что клиент может сделать ?
• Не давать никаких гарантий
• Никогда не повторять запрос. Максимум 1 раз. At Most Once.
• Всегда повторять запрос. По меньшей мере 1 раз. At Least Once.
23
Был ли друг добавлен ?
1. Транзакция в ACID хранилище
• есть мастер, успех однозначен (или проходит или нет)
• возможен атомарный откат
2. Обновление информации в кешах
• много реплик, мастера нет
• атомарного отката нет: возможны частичные отказы
24
Добавляем друга
• Операция применима повторно с тем же результатом
• напр: чтение, Set.add(), Math.max(x,y)
• Упорядоченное Атомарное изменение с контролем дубликата

25
Идемпотентность
Только для Идемпотентных операций

можно применять стратегию

“всегда повторять попытку”
https://ru.wikipedia.org/wiki/Идемпотентность
26
Идемпотентность в ACID хранилище
Подружиться
ждем; timeout
Подружиться
Подружились!
Уже друзья ?
Нет, делаем изменения!
Уже друзья ?
Да, ничего не делаем !
27
Идемпотентность через секвенсинг
Подружиться (ОпИД)
Подружились!
УжеДелали (ОпИд) ?
Нет, делаем изменения!
Выписать ОпИД
Примеры ОпИД:
• OpId+=1
• OpId=currentTimeMillis()
• OpId=TimeUUID
http://johannburkard.de/software/uuid/
1. Транзакция в ACID хранилище
• есть мастер, успех однозначен (или проходит или нет)
• возможен атомарный откат
2. Обновление информации в кешах
• много реплик, мастера нет
• атомарного отката нет: возможны частичные отказы
28
Добавляем друга
29
Нотификация реплик кешей
add(Friend)
p = 0 N01 N02 N03 . . .
Но без повтора данные реплики рассинхронизируются
Повторять бессмысленно
• Процесс синхронизации данных
• Непрерывно читает изменения из транзакционного хранилища



SELECT * FROM users WHERE modified > ?
• Применяет их в память кеша
• Загружает изменения при старте ноды
• Повтор - ненужен.

30
Синхронизируем кеш через БД
31
Смерть через таймаут
STW GC
Подружиться
ждем; timeout
конец 

пула потоков
1. Клиенты перестают обращаться к серверу
После Х непрерывных отказов за последнюю секунду
2. Клиенты мониторят доступность сервера
В фоне, раз в минуту
3. И возвращают его в ротацию
32
Вывод из ротации
33
Смерть через торможение
Avg = 1.5ms
Max = 1.5c
24 cpu cores
Cap = 24,000 ops
Cтавить таймаут = 2.4ms ?
Выводить из ротации если среднее > 2.4ms ?
Avg = 24ms
Max = 1.5c
24 cpu cores
Cap = 1,000 ops
10,000 ops
34
Спекулятивный повтор
Идемпотентная Оп
wait; timeout
Повторный запрос
Результат операции
• Применим не всегда
• Идемпотентные операции

дополнительная нагрузка, 

трафик
• Балансируем спекуляцию: всегда, >99p, >avg
35
Спекулятивный повтор
• Лучше
• Задержки 99p, средние
• Стабильность системы
Классы, задержка 99p, наносекунды.

без спекулятивного повтора (желтый)

и с ним (красный)
^^^ пики до 1 сек ^^^
Больше отказов !
Распределенные системы в Одноклассниках
• Чрезмерная нагрузка
• Чрезмерная паранойя
• Баги
• Люди
• Масштабные аварии
37
Отказ всех реплик сервиса
38
Использовать другие источники,

деградация консистентности
Использовать неполные данные,
частичная деградация функции

Отключать функцию полностью
Деградировать!
39
Код
interface UserCache {

@RemoteMethod
Distributed<Collection<User>> getUsersByIds(long[] keys);
}
interface Distributed<D>
{
boolean isInconsistency();
D getData();
}
class UserCacheStub implements UserCache {


Distributed<Collection<User>> getUsersByIds(long[] keys) {
return Distributed.inconsistent();
}
}
Тестирование отказов
Распределенные системы в Одноклассниках
41
Свой продукт
“Стандартные” продукты - особенно !
“Админские” маневры
Что тестировать ?
• Что делает:
• Определяет соединения с фронта на сервис
• Отрубает соединения (iptables drop)
• Запускает авто тесты
• Что проверяем
• Что ничего не валится, показываются красивые заглушки
• Сервер стартует
42
Свой продукт: “Горилла”
• Тестовый стенд с синтетический нагрузкой ?
- Топология сети не неизменна
- Сложно воспроизвести профиль нагрузки.
• На продакшене!
• Но чтобы никто не заметил
• Проверяем сценарии отказов и восстановления
43
Как тестировать стандартные решения ?
44
Зеркало
UserCacheProxy
UserCacheImpl UserCacheNew
primary mirror
1. Вызываем primary
2. В отдельном тред пуле mirror. Сравниваем.
3. На основании конфигурации отключаем, переключаем
one-conf
Диагностика
Распределенные системы в Одноклассниках
• Быстрое определение существования аварии
• Локализация проблемы
• Своевременное предупреждение аварий
46
Зачем
• Zabbix
• Cacti
• Операционные метрики
• Имена вызванных операций, напр. “Graph.getFriendsByFilter”
• Количество вызовов, успешность
• Длительность вызовов
47
Авария есть или будет ?
• Оперативную статистику и тренды
• Агрегированное число вызовов и ошибок
• Агрегации задержек
• Среднее, Макс
• Перцентили 50,75,98,99,99.9
48
Что показывают графики
49
Интересные графики
50
Авто поиск аномалий
• Возможностей отказов в распределенных системах безграничны
• Отказы маскируются за счет информации, времени, железа
• При немаскируемых отказах - деградируем !
• Отказы надо тестировать наравне с функционалом
• Отказы нужно диагностировать и предупреждать на проде
51
Краткое содержание предыдущих слайдов
52 Распределенные системы в Одноклассниках, JBreak 2016
slideshare.net/m0nstermind
https://v.ok.ru/publishing.html
http://www.cs.yale.edu/homes/aspnes/classes/465/notes.pdf
Notes on Theory of Distributed Systems CS 465/565: 

Spring 2014
James Aspnes
Тут можно узнать больше:

More Related Content

What's hot

За гранью NoSQL: NewSQL на Cassandra
За гранью NoSQL: NewSQL на CassandraЗа гранью NoSQL: NewSQL на Cassandra
За гранью NoSQL: NewSQL на Cassandraodnoklassniki.ru
 
андрей паньгин
андрей паньгинандрей паньгин
андрей паньгинkuchinskaya
 
MySQL 5.7 - NoSQL - JSON, Protocol X, Document Store / Петр Зайцев (Percona)
MySQL 5.7 - NoSQL - JSON, Protocol X, Document Store / Петр Зайцев (Percona)MySQL 5.7 - NoSQL - JSON, Protocol X, Document Store / Петр Зайцев (Percona)
MySQL 5.7 - NoSQL - JSON, Protocol X, Document Store / Петр Зайцев (Percona)Ontico
 
Multithreading in java past and actual
Multithreading in java past and actualMultithreading in java past and actual
Multithreading in java past and actualYevgen Levik
 
Чему мы научились разрабатывая микросервисы?
Чему мы научились разрабатывая микросервисы?Чему мы научились разрабатывая микросервисы?
Чему мы научились разрабатывая микросервисы?Vadim Madison
 
Евгений Потапов (Сумма Айти)
Евгений Потапов (Сумма Айти)Евгений Потапов (Сумма Айти)
Евгений Потапов (Сумма Айти)Ontico
 
Жизнь проекта на production советы по эксплуатации / Николай Сивко (okmeter.io)
Жизнь проекта на production советы по эксплуатации / Николай Сивко (okmeter.io)Жизнь проекта на production советы по эксплуатации / Николай Сивко (okmeter.io)
Жизнь проекта на production советы по эксплуатации / Николай Сивко (okmeter.io)Ontico
 
Как сделать ваш JavaScript быстрее
Как сделать ваш JavaScript быстрееКак сделать ваш JavaScript быстрее
Как сделать ваш JavaScript быстрееRoman Dvornov
 
Кластеры баз данных делаем сложные вещи просто / Андрей Тихонов (Avito)
Кластеры баз данных делаем сложные вещи просто / Андрей Тихонов (Avito)Кластеры баз данных делаем сложные вещи просто / Андрей Тихонов (Avito)
Кластеры баз данных делаем сложные вещи просто / Андрей Тихонов (Avito)Ontico
 
Денис Иванов
Денис ИвановДенис Иванов
Денис ИвановCodeFest
 
Оптимизация работы с данными в мобильных приложениях / Святослав Иванов, Артё...
Оптимизация работы с данными в мобильных приложениях / Святослав Иванов, Артё...Оптимизация работы с данными в мобильных приложениях / Святослав Иванов, Артё...
Оптимизация работы с данными в мобильных приложениях / Святослав Иванов, Артё...Ontico
 
Производительность запросов в PostgreSQL - шаг за шагом / Илья Космодемьянски...
Производительность запросов в PostgreSQL - шаг за шагом / Илья Космодемьянски...Производительность запросов в PostgreSQL - шаг за шагом / Илья Космодемьянски...
Производительность запросов в PostgreSQL - шаг за шагом / Илья Космодемьянски...Ontico
 
Метапрограммирование с примерами на JavaScript
Метапрограммирование с примерами на JavaScriptМетапрограммирование с примерами на JavaScript
Метапрограммирование с примерами на JavaScriptTimur Shemsedinov
 
Unsafe: to be or to be removed?
Unsafe: to be or to be removed?Unsafe: to be or to be removed?
Unsafe: to be or to be removed?Alexey Fyodorov
 
Класс!ная Cassandra
Класс!ная CassandraКласс!ная Cassandra
Класс!ная Cassandraodnoklassniki.ru
 

What's hot (20)

За гранью NoSQL: NewSQL на Cassandra
За гранью NoSQL: NewSQL на CassandraЗа гранью NoSQL: NewSQL на Cassandra
За гранью NoSQL: NewSQL на Cassandra
 
андрей паньгин
андрей паньгинандрей паньгин
андрей паньгин
 
MySQL 5.7 - NoSQL - JSON, Protocol X, Document Store / Петр Зайцев (Percona)
MySQL 5.7 - NoSQL - JSON, Protocol X, Document Store / Петр Зайцев (Percona)MySQL 5.7 - NoSQL - JSON, Protocol X, Document Store / Петр Зайцев (Percona)
MySQL 5.7 - NoSQL - JSON, Protocol X, Document Store / Петр Зайцев (Percona)
 
Multithreading in java past and actual
Multithreading in java past and actualMultithreading in java past and actual
Multithreading in java past and actual
 
Чему мы научились разрабатывая микросервисы?
Чему мы научились разрабатывая микросервисы?Чему мы научились разрабатывая микросервисы?
Чему мы научились разрабатывая микросервисы?
 
Java threads - part 2
Java threads - part 2Java threads - part 2
Java threads - part 2
 
Java threads - part 3
Java threads - part 3Java threads - part 3
Java threads - part 3
 
Евгений Потапов (Сумма Айти)
Евгений Потапов (Сумма Айти)Евгений Потапов (Сумма Айти)
Евгений Потапов (Сумма Айти)
 
Java threads - part 1
Java threads - part 1Java threads - part 1
Java threads - part 1
 
Java 8. Thread pools
Java 8. Thread poolsJava 8. Thread pools
Java 8. Thread pools
 
Жизнь проекта на production советы по эксплуатации / Николай Сивко (okmeter.io)
Жизнь проекта на production советы по эксплуатации / Николай Сивко (okmeter.io)Жизнь проекта на production советы по эксплуатации / Николай Сивко (okmeter.io)
Жизнь проекта на production советы по эксплуатации / Николай Сивко (okmeter.io)
 
Mysql vs postgresql
Mysql vs postgresqlMysql vs postgresql
Mysql vs postgresql
 
Как сделать ваш JavaScript быстрее
Как сделать ваш JavaScript быстрееКак сделать ваш JavaScript быстрее
Как сделать ваш JavaScript быстрее
 
Кластеры баз данных делаем сложные вещи просто / Андрей Тихонов (Avito)
Кластеры баз данных делаем сложные вещи просто / Андрей Тихонов (Avito)Кластеры баз данных делаем сложные вещи просто / Андрей Тихонов (Avito)
Кластеры баз данных делаем сложные вещи просто / Андрей Тихонов (Avito)
 
Денис Иванов
Денис ИвановДенис Иванов
Денис Иванов
 
Оптимизация работы с данными в мобильных приложениях / Святослав Иванов, Артё...
Оптимизация работы с данными в мобильных приложениях / Святослав Иванов, Артё...Оптимизация работы с данными в мобильных приложениях / Святослав Иванов, Артё...
Оптимизация работы с данными в мобильных приложениях / Святослав Иванов, Артё...
 
Производительность запросов в PostgreSQL - шаг за шагом / Илья Космодемьянски...
Производительность запросов в PostgreSQL - шаг за шагом / Илья Космодемьянски...Производительность запросов в PostgreSQL - шаг за шагом / Илья Космодемьянски...
Производительность запросов в PostgreSQL - шаг за шагом / Илья Космодемьянски...
 
Метапрограммирование с примерами на JavaScript
Метапрограммирование с примерами на JavaScriptМетапрограммирование с примерами на JavaScript
Метапрограммирование с примерами на JavaScript
 
Unsafe: to be or to be removed?
Unsafe: to be or to be removed?Unsafe: to be or to be removed?
Unsafe: to be or to be removed?
 
Класс!ная Cassandra
Класс!ная CassandraКласс!ная Cassandra
Класс!ная Cassandra
 

Similar to Распределенные системы в Одноклассниках

PostgreSQL performance recipes
PostgreSQL performance recipesPostgreSQL performance recipes
PostgreSQL performance recipesAlexey Ermakov
 
hl++ Rubtsov
hl++ Rubtsovhl++ Rubtsov
hl++ RubtsovOntico
 
Java 9: what is there beyond modularization
Java 9: what is there beyond modularizationJava 9: what is there beyond modularization
Java 9: what is there beyond modularizationIvan Krylov
 
Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...
Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...
Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...Ontico
 
Михаил Давыдов "Масштабируемые JavaScript-приложения"
Михаил Давыдов "Масштабируемые JavaScript-приложения"Михаил Давыдов "Масштабируемые JavaScript-приложения"
Михаил Давыдов "Масштабируемые JavaScript-приложения"Yandex
 
Тестирование серверной конфигурации
Тестирование серверной конфигурацииТестирование серверной конфигурации
Тестирование серверной конфигурацииTimur Batyrshin
 
QA MeetUp - Тимур Батыршин: "Тестирование серверной конфигурации"
QA MeetUp - Тимур Батыршин: "Тестирование серверной конфигурации"QA MeetUp - Тимур Батыршин: "Тестирование серверной конфигурации"
QA MeetUp - Тимур Батыршин: "Тестирование серверной конфигурации"Provectus
 
Тестируем код с Visual Studio 2012 - XP Days Ukraine 2012
Тестируем код с Visual Studio 2012 - XP Days Ukraine 2012Тестируем код с Visual Studio 2012 - XP Days Ukraine 2012
Тестируем код с Visual Studio 2012 - XP Days Ukraine 2012Dmytro Mindra
 
So Your WAF Needs a Parser
So Your WAF Needs a ParserSo Your WAF Needs a Parser
So Your WAF Needs a Parseryalegko
 
микроСЕРВИСЫ: огонь, вода и медные трубы
микроСЕРВИСЫ: огонь, вода и медные трубымикроСЕРВИСЫ: огонь, вода и медные трубы
микроСЕРВИСЫ: огонь, вода и медные трубыAleksandr Tarasov
 
Java осень 2014 занятие 1
Java осень 2014 занятие 1Java осень 2014 занятие 1
Java осень 2014 занятие 1Technopark
 
Чему мы научились, разрабатывая микросервисы / Вадим Мадисон (RuTube)
Чему мы научились, разрабатывая микросервисы / Вадим Мадисон (RuTube)Чему мы научились, разрабатывая микросервисы / Вадим Мадисон (RuTube)
Чему мы научились, разрабатывая микросервисы / Вадим Мадисон (RuTube)Ontico
 
"Тестирование распределенных систем" Сатарин Андрей, Яндекс
"Тестирование распределенных систем" Сатарин Андрей, Яндекс"Тестирование распределенных систем" Сатарин Андрей, Яндекс
"Тестирование распределенных систем" Сатарин Андрей, Яндексit-people
 
Испытание поединком PostgreSQL vs MySQL / Александр Чистяков, Даниил Подольский
Испытание поединком PostgreSQL vs MySQL / Александр Чистяков, Даниил Подольский Испытание поединком PostgreSQL vs MySQL / Александр Чистяков, Даниил Подольский
Испытание поединком PostgreSQL vs MySQL / Александр Чистяков, Даниил Подольский Ontico
 
Тестирование программных фильтров безопасности
Тестирование программных фильтров безопасностиТестирование программных фильтров безопасности
Тестирование программных фильтров безопасностиZestranec
 
Путь от монолита на PHP к микросервисам на Scala / Денис Иванов (2GIS)
Путь от монолита на PHP к микросервисам на Scala  / Денис Иванов (2GIS)Путь от монолита на PHP к микросервисам на Scala  / Денис Иванов (2GIS)
Путь от монолита на PHP к микросервисам на Scala / Денис Иванов (2GIS)Ontico
 
Михаил Давыдов "Масштабируемые JavaScript-приложения"
Михаил Давыдов "Масштабируемые JavaScript-приложения"Михаил Давыдов "Масштабируемые JavaScript-приложения"
Михаил Давыдов "Масштабируемые JavaScript-приложения"Yandex
 
Jbreak 2016: Твой личный Spring Boot Starter
Jbreak 2016: Твой личный Spring Boot StarterJbreak 2016: Твой личный Spring Boot Starter
Jbreak 2016: Твой личный Spring Boot StarterAleksandr Tarasov
 
Java весна 2013 лекция 9
Java весна 2013 лекция 9Java весна 2013 лекция 9
Java весна 2013 лекция 9Technopark
 
Java осень 2014 занятие 5
Java осень 2014 занятие 5Java осень 2014 занятие 5
Java осень 2014 занятие 5Technopark
 

Similar to Распределенные системы в Одноклассниках (20)

PostgreSQL performance recipes
PostgreSQL performance recipesPostgreSQL performance recipes
PostgreSQL performance recipes
 
hl++ Rubtsov
hl++ Rubtsovhl++ Rubtsov
hl++ Rubtsov
 
Java 9: what is there beyond modularization
Java 9: what is there beyond modularizationJava 9: what is there beyond modularization
Java 9: what is there beyond modularization
 
Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...
Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...
Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...
 
Михаил Давыдов "Масштабируемые JavaScript-приложения"
Михаил Давыдов "Масштабируемые JavaScript-приложения"Михаил Давыдов "Масштабируемые JavaScript-приложения"
Михаил Давыдов "Масштабируемые JavaScript-приложения"
 
Тестирование серверной конфигурации
Тестирование серверной конфигурацииТестирование серверной конфигурации
Тестирование серверной конфигурации
 
QA MeetUp - Тимур Батыршин: "Тестирование серверной конфигурации"
QA MeetUp - Тимур Батыршин: "Тестирование серверной конфигурации"QA MeetUp - Тимур Батыршин: "Тестирование серверной конфигурации"
QA MeetUp - Тимур Батыршин: "Тестирование серверной конфигурации"
 
Тестируем код с Visual Studio 2012 - XP Days Ukraine 2012
Тестируем код с Visual Studio 2012 - XP Days Ukraine 2012Тестируем код с Visual Studio 2012 - XP Days Ukraine 2012
Тестируем код с Visual Studio 2012 - XP Days Ukraine 2012
 
So Your WAF Needs a Parser
So Your WAF Needs a ParserSo Your WAF Needs a Parser
So Your WAF Needs a Parser
 
микроСЕРВИСЫ: огонь, вода и медные трубы
микроСЕРВИСЫ: огонь, вода и медные трубымикроСЕРВИСЫ: огонь, вода и медные трубы
микроСЕРВИСЫ: огонь, вода и медные трубы
 
Java осень 2014 занятие 1
Java осень 2014 занятие 1Java осень 2014 занятие 1
Java осень 2014 занятие 1
 
Чему мы научились, разрабатывая микросервисы / Вадим Мадисон (RuTube)
Чему мы научились, разрабатывая микросервисы / Вадим Мадисон (RuTube)Чему мы научились, разрабатывая микросервисы / Вадим Мадисон (RuTube)
Чему мы научились, разрабатывая микросервисы / Вадим Мадисон (RuTube)
 
"Тестирование распределенных систем" Сатарин Андрей, Яндекс
"Тестирование распределенных систем" Сатарин Андрей, Яндекс"Тестирование распределенных систем" Сатарин Андрей, Яндекс
"Тестирование распределенных систем" Сатарин Андрей, Яндекс
 
Испытание поединком PostgreSQL vs MySQL / Александр Чистяков, Даниил Подольский
Испытание поединком PostgreSQL vs MySQL / Александр Чистяков, Даниил Подольский Испытание поединком PostgreSQL vs MySQL / Александр Чистяков, Даниил Подольский
Испытание поединком PostgreSQL vs MySQL / Александр Чистяков, Даниил Подольский
 
Тестирование программных фильтров безопасности
Тестирование программных фильтров безопасностиТестирование программных фильтров безопасности
Тестирование программных фильтров безопасности
 
Путь от монолита на PHP к микросервисам на Scala / Денис Иванов (2GIS)
Путь от монолита на PHP к микросервисам на Scala  / Денис Иванов (2GIS)Путь от монолита на PHP к микросервисам на Scala  / Денис Иванов (2GIS)
Путь от монолита на PHP к микросервисам на Scala / Денис Иванов (2GIS)
 
Михаил Давыдов "Масштабируемые JavaScript-приложения"
Михаил Давыдов "Масштабируемые JavaScript-приложения"Михаил Давыдов "Масштабируемые JavaScript-приложения"
Михаил Давыдов "Масштабируемые JavaScript-приложения"
 
Jbreak 2016: Твой личный Spring Boot Starter
Jbreak 2016: Твой личный Spring Boot StarterJbreak 2016: Твой личный Spring Boot Starter
Jbreak 2016: Твой личный Spring Boot Starter
 
Java весна 2013 лекция 9
Java весна 2013 лекция 9Java весна 2013 лекция 9
Java весна 2013 лекция 9
 
Java осень 2014 занятие 5
Java осень 2014 занятие 5Java осень 2014 занятие 5
Java осень 2014 занятие 5
 

More from odnoklassniki.ru

Distributed systems at ok.ru #rigadevday
Distributed systems at ok.ru #rigadevdayDistributed systems at ok.ru #rigadevday
Distributed systems at ok.ru #rigadevdayodnoklassniki.ru
 
Тестирование аварий. Андрей Губа. Highload++ 2015
Тестирование аварий. Андрей Губа. Highload++ 2015Тестирование аварий. Андрей Губа. Highload++ 2015
Тестирование аварий. Андрей Губа. Highload++ 2015odnoklassniki.ru
 
Тюним память и сетевой стек в Linux: история перевода высоконагруженных серве...
Тюним память и сетевой стек в Linux: история перевода высоконагруженных серве...Тюним память и сетевой стек в Linux: история перевода высоконагруженных серве...
Тюним память и сетевой стек в Linux: история перевода высоконагруженных серве...odnoklassniki.ru
 
Add a bit of ACID to Cassandra. Cassandra Summit EU 2014
Add a bit of ACID to Cassandra. Cassandra Summit EU 2014Add a bit of ACID to Cassandra. Cassandra Summit EU 2014
Add a bit of ACID to Cassandra. Cassandra Summit EU 2014odnoklassniki.ru
 
Кадры решают все, или стриминг видео в «Одноклассниках». Александр Тоболь
Кадры решают все, или стриминг видео в «Одноклассниках». Александр ТобольКадры решают все, или стриминг видео в «Одноклассниках». Александр Тоболь
Кадры решают все, или стриминг видео в «Одноклассниках». Александр Тобольodnoklassniki.ru
 
Платформа для видео сроком в квартал. Александр Тоболь.
Платформа для видео сроком в квартал. Александр Тоболь.Платформа для видео сроком в квартал. Александр Тоболь.
Платформа для видео сроком в квартал. Александр Тоболь.odnoklassniki.ru
 
Франкенштейнизация Voldemort или key-value данные в Одноклассниках. Роман Ан...
Франкенштейнизация Voldemort или key-value данные в Одноклассниках. Роман Ан...Франкенштейнизация Voldemort или key-value данные в Одноклассниках. Роман Ан...
Франкенштейнизация Voldemort или key-value данные в Одноклассниках. Роман Ан...odnoklassniki.ru
 
Аварийный дамп – чёрный ящик упавшей JVM. Андрей Паньгин
Аварийный дамп – чёрный ящик упавшей JVM. Андрей ПаньгинАварийный дамп – чёрный ящик упавшей JVM. Андрей Паньгин
Аварийный дамп – чёрный ящик упавшей JVM. Андрей Паньгинodnoklassniki.ru
 
Being closer to Cassandra by Oleg Anastasyev. Talk at Cassandra Summit EU 2013
Being closer to Cassandra by Oleg Anastasyev. Talk at Cassandra Summit EU 2013Being closer to Cassandra by Oleg Anastasyev. Talk at Cassandra Summit EU 2013
Being closer to Cassandra by Oleg Anastasyev. Talk at Cassandra Summit EU 2013odnoklassniki.ru
 
Управление тысячами серверов в Одноклассниках. Алексей Чудов.
Управление тысячами серверов в Одноклассниках. Алексей Чудов.Управление тысячами серверов в Одноклассниках. Алексей Чудов.
Управление тысячами серверов в Одноклассниках. Алексей Чудов.odnoklassniki.ru
 
Java Runtime: повседневные обязанности JVM
Java Runtime: повседневные обязанности JVMJava Runtime: повседневные обязанности JVM
Java Runtime: повседневные обязанности JVModnoklassniki.ru
 
Cистема внутренней статистики Odnoklassniki.ru
Cистема внутренней статистики Odnoklassniki.ruCистема внутренней статистики Odnoklassniki.ru
Cистема внутренней статистики Odnoklassniki.ruodnoklassniki.ru
 
Как, используя Lucene, построить высоконагруженную систему поиска разнородных...
Как, используя Lucene, построить высоконагруженную систему поиска разнородных...Как, используя Lucene, построить высоконагруженную систему поиска разнородных...
Как, используя Lucene, построить высоконагруженную систему поиска разнородных...odnoklassniki.ru
 

More from odnoklassniki.ru (13)

Distributed systems at ok.ru #rigadevday
Distributed systems at ok.ru #rigadevdayDistributed systems at ok.ru #rigadevday
Distributed systems at ok.ru #rigadevday
 
Тестирование аварий. Андрей Губа. Highload++ 2015
Тестирование аварий. Андрей Губа. Highload++ 2015Тестирование аварий. Андрей Губа. Highload++ 2015
Тестирование аварий. Андрей Губа. Highload++ 2015
 
Тюним память и сетевой стек в Linux: история перевода высоконагруженных серве...
Тюним память и сетевой стек в Linux: история перевода высоконагруженных серве...Тюним память и сетевой стек в Linux: история перевода высоконагруженных серве...
Тюним память и сетевой стек в Linux: история перевода высоконагруженных серве...
 
Add a bit of ACID to Cassandra. Cassandra Summit EU 2014
Add a bit of ACID to Cassandra. Cassandra Summit EU 2014Add a bit of ACID to Cassandra. Cassandra Summit EU 2014
Add a bit of ACID to Cassandra. Cassandra Summit EU 2014
 
Кадры решают все, или стриминг видео в «Одноклассниках». Александр Тоболь
Кадры решают все, или стриминг видео в «Одноклассниках». Александр ТобольКадры решают все, или стриминг видео в «Одноклассниках». Александр Тоболь
Кадры решают все, или стриминг видео в «Одноклассниках». Александр Тоболь
 
Платформа для видео сроком в квартал. Александр Тоболь.
Платформа для видео сроком в квартал. Александр Тоболь.Платформа для видео сроком в квартал. Александр Тоболь.
Платформа для видео сроком в квартал. Александр Тоболь.
 
Франкенштейнизация Voldemort или key-value данные в Одноклассниках. Роман Ан...
Франкенштейнизация Voldemort или key-value данные в Одноклассниках. Роман Ан...Франкенштейнизация Voldemort или key-value данные в Одноклассниках. Роман Ан...
Франкенштейнизация Voldemort или key-value данные в Одноклассниках. Роман Ан...
 
Аварийный дамп – чёрный ящик упавшей JVM. Андрей Паньгин
Аварийный дамп – чёрный ящик упавшей JVM. Андрей ПаньгинАварийный дамп – чёрный ящик упавшей JVM. Андрей Паньгин
Аварийный дамп – чёрный ящик упавшей JVM. Андрей Паньгин
 
Being closer to Cassandra by Oleg Anastasyev. Talk at Cassandra Summit EU 2013
Being closer to Cassandra by Oleg Anastasyev. Talk at Cassandra Summit EU 2013Being closer to Cassandra by Oleg Anastasyev. Talk at Cassandra Summit EU 2013
Being closer to Cassandra by Oleg Anastasyev. Talk at Cassandra Summit EU 2013
 
Управление тысячами серверов в Одноклассниках. Алексей Чудов.
Управление тысячами серверов в Одноклассниках. Алексей Чудов.Управление тысячами серверов в Одноклассниках. Алексей Чудов.
Управление тысячами серверов в Одноклассниках. Алексей Чудов.
 
Java Runtime: повседневные обязанности JVM
Java Runtime: повседневные обязанности JVMJava Runtime: повседневные обязанности JVM
Java Runtime: повседневные обязанности JVM
 
Cистема внутренней статистики Odnoklassniki.ru
Cистема внутренней статистики Odnoklassniki.ruCистема внутренней статистики Odnoklassniki.ru
Cистема внутренней статистики Odnoklassniki.ru
 
Как, используя Lucene, построить высоконагруженную систему поиска разнородных...
Как, используя Lucene, построить высоконагруженную систему поиска разнородных...Как, используя Lucene, построить высоконагруженную систему поиска разнородных...
Как, используя Lucene, построить высоконагруженную систему поиска разнородных...
 

Распределенные системы в Одноклассниках

  • 1. Распределенные системы в Одноклассниках Олег Анастасьев @m0nstermind oa@ok.ru
  • 2. 1. Абсолютно надежная сеть 2. Мизерная сетевая задержка 3. Практически безлимитная пропускная способность 4. Полностью однородна 5. Изменение топологии сети незаметны 6. Полностью защищена 7. Управляется одним администратором 8. Транспортировка данных почти ничего не стоит 2 В Одноклассниках
  • 3. 1. Абсолютно надежная сеть 2. Мизерная сетевая задержка 3. Практически безлимитная пропускная способность 4. Полностью однородна 5. Изменение топологии сети незаметны 6. Полностью защищена 7. Управляется одним администратором 8. Транспортировка данных почти ничего не стоит 3 Заблуждения разработчиков распределенных систем https://en.wikipedia.org/wiki/Fallacies_of_distributed_computing [Peter Deutsch, 1994; James Gosling 1997]
  • 6. 6 Страница друзей 1. Получить список друзей 2. Применить фильтр 3. Подавить ЧС 4. Получить профили 5. Отсортировать 6. Получить наклейки 7. Посчитать счетчики
  • 7. 7 Простой способ SELECT * FROM friendlist f, users u JOIN ON f.vertexId=u.userId
 WHERE u.userId=? AND f.kind=? AND NOT EXISTS( SELECT * FROM blacklist …) …
  • 8. • Дружбы • 12 млрд. связей, 300GB • 500 000 запросов в сек 8 Простой способ не работает • Профили пользователей • > 350 млн. штук, • 3 500 000 запросов в сек, 50 Gbit
  • 9. 9 Работает так web frontend API frontend app server one-graph user-cache black-list (микро) сервисы
  • 10. 10 Анатомия (микро) сервиса Ремотный интерфейс Логика , Кеши [ Локальное хранилище ] 1 JVM
  • 11. 11 Анатомия (микро) сервиса Ремотный интерфейс https://github.com/odnoklassniki/one-nio interface GraphService extends RemoteService { @RemoteMethod long[] getFriendsByFilter(@Partition long vertexId, long relationMask); } interface UserCache {
 @RemoteMethod User getUserById(long id); }
  • 12. 12 App Server code https://github.com/odnoklassniki/one-nio long []friendsIds = graphService.getFriendsByFilter(userId, mask); List<User> users = new ArrayList<>(friendsIds.length); for (long id : friendsIds) { if(blackList.isAllowed(userId,id)) { users.add(userCache.getUserById(id)); } } … return users;
  • 13. • По таким значениям партиционируем • У сервиса есть стратегия • long id -> int partitionId(id) -> node1,node2,… • Стратегии разные • Cassandra ring, Voldemort partitions • или… 13 interface GraphService extends RemoteService { @RemoteMethod long[] getFriendsByFilter(@Partition long vertexId, long relationMask); }
  • 14. 14 Взвешенный квадрат p = id % 16 p = 0 p = 15 p = 1 N01 N02 N03 . . . 019 020 W=1 W=100 N11 node = wrr(p) SET
  • 15. 15 Проблема в коде https://github.com/odnoklassniki/one-nio long []friendsIds = graphService.getFriendsByFilter(userId, mask); List<User> users = new ArrayList<>(friendsIds.length); for (long id : friendsIds) { if(blackList.isAllowed(userId,id)) { users.add(userCache.getUserById(id)); } } … return users;
  • 16. 16 Цена сетевого запроса 0.1-0.3 ms 0.7-1.0 ms Другой ЦОД * цена сильно зависит от конкретной инфраструктуры и фреймворков. задержка 
 = 1.0ms * 2 reqs * 200 друзей
 = 400 ms
 10k друзей задержка = 20 seconds
  • 17. 17 Решение: пакетные запросы public interface UserCache {
 @RemoteMethod( split = true ) Collection<User> getUsersByIds(long[] keys); } long []friendsIds = graphService.getFriendsByFilter(userId, mask); 
 friendsIds = blackList.filterAllowed(userId, friendsIds ); List<User> users = userCache.getUsersByIds(friendsIds); … return users;
  • 18. 18 split & merge split ( ids by p ) -> ids0, ids1 p = 0 p = 1 N01 N02 N03 . . . N11 ids0 ids1 users = merge (users0, users1)
  • 19. 19 1. Пропажа клиента 2. Пропажа сервера 3. Потеря исходящего сообщения 4. Потеря входящего сообщения 5. Таймаут сервера 6. Неправильный ответ 7. Произвольный отказ Что может пойти не так ?
  • 21. • Отказы невозможно предотвратить, только скрыть • Отказ произойдет обязательно. • Ключ к скрытию отказов - избыточность: • Информации (коды защиты от ошибок) • Железа (резервирование, реплики, дублирующие схемы) • Времени (транзакции, retries) 21 Что делать с отказами ?
  • 22. 22 Что сервер сделал ? Сдаваться нельзя , повторить ! Сдаваться , нельзя повторить ! ? ? Добавить друга
  • 23. • Со стороны клиента - неизвестно • Что клиент может сделать ? • Не давать никаких гарантий • Никогда не повторять запрос. Максимум 1 раз. At Most Once. • Всегда повторять запрос. По меньшей мере 1 раз. At Least Once. 23 Был ли друг добавлен ?
  • 24. 1. Транзакция в ACID хранилище • есть мастер, успех однозначен (или проходит или нет) • возможен атомарный откат 2. Обновление информации в кешах • много реплик, мастера нет • атомарного отката нет: возможны частичные отказы 24 Добавляем друга
  • 25. • Операция применима повторно с тем же результатом • напр: чтение, Set.add(), Math.max(x,y) • Упорядоченное Атомарное изменение с контролем дубликата
 25 Идемпотентность Только для Идемпотентных операций
 можно применять стратегию
 “всегда повторять попытку” https://ru.wikipedia.org/wiki/Идемпотентность
  • 26. 26 Идемпотентность в ACID хранилище Подружиться ждем; timeout Подружиться Подружились! Уже друзья ? Нет, делаем изменения! Уже друзья ? Да, ничего не делаем !
  • 27. 27 Идемпотентность через секвенсинг Подружиться (ОпИД) Подружились! УжеДелали (ОпИд) ? Нет, делаем изменения! Выписать ОпИД Примеры ОпИД: • OpId+=1 • OpId=currentTimeMillis() • OpId=TimeUUID http://johannburkard.de/software/uuid/
  • 28. 1. Транзакция в ACID хранилище • есть мастер, успех однозначен (или проходит или нет) • возможен атомарный откат 2. Обновление информации в кешах • много реплик, мастера нет • атомарного отката нет: возможны частичные отказы 28 Добавляем друга
  • 29. 29 Нотификация реплик кешей add(Friend) p = 0 N01 N02 N03 . . . Но без повтора данные реплики рассинхронизируются Повторять бессмысленно
  • 30. • Процесс синхронизации данных • Непрерывно читает изменения из транзакционного хранилища
 
 SELECT * FROM users WHERE modified > ? • Применяет их в память кеша • Загружает изменения при старте ноды • Повтор - ненужен.
 30 Синхронизируем кеш через БД
  • 31. 31 Смерть через таймаут STW GC Подружиться ждем; timeout конец 
 пула потоков
  • 32. 1. Клиенты перестают обращаться к серверу После Х непрерывных отказов за последнюю секунду 2. Клиенты мониторят доступность сервера В фоне, раз в минуту 3. И возвращают его в ротацию 32 Вывод из ротации
  • 33. 33 Смерть через торможение Avg = 1.5ms Max = 1.5c 24 cpu cores Cap = 24,000 ops Cтавить таймаут = 2.4ms ? Выводить из ротации если среднее > 2.4ms ? Avg = 24ms Max = 1.5c 24 cpu cores Cap = 1,000 ops 10,000 ops
  • 34. 34 Спекулятивный повтор Идемпотентная Оп wait; timeout Повторный запрос Результат операции
  • 35. • Применим не всегда • Идемпотентные операции
 дополнительная нагрузка, 
 трафик • Балансируем спекуляцию: всегда, >99p, >avg 35 Спекулятивный повтор • Лучше • Задержки 99p, средние • Стабильность системы Классы, задержка 99p, наносекунды.
 без спекулятивного повтора (желтый)
 и с ним (красный) ^^^ пики до 1 сек ^^^
  • 36. Больше отказов ! Распределенные системы в Одноклассниках
  • 37. • Чрезмерная нагрузка • Чрезмерная паранойя • Баги • Люди • Масштабные аварии 37 Отказ всех реплик сервиса
  • 38. 38 Использовать другие источники,
 деградация консистентности Использовать неполные данные, частичная деградация функции
 Отключать функцию полностью Деградировать!
  • 39. 39 Код interface UserCache {
 @RemoteMethod Distributed<Collection<User>> getUsersByIds(long[] keys); } interface Distributed<D> { boolean isInconsistency(); D getData(); } class UserCacheStub implements UserCache { 
 Distributed<Collection<User>> getUsersByIds(long[] keys) { return Distributed.inconsistent(); } }
  • 41. 41 Свой продукт “Стандартные” продукты - особенно ! “Админские” маневры Что тестировать ?
  • 42. • Что делает: • Определяет соединения с фронта на сервис • Отрубает соединения (iptables drop) • Запускает авто тесты • Что проверяем • Что ничего не валится, показываются красивые заглушки • Сервер стартует 42 Свой продукт: “Горилла”
  • 43. • Тестовый стенд с синтетический нагрузкой ? - Топология сети не неизменна - Сложно воспроизвести профиль нагрузки. • На продакшене! • Но чтобы никто не заметил • Проверяем сценарии отказов и восстановления 43 Как тестировать стандартные решения ?
  • 44. 44 Зеркало UserCacheProxy UserCacheImpl UserCacheNew primary mirror 1. Вызываем primary 2. В отдельном тред пуле mirror. Сравниваем. 3. На основании конфигурации отключаем, переключаем one-conf
  • 46. • Быстрое определение существования аварии • Локализация проблемы • Своевременное предупреждение аварий 46 Зачем
  • 47. • Zabbix • Cacti • Операционные метрики • Имена вызванных операций, напр. “Graph.getFriendsByFilter” • Количество вызовов, успешность • Длительность вызовов 47 Авария есть или будет ?
  • 48. • Оперативную статистику и тренды • Агрегированное число вызовов и ошибок • Агрегации задержек • Среднее, Макс • Перцентили 50,75,98,99,99.9 48 Что показывают графики
  • 51. • Возможностей отказов в распределенных системах безграничны • Отказы маскируются за счет информации, времени, железа • При немаскируемых отказах - деградируем ! • Отказы надо тестировать наравне с функционалом • Отказы нужно диагностировать и предупреждать на проде 51 Краткое содержание предыдущих слайдов
  • 52. 52 Распределенные системы в Одноклассниках, JBreak 2016 slideshare.net/m0nstermind https://v.ok.ru/publishing.html http://www.cs.yale.edu/homes/aspnes/classes/465/notes.pdf Notes on Theory of Distributed Systems CS 465/565: 
 Spring 2014 James Aspnes Тут можно узнать больше: