SlideShare a Scribd company logo
Managed Big Memory
Big Memory = использование больших объемов
RAM в прикладных целях
@agnicore, @itadapter
Dmitriy Khmaladze, Oleg Panagushin
О нас
● Мы - Agnicore, Нью-Йорк, США
● Всё началось с IT Adapter - занимались разработкой и поддержкой
систем высоконагруженных систем более 10 лет.
● Начинали в 90х на нативных решениях C++, Delphi; С начала
двухтысячных больше заказов систем в управляемых средах
исполнения
● Компания Agnicore сформировалась на базе разработок IT Adapter с
целью систематизации ноу-хау в виде готовых решений
2
Фокус
● 64 bit Managed Environments / Server Platforms
● Обработка данных в памяти используя нативную модель - миллионы domain
объектов в процессе - хранящихся длительное время
● Managed Code Runtimes - каждый имеет свою нативную модель объектов
(arrays, maps, properties/fields, value types, readonly etc.)
● Попытаемся остаться в рамках процесса - без IPC
● Опишем методологию off-heap с прозрачной сериализацией, результат
применения которой неочевиден без проведения детальных исследований
● То, о чем пойдет речь, можно использовать на практике 3
Stateless Systems?
● Какой state: session, application, биржевой, бизнес транзакции,
социальный (группа, пользователи), товары?
● Как часто меняется state: user session, биржа, социальная
группа/комната, ценовые политики товаров?
● State есть. Вопрос: где он хранится в долгосрочной и операционной
перспективе?
● Операционные данные лучше хранить в RAM, поскольку это очень
быстро и доступно - Big Memory
4
Применение Big Memory
Кэш
● Для хранения горячих
объектов
● Собираемых из разных
узлов системы
● Для более быстрого
отклика
5
Применение Big Memory
Обход графов
Объекты хранятся долго и
могут меняться часто
● Социальные сети
(изначальная задача)
● Построение связей
● Поиск на графе
● Построение
семантических сетей
6
Применение Big Memory
Поточная обработка
● Обработка данных из
множества источников
● Буферизация данных
● Сопоставление потока
данных с массивом
образцов
7
Применение Big Memory
Нужна детерминированная пропускная способность
Кэш
● Для хранения горячих
объектов
● Собираемых из разных
узлов кластера
● Для более быстрого
отклика
Обход графов
● Построение связей
● Поиск на графе
● Траверс больших графов
● Построение нейронных
сетей
Поточная обработка
● Обработка данных из
множества источников
● Буферизация данных
● Сопоставление поточных
данных с массивом
образцов
8
Обзор рынка - Системы In-Memory обработки
● Hazelcast (Java)
● Apache Ignite / GridGain (Java)
● GigaSpaces (Java)
● Terracotta (Java)
● Redis, MongoDB (MMF) (C/C++)
● NFX Pile (.NET/CLR) Native Objects
9
Systems provide: off-heap (in-process) and distributed (off-process) data
structures Lists, HashMaps, Queues + transactions/atomic:
distributed
in-Memory DB
+ data
structures
Локальная память не используется!
● Использовать много памяти в прикладных приложениях не принято
● Обычно полагаются на внешние хранилища
● Внешние = задержки, копирование данных, context switching, mapping
моделей
10
NIC
NIC
CLR/JVM
Serialization
Почему?
11
Сборка Мусора
12
Как столкнуться с проблемой сборки мусора?
● Не нужны никакие специальные тулзы
● Берем обычный reference-тип, например, User
● Берем List<User> и наполняем несколькими десятками миллионов экземпляров
● Можно в одном потоке, можно в разных
● Приложение начинает подтормаживать при любой последующей нагрузке,
которая аллокирует новые объекты в памяти - например, обрабатывает обычные
Web запросы
13
Managed Runtimes Big Memory GC Problems
● Несколько миллионов объектов…
… приводят к подтормаживаниям процесса
● Чем больше физической памяти…
… тем ситуация хуже
● Решения оптимизации GC…
… не являются панацеей
● Обработка событий сборки мусора…
… ведет к неравномерному распределению нагрузки
14
На заметку
● Задержки GC пропорциональны количеству и запутанности объектов и
количеству ссылок на каждый объект который двигается
● Дефрагментация дырок памяти - реальный убийца = stop all
● Чем больше доступной физической памяти -
тем реже задействуется полный GC
● Чем меньше объекты тем больше их количество в памяти - см. №1
15
На заметку - формат памяти
● Строка из 5 букв занимает > 20 байт на x64
● Каждый объект имеет заголовок 16 байт (16 байт на x64 CLR), т.е.
String[1000] пустых строк ~ 24 килобайта
● JIT производит выравнивание полей для увеличения скорости доступа
● Объект состоящий из нескольких строк и чисел может занять около 100 байт!
16
INT 64
INT 32 UNUSED
String reference
Object Header
Борьба с GC
● Встроенный механизм поколений GC неэффективен поскольку объекты могут
быть долгоживущими
● Pooling - предаллокация и переиспользование объектов
● Выход в неуправляемый код - hello C++
● Ручное распределение :
○ Выделение кусочков byte[]
○ Специализированные сериализаторы для конкретных классов/структур
● Переключение трафика между узлами по уведомлению о приближающемся GC
Разные режимы GC не универсальны для любых задач
17
Тестируем на реальных бизнес объектах
18
<runtime>
<gcServer enabled="true"/>
</runtime>
Нагрузка:
Reference
Map<string,string>
Тестируем CLR
● https://github.com/aumcode/piledemo/tree/master/SocialTrading
● Более 40M объектов невозможно протестировать в относительно
реальном времени.
● Пробовали background, server, SustainedLatencyMode etc.
● Аллокация: 10 потоков из 12 - стабильно 100% CPU
● Аллокация: 6 потоков из 12 в пиках доходят до 90+% CPU
● Jitter - притормаживание процесса
○ На 10М объектов - 700ms раз в секунду
○ На 40М объектов - 2.4s раз в полсекунды
○ На 60М объектов - невозможно измерить в реальном времени
19
Проблемы Big Memory на примере .NET
20
Машина: I7 3.2ghz 6 core, 64 Gb DDR3; Server GC
Что делать?
21
Out-of-process
22
NIC
NIC
CLR
Serialization
In-process
Неуправляемый буфер - Ограничения типов
● требуется маршалинг
● требуются специально подготовленные модели данных / DTO
● нет полиморфизма и графов объектов
● трудно портировать
● тяжело поддерживать
23
CLR/JVM
UNSAFE
In-process
Сериализация
Будет ли решение
основанное на
сериализации работать
приемлемо быстро?
Следует заметить, что
решения out-process =
сериализация
Неуправляемый буфер
● требуется маршалинг
● требуются DTO
● нет полиморфизма и
графов объектов
● трудно портировать
● тяжело поддерживать
Ограничения типов
● Пример: пулы, value типы
● требуются DTO
● нет полиморфизма и
графов объектов
● тяжело поддерживать
24
Сериализация
● Protocol Buffers (Binary)
○ Большая скорость
○ Нет полиморфизма
○ Требует отдельной схемы или мета разметки
● Cap’n Proto (Zero-Copy Binary)
○ Zero-copy сериализатор применим к ограниченному классу задач
○ Большая скорость
○ Вообще не позволяет работать с нативным CLR объектами
○ Время сериализации переносится во время доступа к полям
● BinaryFormatter (.NET)
○ Поддерживает любой CLR объект, но медленно и большой перерасход памяти
● Сериализация в текст (JSON, XML, YAML) (Textual)
○ Очень медленно, большая нагрузка на сборщик мусора
25
Tester Serbench
26
https://github.com/aumcode/serbench
Бизнес нагрузка:
(24 fields)
6 strings, bool, DateTime,
Decimal, int
1 core, 3.2 Ghz I7
Последовательный код на 1
потоке
Serbench
https://github.com/aumcode/serbench
27
SLIM
SLIM
TEXT
Serbench
28
SLIM SLIM
Slim Сериализатор
+ В 5-10 раз быстрее
BinaryFormatter
+ 10-50% плотнее упаковывает
данные чем нативные CLR
+ Поддерживается полиморфизм,
readonly поля, ISerializable и т.д.
+ Не нужны мета атрибуты и
специализированные схемы
- Не поддерживается
версионность
- Не поддерживаются делегаты
29
Телепортация объектов сложных типов:
Dictionary<Patient, Policy<Medical>>
List<Policy<Employment>>
Policy<TDoc> : IEnumerable<TDoc>
etc..
Решение - Большая Куча (NFX.Pile)
● Диспетчер памяти
● На 100% реализован в управляемом коде (без C/C++)
● Внутренне хранит в массивах байт - сегментами - byte[]
● Опционально зеркалирование сегментов в MMF
● Храним: string, byte[], object
● Для сериализации object используется Slim
30
Диспетчер памяти - IPile
31
var data = new Person
{LastName= ”Wiseman”, Age=25 …};
var ptr = pile.Put(data);
…
var got = pile.Get( ptr) as Person;
…
got.LastName....
got.Age....
…
pile.Delete(ptr);
Использование Pile
32
Value Type - GC не видит
PilePointer[10123] = 1 reference, not 10K!
ID узла
распределенного
кластера (optional)
var obj1 = new Payload{ID = 1, Name = "1", Data = null};
var p1 = pile.Put(obj1, preallocateBlockSize: 4000);
pile.SizeOf(p1);// 4000
var obj2 = new Payload{ID = 2, Name = "2", Data =
new byte []{1,2,3,4,5,6,7,8}};
pile.Put(p1, obj2);
var got = pile.Get(p1) as Payload;
……
got.Name…
…
pile.Delete(p1);
Использование Pile - In-Place Mutation
33
Резервируем больше памяти
(необязательно)
Пишем объект по
существующему поинтеру
Удаляем поинтер и все, на что
он указывает
Если новый payload не помещается в существующий блок, то
Pile создаст внутренний alias на новый блок
Устройство Pile
34
PilePointer { Segment: 0x00, Address: 0x00fa53dc }
Seg[0]
Seg[1]
Seg[N]
Дескриптор сегмента Массив байт
Memory-Mapped-File
(опционально)
Устройство Pile
● Сериализуем CLR объект в массив байт
○ Сериализатор динамически адаптируется и кэширует новые типы
● Ищем свободную область нужного размера
○ Перебираем сегменты и анализируем статистику - оптимизируя локинг многопоточности
○ Если есть место, записываем согласно дескриптору и обновляем его
○ Иначе выделяем новый сегмент
● Обеспечивается потоковая безопасность
○ Используется легковесный Reader/Writer Spin-Lock адаптивный к количеству
процессоров
○ В момент аллокации сегменты перебираются непересекающимися окнами с целью
предотвращения lock contention
35
О фрагментации
● Фрагментация появляется при удалении объектов.
● Pile не двигает задействованные блоки (no compaction). Compaction -
основная причина stop-all GC
● Pile периодически (в зависимости от статистики) проползает (crawl)
каждый сегмент, объединяя маленькие прилегающие блоки в большие.
● Фрагментация Pile незначительно влияет на общую производительность,
поскольку Pile - решение более высокого уровня, локальность доступа
важна в момент материализации byte[] в CLR объект.
● Pile обычно используется в random-access режиме (например, поиск по
ключам)
36
Тестируем на реальных бизнес объектах
37
<runtime>
<gcServer enabled="true"/>
</runtime>
Нагрузка:
38
NFX.Pile
103M objects
10 Gb allocated
W: 1,300,000 ops/sec
Jitter: < 43ms 10ms avg
6 thread ~ 75% CPU
1,300,000 ops/sec
NFX.Pile
JITTER
39
NFX.Pile
1,100,000 ops/sec
1,100,000 ops/sec
NFX.Pile
212M objects
21 Gb allocated
W: 1,100,000 ops/sec
D: 1,100,000 ops/sec
---------------------------
T: 2,200,000 ops/sec
Jitter: <58ms <20ms
40
Crawl = Defragmentation
236 M crawled
121 M free slots defragmented into 59M free slots in 1.186 sec
41
NFX.Pile
118M objects
12 Gb allocated
R: 800,000 ops/sec
W: 800,000 ops/sec
D: 800,000 ops/sec
---------------------------
T: 2,400,000 ops/sec
Jitter: <168ms <20ms
Full GC:
277 ms 3 Gb free
800,000 ops/sec
800,000 ops/sec
800,000 ops/sec
NFX.Pile
Скорость Pile
42
Pile аллокирует 40M за 34 сек
https://github.com/aumcode/piledemo
Скорость CLR
43
CLR аллокирует 40M за 39 сек
https://github.com/aumcode/piledemo
44
.NET CLR
16M objects
12 Gb allocated
W: 100K-2.5M ops/sec
---------------------------
T: ~100K - 2.5.M ops/sec
Jitter: +1s +250ms
CPU: 98%
100K - 2,500,000 ops/sec
CLR .NET
45
.NET CLR
40M objects
50 Gb allocated
W: 130K - 2.5M ops/sec
D: 130K - 2.5M ops/sec
---------------------------
T: 400K - 5M ops/sec
Jitter: 3s avg +1.4s
CPU: 100%
130K - 2,500,000 ops/sec
130K - 2,500,000 ops/sec
CLR .NET
46
.NET CLR
40M objects
59-40 Gb allocated
W: 77K - 1.8M ops/sec
D: 80K - 1.8M ops/sec
---------------------------
T: 160K - <4M ops/sec
Jitter: 14s avg +3s
CPU: 100%
77K - 1,800,000 ops/sec
80K - 1,800,000 ops/sec
CLR .NET
47
438K - 1,400,000 ops/sec
438K - 1,400,000 ops/sec
438K - 1,400,000 ops/sec
.NET CLR
28M objects
59-30 Gb allocated
R: 438K - 1.4M ops/sec
W: 438K - 1.4M ops/sec
D: 438K - 1.4M ops/sec
---------------------------
T: 1.4K - <4.5M ops/sec
Jitter: 29s avg +5s
CPU: 100%
CLR .NET
Скорость CLR
48
CLR аллокирует 40M за 39 сек
https://github.com/aumcode/piledemo
Скорость Pile
49
Pile аллокирует 40M за 34 сек
https://github.com/aumcode/piledemo
В итоге Pile:
+ Позволяет хранить больше объектов в том же объеме памяти
○ Объекты сжимаются Slim сериализатором
+ Обеспечивает детерминированную пропускную способность
○ Устраняются “паузы”, вызванные сборщиком мусора
+ После десериализации возвращает копию объекта
○ Это удобно в случае многопоточного программирования
+ На основе Pile реализуются более высокоуровневые абстракции,
например: Cache, Dictionary, Tree, LinkedList и т.д.
50
Pile Кэш - практическое применение BigMemory
● LocalCache - реализация in-process кэш сервера
○ В режиме Durable: работает как обычный dictionary
○ Поддерживает именованные таблицы
○ Приоритизацию объектов
○ Максимальный TTL или абсолютный expiration
○ Поддерживает детальную настройку значений емкости, LWM,
коэффициент расширения/сжатия для каждой таблицы
● Используется для мемоизации
доступа к данным БД
● Используется как обычный “большой” hashmap
51
Использование Pile - Cache
52
var userData = new SocialUser{.....};
var tbl = cache.GetOrCreateTable<SocialID>(“users”);
…
tbl.Put(userData.SocialID, userData);
…
var requestedId = new SocialID(IDType.Twitter, 42376472343);
var ageSec = 120;
var user = tbl.Get(requestedId, maxAgeSec: ageSec) as SocialUser;
…
var removed = tbl.Remove(requestedId);
…
Нет никаких поинтеров,
только предметная область
Big Memory Instruments
53
Заключение
● Мы исследовали подход к хранению большого количества объектов предметной
области in-process путем сериализации объектов в managed byte[], не задействуя
C++/внешние хранилища
● Ценность - не требуется коренного изменения бизнес модели данных
● Решение managed диспетчера памяти (Pile) позволяет:
○ Хранить резидентно в локальной памяти более миллиарда домен объектов, адресуясь к
ним по простым ключам через Кэш
○ Сжать managed footprint объектов на 10-50% (благодаря сериализации)
○ Гарантировать паузы GC < 50ms (при 128GB heap 1.5B объектов по 71 байту)
○ Обеспечить высокую скорость записи/чтения объектов (сотни тысяч простых
экземпляров в секунду на поток)
○ Проектировать высокоуровневые структуры данных для решения специализированных
задач: семантические сети, социальные графы, деревья и т.д.
54
Спасибо!
@itadapter, @agnicore
memory@agnicore.com
https://itadapter.com
https://agnicore.com
https://github.com/aumcode
https://nfxlib.com
© 2017 Agnicore Inc.
55
Links
https://aloiskraus.wordpress.com/2017/04/23/the-definitive-serialization-performan
ce-guide/comment-page-1/
https://www.infoq.com/articles/Big-Memory-Part-1
https://www.infoq.com/articles/Big-Memory-Part-2
https://nfxlib.com
https://github.com/aumcode/serbench
56

More Related Content

PPTX
Погружение в виртуальную память и большие страницы / Константин Новаковский (...
PDF
Мониторинг и отладка MySQL: максимум информации при минимальных потерях
PPTX
Чеклист по клиентской оптимизации - Лавлинский Николай, РИТ++ 2017
PDF
Семантическое ядро рунета - высоконагруженная сontent-based рекомендательная ...
PDF
Что особенного в СУБД для данных в оперативной памяти / Константин Осипов (Ta...
PDF
Open Source SQL-базы данных вступили в эру миллионов запросов в секунду / Фед...
PDF
Кластеры баз данных делаем сложные вещи просто / Андрей Тихонов (Avito)
PDF
Tempesta FW: challenges, internals, use cases / Александр Крижановский (Tempe...
Погружение в виртуальную память и большие страницы / Константин Новаковский (...
Мониторинг и отладка MySQL: максимум информации при минимальных потерях
Чеклист по клиентской оптимизации - Лавлинский Николай, РИТ++ 2017
Семантическое ядро рунета - высоконагруженная сontent-based рекомендательная ...
Что особенного в СУБД для данных в оперативной памяти / Константин Осипов (Ta...
Open Source SQL-базы данных вступили в эру миллионов запросов в секунду / Фед...
Кластеры баз данных делаем сложные вещи просто / Андрей Тихонов (Avito)
Tempesta FW: challenges, internals, use cases / Александр Крижановский (Tempe...

What's hot (20)

PDF
Внутреннее устройство PostgreSQL: временные таблицы и фрагментация памяти / Г...
PPTX
За счет чего Tarantool такой оптимальный / Денис Аникин (Mail.Ru)
PDF
10 способов достижения HighLoad'а и BigData на ровном месте / Илья Космодемья...
PDF
My talk at Highload++ 2015
PPTX
Flashcache в mamba.ru / Яковлев Александр Юрьевич (ЗАО Мамба)
PDF
Ускоряем и разгружаем веб-сервер, прозрачно кэшируя на SSD, Станислав Николов...
PDF
pgconf.ru 2015 avito postgresql
PPTX
Chronicle Map — key-value хранилище для трейдинга на Java / Левентов Роман (C...
PDF
Путь от монолита на PHP к микросервисам на Scala / Денис Иванов (2GIS)
PPTX
Жизнь проекта на production советы по эксплуатации / Николай Сивко (okmeter.io)
PDF
Оптимизация программ для современных процессоров и Linux, Александр Крижановс...
PPTX
Эволюция программно-аппаратного обеспечения хранения фотографий в Badoo / Дми...
PDF
nginx.CHANGES.2015 / Игорь Сысоев, Валентин Бартенев (Nginx)
PPTX
«Секретные» технологии инвестиционных банков / Алексей Рагозин (Дойче Банк)
PPTX
Как обслужить 60 миллионов абонентов, Артем Руфанов (ПЕТЕР-СЕРВИС)
PPTX
MySQL 5.7 - NoSQL - JSON, Protocol X, Document Store / Петр Зайцев (Percona)
PPTX
Спасение 6 миллионов файлов в условиях полного Хецнера
PPTX
Инструменты высоконагруженных проектов - кэширование и очереди, Вячеслав Моск...
PDF
Последние новости постгреса с PGCon / О.Бартунов, А.Коротков, Ф.Сигаев (Postg...
PDF
NodeJS в HighLoad проекте / Акрицкий Владимир (iAge Engineering)
Внутреннее устройство PostgreSQL: временные таблицы и фрагментация памяти / Г...
За счет чего Tarantool такой оптимальный / Денис Аникин (Mail.Ru)
10 способов достижения HighLoad'а и BigData на ровном месте / Илья Космодемья...
My talk at Highload++ 2015
Flashcache в mamba.ru / Яковлев Александр Юрьевич (ЗАО Мамба)
Ускоряем и разгружаем веб-сервер, прозрачно кэшируя на SSD, Станислав Николов...
pgconf.ru 2015 avito postgresql
Chronicle Map — key-value хранилище для трейдинга на Java / Левентов Роман (C...
Путь от монолита на PHP к микросервисам на Scala / Денис Иванов (2GIS)
Жизнь проекта на production советы по эксплуатации / Николай Сивко (okmeter.io)
Оптимизация программ для современных процессоров и Linux, Александр Крижановс...
Эволюция программно-аппаратного обеспечения хранения фотографий в Badoo / Дми...
nginx.CHANGES.2015 / Игорь Сысоев, Валентин Бартенев (Nginx)
«Секретные» технологии инвестиционных банков / Алексей Рагозин (Дойче Банк)
Как обслужить 60 миллионов абонентов, Артем Руфанов (ПЕТЕР-СЕРВИС)
MySQL 5.7 - NoSQL - JSON, Protocol X, Document Store / Петр Зайцев (Percona)
Спасение 6 миллионов файлов в условиях полного Хецнера
Инструменты высоконагруженных проектов - кэширование и очереди, Вячеслав Моск...
Последние новости постгреса с PGCon / О.Бартунов, А.Коротков, Ф.Сигаев (Postg...
NodeJS в HighLoad проекте / Акрицкий Владимир (iAge Engineering)
Ad

Viewers also liked (20)

PDF
Лучшие практики CI/CD с Kubernetes и GitLab / Дмитрий Столяров (Флант)
PDF
NoSQL Best Practices for PostgreSQL / Дмитрий Долгов (Mindojo)
PDF
Развитие баз данных в Dropbox. Путь от одной глобальной базы MySQL к 6000 шар...
PDF
Введение в блокчейн и алгоритмы консенсуса / Филипп Филиппак (Waves Platform)
PDF
Применение блокчейна в RTB. Можно ли масштабировать децентрализованную базу д...
PPTX
Безболезненный Fallback cache на Scala / Олег Нижников (Tinkoff.ru)
PPTX
Хранилище данных Avito: аналитика для микросервисной архитектуры / Артем Дани...
PPTX
Lua в нагруженных телеком-системах / Дмитрий Борисов (ИП Борисов Дмитрий Нико...
PPTX
Ошибки проектирования высоконагруженных проектов / Максим Ехлаков (OneTwoRent)
PPTX
Масштабирование сети VR-аттракционов CinemaVR / Андрей Татаринов (VRTech)
PPTX
Встреча докладчиков Hl++ 2017
PPTX
Как сделать сложное простым. История создания Проект1917 / Сергей Спорышев (I...
PPTX
WAMP[-proto] как основа композитных SOA-приложений и его имплементация на Lua...
PPTX
Как заранее соломки подстелить или путь к 99,99% uptime проекта / Игорь Мызги...
PDF
Карта граблей на поле сбора и доставки логов. Lazada-way / Юрий Бушмелев (Laz...
PDF
DevOps-трансформация Альфа-Банка / Антон Исанин (Альфа-Банк)
PDF
Все, что тимлид должен знать о найме и увольнении / Степан Овчинников (ИНТЕРВ...
PDF
Сложности performance-тестирования / Андрей Акиньшин (JetBrains)
PDF
DDoS-атаки: тектонические изменения в 2016-2017 году / Артём Гавриченков (Qra...
PPTX
Организации в бирюзовом цвете / Мария Груздева (НИУ ВШЭ)
Лучшие практики CI/CD с Kubernetes и GitLab / Дмитрий Столяров (Флант)
NoSQL Best Practices for PostgreSQL / Дмитрий Долгов (Mindojo)
Развитие баз данных в Dropbox. Путь от одной глобальной базы MySQL к 6000 шар...
Введение в блокчейн и алгоритмы консенсуса / Филипп Филиппак (Waves Platform)
Применение блокчейна в RTB. Можно ли масштабировать децентрализованную базу д...
Безболезненный Fallback cache на Scala / Олег Нижников (Tinkoff.ru)
Хранилище данных Avito: аналитика для микросервисной архитектуры / Артем Дани...
Lua в нагруженных телеком-системах / Дмитрий Борисов (ИП Борисов Дмитрий Нико...
Ошибки проектирования высоконагруженных проектов / Максим Ехлаков (OneTwoRent)
Масштабирование сети VR-аттракционов CinemaVR / Андрей Татаринов (VRTech)
Встреча докладчиков Hl++ 2017
Как сделать сложное простым. История создания Проект1917 / Сергей Спорышев (I...
WAMP[-proto] как основа композитных SOA-приложений и его имплементация на Lua...
Как заранее соломки подстелить или путь к 99,99% uptime проекта / Игорь Мызги...
Карта граблей на поле сбора и доставки логов. Lazada-way / Юрий Бушмелев (Laz...
DevOps-трансформация Альфа-Банка / Антон Исанин (Альфа-Банк)
Все, что тимлид должен знать о найме и увольнении / Степан Овчинников (ИНТЕРВ...
Сложности performance-тестирования / Андрей Акиньшин (JetBrains)
DDoS-атаки: тектонические изменения в 2016-2017 году / Артём Гавриченков (Qra...
Организации в бирюзовом цвете / Мария Груздева (НИУ ВШЭ)
Ad

Similar to BigMemory - работа с сотнями миллионов бизнес-объектов / Дмитрий Хмаладзе (Agnicore) (20)

PDF
Новые возможности распределенной обработки данных в памяти (Coherence)
PDF
Caching data outside Java Heap and using Shared Memory in Java
PPTX
Developing highload servers with Java
PPT
An internal look at HotSpot JVM
PDF
Продолжаем говорить о микрооптимизациях .NET-приложений
PDF
High Load 2009 Imdg Presentation
PDF
Java осень 2014 занятие 6
PDF
андрей паньгин
PDF
CodeFest 2013. Иванов В. — Уменьшение расхода оперативной памяти в Java-прило...
PDF
Выжимаем из сервера максимум (Андрей Паньгин)
PDF
Олег Царев, Кирилл Коринский Сравнительный анализ хранилищ данных
PDF
Purely practical data structures
PDF
Евгений Лазин. Неизменяемая структура данных HAMT для создания БД в памяти
PDF
In the sun.misc.Unsafe bowels
PDF
Незаурядная Java как инструмент разработки высоконагруженного сервера
PPT
Проект «Одноклассники» Mail.Ru Group, Андрей Паньгин
PDF
Java tricks for high-load server programming
PPTX
Dz Java Hi Load 0.4
PPTX
PostSharp - Threading Model Library
Новые возможности распределенной обработки данных в памяти (Coherence)
Caching data outside Java Heap and using Shared Memory in Java
Developing highload servers with Java
An internal look at HotSpot JVM
Продолжаем говорить о микрооптимизациях .NET-приложений
High Load 2009 Imdg Presentation
Java осень 2014 занятие 6
андрей паньгин
CodeFest 2013. Иванов В. — Уменьшение расхода оперативной памяти в Java-прило...
Выжимаем из сервера максимум (Андрей Паньгин)
Олег Царев, Кирилл Коринский Сравнительный анализ хранилищ данных
Purely practical data structures
Евгений Лазин. Неизменяемая структура данных HAMT для создания БД в памяти
In the sun.misc.Unsafe bowels
Незаурядная Java как инструмент разработки высоконагруженного сервера
Проект «Одноклассники» Mail.Ru Group, Андрей Паньгин
Java tricks for high-load server programming
Dz Java Hi Load 0.4
PostSharp - Threading Model Library

More from Ontico (20)

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

BigMemory - работа с сотнями миллионов бизнес-объектов / Дмитрий Хмаладзе (Agnicore)

  • 1. Managed Big Memory Big Memory = использование больших объемов RAM в прикладных целях @agnicore, @itadapter Dmitriy Khmaladze, Oleg Panagushin
  • 2. О нас ● Мы - Agnicore, Нью-Йорк, США ● Всё началось с IT Adapter - занимались разработкой и поддержкой систем высоконагруженных систем более 10 лет. ● Начинали в 90х на нативных решениях C++, Delphi; С начала двухтысячных больше заказов систем в управляемых средах исполнения ● Компания Agnicore сформировалась на базе разработок IT Adapter с целью систематизации ноу-хау в виде готовых решений 2
  • 3. Фокус ● 64 bit Managed Environments / Server Platforms ● Обработка данных в памяти используя нативную модель - миллионы domain объектов в процессе - хранящихся длительное время ● Managed Code Runtimes - каждый имеет свою нативную модель объектов (arrays, maps, properties/fields, value types, readonly etc.) ● Попытаемся остаться в рамках процесса - без IPC ● Опишем методологию off-heap с прозрачной сериализацией, результат применения которой неочевиден без проведения детальных исследований ● То, о чем пойдет речь, можно использовать на практике 3
  • 4. Stateless Systems? ● Какой state: session, application, биржевой, бизнес транзакции, социальный (группа, пользователи), товары? ● Как часто меняется state: user session, биржа, социальная группа/комната, ценовые политики товаров? ● State есть. Вопрос: где он хранится в долгосрочной и операционной перспективе? ● Операционные данные лучше хранить в RAM, поскольку это очень быстро и доступно - Big Memory 4
  • 5. Применение Big Memory Кэш ● Для хранения горячих объектов ● Собираемых из разных узлов системы ● Для более быстрого отклика 5
  • 6. Применение Big Memory Обход графов Объекты хранятся долго и могут меняться часто ● Социальные сети (изначальная задача) ● Построение связей ● Поиск на графе ● Построение семантических сетей 6
  • 7. Применение Big Memory Поточная обработка ● Обработка данных из множества источников ● Буферизация данных ● Сопоставление потока данных с массивом образцов 7
  • 8. Применение Big Memory Нужна детерминированная пропускная способность Кэш ● Для хранения горячих объектов ● Собираемых из разных узлов кластера ● Для более быстрого отклика Обход графов ● Построение связей ● Поиск на графе ● Траверс больших графов ● Построение нейронных сетей Поточная обработка ● Обработка данных из множества источников ● Буферизация данных ● Сопоставление поточных данных с массивом образцов 8
  • 9. Обзор рынка - Системы In-Memory обработки ● Hazelcast (Java) ● Apache Ignite / GridGain (Java) ● GigaSpaces (Java) ● Terracotta (Java) ● Redis, MongoDB (MMF) (C/C++) ● NFX Pile (.NET/CLR) Native Objects 9 Systems provide: off-heap (in-process) and distributed (off-process) data structures Lists, HashMaps, Queues + transactions/atomic: distributed in-Memory DB + data structures
  • 10. Локальная память не используется! ● Использовать много памяти в прикладных приложениях не принято ● Обычно полагаются на внешние хранилища ● Внешние = задержки, копирование данных, context switching, mapping моделей 10 NIC NIC CLR/JVM Serialization
  • 13. Как столкнуться с проблемой сборки мусора? ● Не нужны никакие специальные тулзы ● Берем обычный reference-тип, например, User ● Берем List<User> и наполняем несколькими десятками миллионов экземпляров ● Можно в одном потоке, можно в разных ● Приложение начинает подтормаживать при любой последующей нагрузке, которая аллокирует новые объекты в памяти - например, обрабатывает обычные Web запросы 13
  • 14. Managed Runtimes Big Memory GC Problems ● Несколько миллионов объектов… … приводят к подтормаживаниям процесса ● Чем больше физической памяти… … тем ситуация хуже ● Решения оптимизации GC… … не являются панацеей ● Обработка событий сборки мусора… … ведет к неравномерному распределению нагрузки 14
  • 15. На заметку ● Задержки GC пропорциональны количеству и запутанности объектов и количеству ссылок на каждый объект который двигается ● Дефрагментация дырок памяти - реальный убийца = stop all ● Чем больше доступной физической памяти - тем реже задействуется полный GC ● Чем меньше объекты тем больше их количество в памяти - см. №1 15
  • 16. На заметку - формат памяти ● Строка из 5 букв занимает > 20 байт на x64 ● Каждый объект имеет заголовок 16 байт (16 байт на x64 CLR), т.е. String[1000] пустых строк ~ 24 килобайта ● JIT производит выравнивание полей для увеличения скорости доступа ● Объект состоящий из нескольких строк и чисел может занять около 100 байт! 16 INT 64 INT 32 UNUSED String reference Object Header
  • 17. Борьба с GC ● Встроенный механизм поколений GC неэффективен поскольку объекты могут быть долгоживущими ● Pooling - предаллокация и переиспользование объектов ● Выход в неуправляемый код - hello C++ ● Ручное распределение : ○ Выделение кусочков byte[] ○ Специализированные сериализаторы для конкретных классов/структур ● Переключение трафика между узлами по уведомлению о приближающемся GC Разные режимы GC не универсальны для любых задач 17
  • 18. Тестируем на реальных бизнес объектах 18 <runtime> <gcServer enabled="true"/> </runtime> Нагрузка: Reference Map<string,string>
  • 19. Тестируем CLR ● https://github.com/aumcode/piledemo/tree/master/SocialTrading ● Более 40M объектов невозможно протестировать в относительно реальном времени. ● Пробовали background, server, SustainedLatencyMode etc. ● Аллокация: 10 потоков из 12 - стабильно 100% CPU ● Аллокация: 6 потоков из 12 в пиках доходят до 90+% CPU ● Jitter - притормаживание процесса ○ На 10М объектов - 700ms раз в секунду ○ На 40М объектов - 2.4s раз в полсекунды ○ На 60М объектов - невозможно измерить в реальном времени 19
  • 20. Проблемы Big Memory на примере .NET 20 Машина: I7 3.2ghz 6 core, 64 Gb DDR3; Server GC
  • 23. In-process Неуправляемый буфер - Ограничения типов ● требуется маршалинг ● требуются специально подготовленные модели данных / DTO ● нет полиморфизма и графов объектов ● трудно портировать ● тяжело поддерживать 23 CLR/JVM UNSAFE
  • 24. In-process Сериализация Будет ли решение основанное на сериализации работать приемлемо быстро? Следует заметить, что решения out-process = сериализация Неуправляемый буфер ● требуется маршалинг ● требуются DTO ● нет полиморфизма и графов объектов ● трудно портировать ● тяжело поддерживать Ограничения типов ● Пример: пулы, value типы ● требуются DTO ● нет полиморфизма и графов объектов ● тяжело поддерживать 24
  • 25. Сериализация ● Protocol Buffers (Binary) ○ Большая скорость ○ Нет полиморфизма ○ Требует отдельной схемы или мета разметки ● Cap’n Proto (Zero-Copy Binary) ○ Zero-copy сериализатор применим к ограниченному классу задач ○ Большая скорость ○ Вообще не позволяет работать с нативным CLR объектами ○ Время сериализации переносится во время доступа к полям ● BinaryFormatter (.NET) ○ Поддерживает любой CLR объект, но медленно и большой перерасход памяти ● Сериализация в текст (JSON, XML, YAML) (Textual) ○ Очень медленно, большая нагрузка на сборщик мусора 25
  • 26. Tester Serbench 26 https://github.com/aumcode/serbench Бизнес нагрузка: (24 fields) 6 strings, bool, DateTime, Decimal, int 1 core, 3.2 Ghz I7 Последовательный код на 1 потоке
  • 29. Slim Сериализатор + В 5-10 раз быстрее BinaryFormatter + 10-50% плотнее упаковывает данные чем нативные CLR + Поддерживается полиморфизм, readonly поля, ISerializable и т.д. + Не нужны мета атрибуты и специализированные схемы - Не поддерживается версионность - Не поддерживаются делегаты 29 Телепортация объектов сложных типов: Dictionary<Patient, Policy<Medical>> List<Policy<Employment>> Policy<TDoc> : IEnumerable<TDoc> etc..
  • 30. Решение - Большая Куча (NFX.Pile) ● Диспетчер памяти ● На 100% реализован в управляемом коде (без C/C++) ● Внутренне хранит в массивах байт - сегментами - byte[] ● Опционально зеркалирование сегментов в MMF ● Храним: string, byte[], object ● Для сериализации object используется Slim 30
  • 32. var data = new Person {LastName= ”Wiseman”, Age=25 …}; var ptr = pile.Put(data); … var got = pile.Get( ptr) as Person; … got.LastName.... got.Age.... … pile.Delete(ptr); Использование Pile 32 Value Type - GC не видит PilePointer[10123] = 1 reference, not 10K! ID узла распределенного кластера (optional)
  • 33. var obj1 = new Payload{ID = 1, Name = "1", Data = null}; var p1 = pile.Put(obj1, preallocateBlockSize: 4000); pile.SizeOf(p1);// 4000 var obj2 = new Payload{ID = 2, Name = "2", Data = new byte []{1,2,3,4,5,6,7,8}}; pile.Put(p1, obj2); var got = pile.Get(p1) as Payload; …… got.Name… … pile.Delete(p1); Использование Pile - In-Place Mutation 33 Резервируем больше памяти (необязательно) Пишем объект по существующему поинтеру Удаляем поинтер и все, на что он указывает Если новый payload не помещается в существующий блок, то Pile создаст внутренний alias на новый блок
  • 34. Устройство Pile 34 PilePointer { Segment: 0x00, Address: 0x00fa53dc } Seg[0] Seg[1] Seg[N] Дескриптор сегмента Массив байт Memory-Mapped-File (опционально)
  • 35. Устройство Pile ● Сериализуем CLR объект в массив байт ○ Сериализатор динамически адаптируется и кэширует новые типы ● Ищем свободную область нужного размера ○ Перебираем сегменты и анализируем статистику - оптимизируя локинг многопоточности ○ Если есть место, записываем согласно дескриптору и обновляем его ○ Иначе выделяем новый сегмент ● Обеспечивается потоковая безопасность ○ Используется легковесный Reader/Writer Spin-Lock адаптивный к количеству процессоров ○ В момент аллокации сегменты перебираются непересекающимися окнами с целью предотвращения lock contention 35
  • 36. О фрагментации ● Фрагментация появляется при удалении объектов. ● Pile не двигает задействованные блоки (no compaction). Compaction - основная причина stop-all GC ● Pile периодически (в зависимости от статистики) проползает (crawl) каждый сегмент, объединяя маленькие прилегающие блоки в большие. ● Фрагментация Pile незначительно влияет на общую производительность, поскольку Pile - решение более высокого уровня, локальность доступа важна в момент материализации byte[] в CLR объект. ● Pile обычно используется в random-access режиме (например, поиск по ключам) 36
  • 37. Тестируем на реальных бизнес объектах 37 <runtime> <gcServer enabled="true"/> </runtime> Нагрузка:
  • 38. 38 NFX.Pile 103M objects 10 Gb allocated W: 1,300,000 ops/sec Jitter: < 43ms 10ms avg 6 thread ~ 75% CPU 1,300,000 ops/sec NFX.Pile JITTER
  • 39. 39 NFX.Pile 1,100,000 ops/sec 1,100,000 ops/sec NFX.Pile 212M objects 21 Gb allocated W: 1,100,000 ops/sec D: 1,100,000 ops/sec --------------------------- T: 2,200,000 ops/sec Jitter: <58ms <20ms
  • 40. 40 Crawl = Defragmentation 236 M crawled 121 M free slots defragmented into 59M free slots in 1.186 sec
  • 41. 41 NFX.Pile 118M objects 12 Gb allocated R: 800,000 ops/sec W: 800,000 ops/sec D: 800,000 ops/sec --------------------------- T: 2,400,000 ops/sec Jitter: <168ms <20ms Full GC: 277 ms 3 Gb free 800,000 ops/sec 800,000 ops/sec 800,000 ops/sec NFX.Pile
  • 42. Скорость Pile 42 Pile аллокирует 40M за 34 сек https://github.com/aumcode/piledemo
  • 43. Скорость CLR 43 CLR аллокирует 40M за 39 сек https://github.com/aumcode/piledemo
  • 44. 44 .NET CLR 16M objects 12 Gb allocated W: 100K-2.5M ops/sec --------------------------- T: ~100K - 2.5.M ops/sec Jitter: +1s +250ms CPU: 98% 100K - 2,500,000 ops/sec CLR .NET
  • 45. 45 .NET CLR 40M objects 50 Gb allocated W: 130K - 2.5M ops/sec D: 130K - 2.5M ops/sec --------------------------- T: 400K - 5M ops/sec Jitter: 3s avg +1.4s CPU: 100% 130K - 2,500,000 ops/sec 130K - 2,500,000 ops/sec CLR .NET
  • 46. 46 .NET CLR 40M objects 59-40 Gb allocated W: 77K - 1.8M ops/sec D: 80K - 1.8M ops/sec --------------------------- T: 160K - <4M ops/sec Jitter: 14s avg +3s CPU: 100% 77K - 1,800,000 ops/sec 80K - 1,800,000 ops/sec CLR .NET
  • 47. 47 438K - 1,400,000 ops/sec 438K - 1,400,000 ops/sec 438K - 1,400,000 ops/sec .NET CLR 28M objects 59-30 Gb allocated R: 438K - 1.4M ops/sec W: 438K - 1.4M ops/sec D: 438K - 1.4M ops/sec --------------------------- T: 1.4K - <4.5M ops/sec Jitter: 29s avg +5s CPU: 100% CLR .NET
  • 48. Скорость CLR 48 CLR аллокирует 40M за 39 сек https://github.com/aumcode/piledemo
  • 49. Скорость Pile 49 Pile аллокирует 40M за 34 сек https://github.com/aumcode/piledemo
  • 50. В итоге Pile: + Позволяет хранить больше объектов в том же объеме памяти ○ Объекты сжимаются Slim сериализатором + Обеспечивает детерминированную пропускную способность ○ Устраняются “паузы”, вызванные сборщиком мусора + После десериализации возвращает копию объекта ○ Это удобно в случае многопоточного программирования + На основе Pile реализуются более высокоуровневые абстракции, например: Cache, Dictionary, Tree, LinkedList и т.д. 50
  • 51. Pile Кэш - практическое применение BigMemory ● LocalCache - реализация in-process кэш сервера ○ В режиме Durable: работает как обычный dictionary ○ Поддерживает именованные таблицы ○ Приоритизацию объектов ○ Максимальный TTL или абсолютный expiration ○ Поддерживает детальную настройку значений емкости, LWM, коэффициент расширения/сжатия для каждой таблицы ● Используется для мемоизации доступа к данным БД ● Используется как обычный “большой” hashmap 51
  • 52. Использование Pile - Cache 52 var userData = new SocialUser{.....}; var tbl = cache.GetOrCreateTable<SocialID>(“users”); … tbl.Put(userData.SocialID, userData); … var requestedId = new SocialID(IDType.Twitter, 42376472343); var ageSec = 120; var user = tbl.Get(requestedId, maxAgeSec: ageSec) as SocialUser; … var removed = tbl.Remove(requestedId); … Нет никаких поинтеров, только предметная область
  • 54. Заключение ● Мы исследовали подход к хранению большого количества объектов предметной области in-process путем сериализации объектов в managed byte[], не задействуя C++/внешние хранилища ● Ценность - не требуется коренного изменения бизнес модели данных ● Решение managed диспетчера памяти (Pile) позволяет: ○ Хранить резидентно в локальной памяти более миллиарда домен объектов, адресуясь к ним по простым ключам через Кэш ○ Сжать managed footprint объектов на 10-50% (благодаря сериализации) ○ Гарантировать паузы GC < 50ms (при 128GB heap 1.5B объектов по 71 байту) ○ Обеспечить высокую скорость записи/чтения объектов (сотни тысяч простых экземпляров в секунду на поток) ○ Проектировать высокоуровневые структуры данных для решения специализированных задач: семантические сети, социальные графы, деревья и т.д. 54