Первая лекция раздела NoSQL курса "Базы данных" в Технополисе.
Содержание: определения и примеры, классификация СУДБ, что значит Web Scale, hashing, caching, key-value хранилища.
Первая лекция раздела NoSQL курса "Базы данных" в Технополисе.
Содержание: определения и примеры, классификация СУДБ, что значит Web Scale, hashing, caching, key-value хранилища.
Современная операционная система: что надо знать разработчику / Александр Кри...Ontico
Мы проговорим про связь приложения и ОС, какие компоненты есть в современной ОС на примере Linux, как настройки этих компонент могут повлиять на приложение.
Я расскажу про планировщик процессов, дисковый и сетевой ввод-вывод и соответствующие планировщики, управление памятью - как это все в общих чертах работает и как его потюнить.
Мониторинг ожиданий в PostgreSQL / Курбангалиев Ильдус (Postgres Professional)Ontico
В многоядерных высоконагруженных системах с высокой конкурентностью часто бывает сложно определить, чем занят отдельный процесс PostgreSQL. Он может находиться в ожидании локов высокого уровня, таких как локи таблиц, внутренних локов, используемых для синхронизации процессов, ввода-вывода и многих других.
В настоящий момент среди всех событий ожидания мониторить можно только локи высокого уровня с помощью представлений PostgreSQL. Другие типы ожиданий требуют использования низкоуровневых утилит типа perf, systemtap и других. Эти утилиты требуют специальных знаний и могут быть платформозависимыми. В то же время другие enterprise базы данных уже включают в себя инструменты для мониторинга ожиданий.
Мы разработали патч, который реализует мониторинг ожиданий в PostgreSQL. С минимальной настройкой (несколько конфигурационных параметров) этот патч показывает полную информацию о текущих ожиданиях в режиме реального времени и с небольшим оверхедом на всю систему. Этот патч уже работает на продакшен серверах Яндекса и показал свою полезность.
DNS в условиях хостинг-провайдера / Константин Новаковский (Selectel)Ontico
DNS — это одна из основополагающих служб и протоколов современного интернета, сервис, который должен всегда работать. Каждый раз, когда конечный пользователь обращается к какому-либо ресурсу глобальной паутины, он использует DNS, и чтобы этот самый первый шаг к проектам у наших клиентов не занимал много времени, мы построили свой DNS-хостинг с использованием Anycast-балансировки. Чуть позже мы применили этот метод для балансировки и повышения доступности рекурсивных серверов внутри наших дата-центров.
В своём докладе я расскажу о способах обеспечения непрерывного обслуживания DNS-запросов, подводных камнях использования anycast’а, постараюсь раскрыть актуальные проблемы обслуживания DNS-серверов и поведаю о современных тенденциях в мире DNS.
Раздатчик музыки непосредственно занимается отдачей байтов аудиопотока многочисленным пользователям https://ok.ru/music. В пике суммарный трафик достигает 100 Гб/с через сотни тысяч соединений, а время до первого байта составляет не больше 100 мс. Предыдущая версия раздатчика на основе файлов и Apache Tomcat не устраивала нас требуемым количеством оборудования и неспособностью утилизировать современное железо. При разработке новой версии мы поставили перед собой цель сохранить внешнюю функциональность сервиса неизменной, но обойтись существенно меньшим количеством машин, сохранив при этом масштабируемость и отказоустойчивость сервиса.
В докладе мы рассмотрим, как различные архитектурные решения помогли нам обеспечить масштабируемость и отказоустойчивость сервиса за счёт распределения и репликации музыкальных треков между нодами. Затем подробно поговорим про устройство отдельной ноды, включая отказоустойчивую подсистему хранения, сетевую подсистему, а также использование подхода reactive streams. Уделим особое внимание собранным граблям и трюкам, позволившим увеличить производительность системы, упростить отладку и эксплуатацию системы.
Доклад ориентирован на разработчиков, которые хотят расширить свой арсенал подходов и инструментов для создания распределённых и/или высоконагруженных систем с интенсивным I/O.
Строим сервисы на базе Nginx и Tarantool / Василий Сошников, Андрей Дроздов (...Ontico
Слушатели этого доклада получат представление о том, как построить отказоустойчивое, быстрое, простое и легко масштабируемое решение на базе Nginx и Tarantool.
Коротко о главном:
+ Обзор внутреннего устройства шардинга в Tarantool.
+ Обзор Tarantool upstream модуля для Nginx.
+ Результаты нагрузочного тестирования Tarantool шардинга в связке с Nginx модулем.
+ Live-demo: распределенное отображение графа категорий Wikipedia в СУБД Tarantool с единой точкой входа и возможностью реалтайм поиска по категориям.
Отказоустойчивая обработка 10M OAuth токенов на Tarantool / Владимир Перепели...Ontico
Многие современные высоконагруженные системы построены с использованием очередей. Не является исключением и внутренний сервис обработки OAuth токенов, который создала наша команда. Исключением является то, что и в качестве основного хранилища, и в качестве всех очередей используется один и тот же продукт - Tarantool. Более того, мы поставили себе амбициозную цель по отказоустойчивости - полную доступность сервиса, когда уходят любые два из трёх датацентров, и успешно её достигли.
При решении мы столкнулись с массой интересных инженерных задач и в нашем докладе мы расскажем вам о том, какие технологии и подходы использовались. В частности, рассмотрим более детально такие вещи, как:
- создание deadline очереди и проблемы, с ней связанные;
- создание кольцевой очереди;
- интеграция между собой шардинга, Raft и очередей;
- как мы победили split brain ;)
сравнение производительности СУБД MySQL и PostgreSQL для "типичной задачи стартапа".
Презентация сопровождала тестовую online-сессию и потому не содержит результатов тестирования.
Чем заняться вечером, если я знаю сколько будет ++i + ++i / Андрей Бородин (Y...Ontico
HighLoad++ 2017
Зал «Пекин + Шанхай», 8 ноября, 18:00
Тезисы:
http://www.highload.ru/2017/abstracts/2960.html
При изучении алгоритмов и структур данных я предлагаю студентам закрепить знания и попытаться сделать мир лучше, выполнив небольшие проекты по внедрению эффективных алгоритмов в свободное программное обеспечение. В этом докладе я расскажу несколько идей для таких проектов.
Мы рассмотрим существующие фрагменты исходного кода, поговорим о том, что в нём можно допилить, и обсудим, сколько баллов за это надо давать.
Реализацией идей могут заняться, разумеется, все желающие.
Flashcache в mamba.ru / Яковлев Александр Юрьевич (ЗАО Мамба)Ontico
Некоторое время назад, когда в очередной раз встал вопрос о производительности большого парка mysql sharding серверов, мы не захотели покупать новые сервера и производить resharding. Мы обнаружили, что компания facebook выпустила в opensource большое количество своих разработок, в том числе и модуль ядра flashcache.
Flashcache — модуль для кэширования блоков блочного устройства, предоставляющий 4 разных режима кэширования.
В данном докладе я расскажу, как мы тестировали, поэтапно проверяя под нагрузкой, 3 из 4 режимов кэширования, сравнивая и выбирая оптимальный. Итогом данной работы стало внедрение данного модуля в нашу архитектуру (фотосервера, сервера БД).
Что особенного в СУБД для данных в оперативной памяти / Константин Осипов (Ta...Ontico
Оперативная память становится всё более дешёвой и производительной, что позволяет использовать её для хранения рабочего набора данных всё большего числа приложений. Хранение всех данных в оперативной памяти позволяет сделать их высоко доступными, а алгоритмы для работы с данными либо существенно упростить, либо ускорить, а иногда — и то, и другое.
Тезисы - http://www.highload.ru/2015/abstracts/1964.html
Реализация восстановления после аварий / Сергей Бурладян (Avito)Ontico
Базы данных PostgreSQL занимают одно из центральных мест в Авито. Они являются разделяемой платформой, вокруг которой построено множество дополнительных сервисов. Одной из основных задач при их администрировании является задача восстановления после аварий как самих баз, так и связанной с ними инфраструктуры.
В своём докладе я постараюсь рассказать про:
+ общую схему связей баз данных между собой и с другими компонентами;
+ точки отказа и виды аварий, затрагиваемые связи;
+ бинарную репликацию и архив;
+ логическую репликацию, pgq, londiste, UNDO (REDO), пересоздание репки;
+ скрипт и процедуру переключения при аварии;
+ планы: развитие «восстановлений» по всем связям, автоматика на основе системы zookeeper (etcd и т.п.).
Модульность и управляемая многопоточность встраиваемых С++ приложений - трудн...corehard_by
- Организация программной системы как совокупности модулей, интерфейсов и управляющих систем.
- Многопоточность - предпосылки для использования и объективная необходимость.
- Организация многопоточности при проектировании алгоритмов, основанных на событиях.
Отладка и устранение проблем в PostgreSQL Streaming Replication.Alexey Lesovsky
Потоковая репликация, которая появилась в 2010 году, стала одной из прорывных фич постгреса и в настоящее время практически ни одна инсталляция не обходится без использования потоковой репликации. Она надежна, легка в настройке, нетребовательна к ресурсам. Однако при всех своих положительных качествах, при её эксплуатации могут возникать различные проблемы и неприятные ситуации. Для диагностики и решения проблем, связанных с потоковой репликацией, есть множество инструментов, как встроенных в PostgreSQL, так и сторонних.
В этом докладе я сделаю обзор доступных инструментов и расскажу, как с помощью этих средств диагностировать различные типы проблем и как устранять их. Рассматривая методы решения, мы также рассмотрим проблемы, которые возникают при эксплуатации потоковой репликации.
Доклад будет полезен DBA и системным администраторам.
Защита данных и датацентров от катастроф. Подход Nutanix / Максим Шапошников ...Ontico
+ Защита данных — это не "одна кнопка", нет годного любому единого решения. Задача всегда диктует выбор средств и решений.
+ RTO — Recovery Time Objective — максимальное время, за которое все ваши бизнес-задачи должны полностью быть восстановлены в работоспособное состояние после полной катастрофы ДЦ.
+ RPO — Recovery Point Objective — максимально приемлемый для ваших задач промежуток времени, за который вы готовы потерять данные.
+ Защита на уровне приложений. Приложение лучше всех знает, как защищать и реплицировать свои данные.
+ Асинхронная репликация — наилучший выход с точки зрения производительности, единственно возможный вариант в случае значительного географического разнесения дата-центров (сотни и более километров). Работает на уровне виртуальных машин.
+ Метро / "растянутые" кластеры и синхронная репликация — нулевой RPO, минимальный RTO, большие потери производительности и множество ограничений. Но иногда — единственный выход, если уровень приложения не умеет реплицировать данные.
+ Лучший подход — комбинация из репликации на уровне приложений, асинхронной и синхронной репликации средствами хранилища.
+ Что есть у Nutanix для решения подобных задач: DR (Async replication), Metro availability cluster, Timestream Backup.
+ Реализация решения с использованием Nutanix на примере FBI: крупнейший VDI в США. Защищенная, mission-critical инфраструктура на 70 тысяч виртуальных десктопов. Асинхронная репликация дата-центров на 1500 миль, защита данных от катастроф.
PostgreSQL: практические примеры оптимизации SQL-запросов / Иван Фролков (Po...Ontico
Довольно часто как адинистраторы, так и разработчики жалуются на низкую производительность приложений, работающих с базой данных, и нередко при этом ищут решения возникших проблем с помощью различных настроек как СУБД, так и операционной системы, пренебрегая при этом самым действенным способом - оптимизацией запросов к собственно БД.
Тому, как понимать, где же узкие места, и как их можно попробовать избежать на примере PostgreSQL и посвящен этот доклад.
SOA: строим свой service mesh / Иван Круглов (Booking.com)Ontico
HighLoad++ 2017
Зал «Дели + Калькутта», 8 ноября, 13:00
Тезисы:
http://www.highload.ru/2017/abstracts/3006.html
Service mesh - это выделенный слой в инфраструктуре компании, который призван упростить взаимодействие между сервисами, а также сделать его надежным и безопасным. В юрисдикцию service mesh, по разным мнениям, входят: маршрутизация запросов, service discovery, балансировка, обработка ошибок, мониторинг, трейсинг, авторизация и аутентификация и др. вещи. Реализация тоже варьируется от размазывания функционала по всему стеку до концентрации большей части его в одной точке.
...
В рамках магистерского курса "Параллельные вычисления" на кафедре КСПТ прочитал лекцию "Actor Model":
* Actor Model
* Futures and Promises
* Примеры систем
Современная операционная система: что надо знать разработчику / Александр Кри...Ontico
Мы проговорим про связь приложения и ОС, какие компоненты есть в современной ОС на примере Linux, как настройки этих компонент могут повлиять на приложение.
Я расскажу про планировщик процессов, дисковый и сетевой ввод-вывод и соответствующие планировщики, управление памятью - как это все в общих чертах работает и как его потюнить.
Мониторинг ожиданий в PostgreSQL / Курбангалиев Ильдус (Postgres Professional)Ontico
В многоядерных высоконагруженных системах с высокой конкурентностью часто бывает сложно определить, чем занят отдельный процесс PostgreSQL. Он может находиться в ожидании локов высокого уровня, таких как локи таблиц, внутренних локов, используемых для синхронизации процессов, ввода-вывода и многих других.
В настоящий момент среди всех событий ожидания мониторить можно только локи высокого уровня с помощью представлений PostgreSQL. Другие типы ожиданий требуют использования низкоуровневых утилит типа perf, systemtap и других. Эти утилиты требуют специальных знаний и могут быть платформозависимыми. В то же время другие enterprise базы данных уже включают в себя инструменты для мониторинга ожиданий.
Мы разработали патч, который реализует мониторинг ожиданий в PostgreSQL. С минимальной настройкой (несколько конфигурационных параметров) этот патч показывает полную информацию о текущих ожиданиях в режиме реального времени и с небольшим оверхедом на всю систему. Этот патч уже работает на продакшен серверах Яндекса и показал свою полезность.
DNS в условиях хостинг-провайдера / Константин Новаковский (Selectel)Ontico
DNS — это одна из основополагающих служб и протоколов современного интернета, сервис, который должен всегда работать. Каждый раз, когда конечный пользователь обращается к какому-либо ресурсу глобальной паутины, он использует DNS, и чтобы этот самый первый шаг к проектам у наших клиентов не занимал много времени, мы построили свой DNS-хостинг с использованием Anycast-балансировки. Чуть позже мы применили этот метод для балансировки и повышения доступности рекурсивных серверов внутри наших дата-центров.
В своём докладе я расскажу о способах обеспечения непрерывного обслуживания DNS-запросов, подводных камнях использования anycast’а, постараюсь раскрыть актуальные проблемы обслуживания DNS-серверов и поведаю о современных тенденциях в мире DNS.
Раздатчик музыки непосредственно занимается отдачей байтов аудиопотока многочисленным пользователям https://ok.ru/music. В пике суммарный трафик достигает 100 Гб/с через сотни тысяч соединений, а время до первого байта составляет не больше 100 мс. Предыдущая версия раздатчика на основе файлов и Apache Tomcat не устраивала нас требуемым количеством оборудования и неспособностью утилизировать современное железо. При разработке новой версии мы поставили перед собой цель сохранить внешнюю функциональность сервиса неизменной, но обойтись существенно меньшим количеством машин, сохранив при этом масштабируемость и отказоустойчивость сервиса.
В докладе мы рассмотрим, как различные архитектурные решения помогли нам обеспечить масштабируемость и отказоустойчивость сервиса за счёт распределения и репликации музыкальных треков между нодами. Затем подробно поговорим про устройство отдельной ноды, включая отказоустойчивую подсистему хранения, сетевую подсистему, а также использование подхода reactive streams. Уделим особое внимание собранным граблям и трюкам, позволившим увеличить производительность системы, упростить отладку и эксплуатацию системы.
Доклад ориентирован на разработчиков, которые хотят расширить свой арсенал подходов и инструментов для создания распределённых и/или высоконагруженных систем с интенсивным I/O.
Строим сервисы на базе Nginx и Tarantool / Василий Сошников, Андрей Дроздов (...Ontico
Слушатели этого доклада получат представление о том, как построить отказоустойчивое, быстрое, простое и легко масштабируемое решение на базе Nginx и Tarantool.
Коротко о главном:
+ Обзор внутреннего устройства шардинга в Tarantool.
+ Обзор Tarantool upstream модуля для Nginx.
+ Результаты нагрузочного тестирования Tarantool шардинга в связке с Nginx модулем.
+ Live-demo: распределенное отображение графа категорий Wikipedia в СУБД Tarantool с единой точкой входа и возможностью реалтайм поиска по категориям.
Отказоустойчивая обработка 10M OAuth токенов на Tarantool / Владимир Перепели...Ontico
Многие современные высоконагруженные системы построены с использованием очередей. Не является исключением и внутренний сервис обработки OAuth токенов, который создала наша команда. Исключением является то, что и в качестве основного хранилища, и в качестве всех очередей используется один и тот же продукт - Tarantool. Более того, мы поставили себе амбициозную цель по отказоустойчивости - полную доступность сервиса, когда уходят любые два из трёх датацентров, и успешно её достигли.
При решении мы столкнулись с массой интересных инженерных задач и в нашем докладе мы расскажем вам о том, какие технологии и подходы использовались. В частности, рассмотрим более детально такие вещи, как:
- создание deadline очереди и проблемы, с ней связанные;
- создание кольцевой очереди;
- интеграция между собой шардинга, Raft и очередей;
- как мы победили split brain ;)
сравнение производительности СУБД MySQL и PostgreSQL для "типичной задачи стартапа".
Презентация сопровождала тестовую online-сессию и потому не содержит результатов тестирования.
Чем заняться вечером, если я знаю сколько будет ++i + ++i / Андрей Бородин (Y...Ontico
HighLoad++ 2017
Зал «Пекин + Шанхай», 8 ноября, 18:00
Тезисы:
http://www.highload.ru/2017/abstracts/2960.html
При изучении алгоритмов и структур данных я предлагаю студентам закрепить знания и попытаться сделать мир лучше, выполнив небольшие проекты по внедрению эффективных алгоритмов в свободное программное обеспечение. В этом докладе я расскажу несколько идей для таких проектов.
Мы рассмотрим существующие фрагменты исходного кода, поговорим о том, что в нём можно допилить, и обсудим, сколько баллов за это надо давать.
Реализацией идей могут заняться, разумеется, все желающие.
Flashcache в mamba.ru / Яковлев Александр Юрьевич (ЗАО Мамба)Ontico
Некоторое время назад, когда в очередной раз встал вопрос о производительности большого парка mysql sharding серверов, мы не захотели покупать новые сервера и производить resharding. Мы обнаружили, что компания facebook выпустила в opensource большое количество своих разработок, в том числе и модуль ядра flashcache.
Flashcache — модуль для кэширования блоков блочного устройства, предоставляющий 4 разных режима кэширования.
В данном докладе я расскажу, как мы тестировали, поэтапно проверяя под нагрузкой, 3 из 4 режимов кэширования, сравнивая и выбирая оптимальный. Итогом данной работы стало внедрение данного модуля в нашу архитектуру (фотосервера, сервера БД).
Что особенного в СУБД для данных в оперативной памяти / Константин Осипов (Ta...Ontico
Оперативная память становится всё более дешёвой и производительной, что позволяет использовать её для хранения рабочего набора данных всё большего числа приложений. Хранение всех данных в оперативной памяти позволяет сделать их высоко доступными, а алгоритмы для работы с данными либо существенно упростить, либо ускорить, а иногда — и то, и другое.
Тезисы - http://www.highload.ru/2015/abstracts/1964.html
Реализация восстановления после аварий / Сергей Бурладян (Avito)Ontico
Базы данных PostgreSQL занимают одно из центральных мест в Авито. Они являются разделяемой платформой, вокруг которой построено множество дополнительных сервисов. Одной из основных задач при их администрировании является задача восстановления после аварий как самих баз, так и связанной с ними инфраструктуры.
В своём докладе я постараюсь рассказать про:
+ общую схему связей баз данных между собой и с другими компонентами;
+ точки отказа и виды аварий, затрагиваемые связи;
+ бинарную репликацию и архив;
+ логическую репликацию, pgq, londiste, UNDO (REDO), пересоздание репки;
+ скрипт и процедуру переключения при аварии;
+ планы: развитие «восстановлений» по всем связям, автоматика на основе системы zookeeper (etcd и т.п.).
Модульность и управляемая многопоточность встраиваемых С++ приложений - трудн...corehard_by
- Организация программной системы как совокупности модулей, интерфейсов и управляющих систем.
- Многопоточность - предпосылки для использования и объективная необходимость.
- Организация многопоточности при проектировании алгоритмов, основанных на событиях.
Отладка и устранение проблем в PostgreSQL Streaming Replication.Alexey Lesovsky
Потоковая репликация, которая появилась в 2010 году, стала одной из прорывных фич постгреса и в настоящее время практически ни одна инсталляция не обходится без использования потоковой репликации. Она надежна, легка в настройке, нетребовательна к ресурсам. Однако при всех своих положительных качествах, при её эксплуатации могут возникать различные проблемы и неприятные ситуации. Для диагностики и решения проблем, связанных с потоковой репликацией, есть множество инструментов, как встроенных в PostgreSQL, так и сторонних.
В этом докладе я сделаю обзор доступных инструментов и расскажу, как с помощью этих средств диагностировать различные типы проблем и как устранять их. Рассматривая методы решения, мы также рассмотрим проблемы, которые возникают при эксплуатации потоковой репликации.
Доклад будет полезен DBA и системным администраторам.
Защита данных и датацентров от катастроф. Подход Nutanix / Максим Шапошников ...Ontico
+ Защита данных — это не "одна кнопка", нет годного любому единого решения. Задача всегда диктует выбор средств и решений.
+ RTO — Recovery Time Objective — максимальное время, за которое все ваши бизнес-задачи должны полностью быть восстановлены в работоспособное состояние после полной катастрофы ДЦ.
+ RPO — Recovery Point Objective — максимально приемлемый для ваших задач промежуток времени, за который вы готовы потерять данные.
+ Защита на уровне приложений. Приложение лучше всех знает, как защищать и реплицировать свои данные.
+ Асинхронная репликация — наилучший выход с точки зрения производительности, единственно возможный вариант в случае значительного географического разнесения дата-центров (сотни и более километров). Работает на уровне виртуальных машин.
+ Метро / "растянутые" кластеры и синхронная репликация — нулевой RPO, минимальный RTO, большие потери производительности и множество ограничений. Но иногда — единственный выход, если уровень приложения не умеет реплицировать данные.
+ Лучший подход — комбинация из репликации на уровне приложений, асинхронной и синхронной репликации средствами хранилища.
+ Что есть у Nutanix для решения подобных задач: DR (Async replication), Metro availability cluster, Timestream Backup.
+ Реализация решения с использованием Nutanix на примере FBI: крупнейший VDI в США. Защищенная, mission-critical инфраструктура на 70 тысяч виртуальных десктопов. Асинхронная репликация дата-центров на 1500 миль, защита данных от катастроф.
PostgreSQL: практические примеры оптимизации SQL-запросов / Иван Фролков (Po...Ontico
Довольно часто как адинистраторы, так и разработчики жалуются на низкую производительность приложений, работающих с базой данных, и нередко при этом ищут решения возникших проблем с помощью различных настроек как СУБД, так и операционной системы, пренебрегая при этом самым действенным способом - оптимизацией запросов к собственно БД.
Тому, как понимать, где же узкие места, и как их можно попробовать избежать на примере PostgreSQL и посвящен этот доклад.
SOA: строим свой service mesh / Иван Круглов (Booking.com)Ontico
HighLoad++ 2017
Зал «Дели + Калькутта», 8 ноября, 13:00
Тезисы:
http://www.highload.ru/2017/abstracts/3006.html
Service mesh - это выделенный слой в инфраструктуре компании, который призван упростить взаимодействие между сервисами, а также сделать его надежным и безопасным. В юрисдикцию service mesh, по разным мнениям, входят: маршрутизация запросов, service discovery, балансировка, обработка ошибок, мониторинг, трейсинг, авторизация и аутентификация и др. вещи. Реализация тоже варьируется от размазывания функционала по всему стеку до концентрации большей части его в одной точке.
...
В рамках магистерского курса "Параллельные вычисления" на кафедре КСПТ прочитал лекцию "Actor Model":
* Actor Model
* Futures and Promises
* Примеры систем
Фреймворк Akka и его использование в ЯндексеVadim Tsesko
Доклад с JPoint 2014 (http://javapoint.ru).
Краткое содержание:
* Actor Model на примере Akka
* Происхождение
* Концепции и API
* Примеры кода
* Примеры систем в Яндекс
* Конвейерная обработка данных
* Реактивные иерархические системы
* Опыт разработки и эксплуатации
* Подводные камни
* Проблемы и некоторые решения
* Дополнительные тулы
Объектно-Ориентированное Программирование на C++, Лекции 3 и 4 Dima Dzuba
Описываются возможности C++ по работе с наследованием (virtual, override, final). Описываются механизмы работы с константными переменными и методами (const, mutable, constexpr). Описываются возможности по перегрузке операторов (operator).
Статический анализ: вокруг Java за 60 минутAndrey Karpov
Статический анализ всё больше воспринимается как неотъемлемая часть процесса разработки качественного программного обеспечения. Разумеется, у этой технологии уже есть свои сторонники и противники, но, несмотря на это, тема статического анализа всё более актуальна и требует детального рассмотрения. Рассмотрим, что такое статический анализ, как он применяется и как влияет на качество и надёжность кода. Поговорим о важности раннего обнаружения ошибок и дефектов уязвимости. Рассмотрим существующие инструменты для Java, такие как Sonar Java, FindBugs и анализатор встроенном в среду разработки IntelliJ IDEA. Расскажем историю, почему несмотря на уже существующие инструменты, мы решили разработать PVS-Studio для Java, как мы это делали и что в итоге получилось. В конце затронем вопрос интеграции статических анализаторов кода в большие старые проекты. Другими словами, как увидеть 100500 срабатываний и не упасть духом.
Статический анализ кода: Что? Как? Зачем?Andrey Karpov
Методология статического анализа год за годом зарекомендовывает себя в поисках дефектов в исходном коде программ.
Максим расскажет про:
- методологию статического анализа и какие плюсы и минусы у нее есть;
- технологии этой методологии, которые позволяют выявлять разнообразнейшие дефекты в коде;
- интересные примеры ошибок в реальных проектах, которые были найдены при помощи статического анализа;
- интеграцию инструментов статического анализа в проекты любой сложности, и почему так важно регулярное использование подобных инструментов.
Техносфера Mail.ru Group, МГУ им. М.В. Ломоносова. Курс "Алгоритмы интеллектуальной обработки больших объемов данных", Лекция №5 "Обработка текстов, Naive Bayes"
Лектор - Николай Анохин
Условная вероятность и теорема Байеса. Нормальное распределение. Naive Bayes: multinomial, binomial, gaussian. Сглаживание. Генеративная модель NB и байесовский вывод. Графические модели.
Видео лекции курса https://www.youtube.com/playlist?list=PLrCZzMib1e9pyyrqknouMZbIPf4l3CwUP
ЛЕКЦИЯ 5. Шаблоны многопоточного программирования
Курс "Параллельные вычислительные технологии" (ПВТ), весна 2015
Сибирский государственный университет телекоммуникаций и информатики
Пазников Алексей Александрович
к.т.н., доцент кафедры вычислительных систем СибГУТИ
http://cpct.sibsutis.ru/~apaznikov
1. Software Transactional Memory
Курс «Базы данных»
Цесько Вадим Александрович
http://incubos.org
@incubos
Computer Science Center
9 декабря 2013 г.
Цесько В. А. (CompSciCenter)
STM
9 декабря 2013 г.
1 / 63
3. Введение
Мотивация
Мотивация
Задача
Множество изменяемых объектов в памяти
Атомарность наборов операций с объектами
Решение
Software Transactional Memorya :
Память как транзакционное хранилище
Универсальная альтернатива ручным блокировкам
ACI
a
http:
//en.wikipedia.org/wiki/Software_transactional_memory
Цесько В. А. (CompSciCenter)
STM
9 декабря 2013 г.
3 / 63
4. Введение
Идея
Идея
(Очень) оптимистичные транзакции
Если прочитанные значения не менялись, то
commit
В противном случае — retry
Возможен abort в любой момент
Как следствие – max concurrency
Цесько В. А. (CompSciCenter)
STM
9 декабря 2013 г.
4 / 63
5. Введение
Идея
Ручные блокировки
Нужно думать о перекрывающихся операциях
Нужно «держать в голове» весь код
Deadlocks, livelocks, progress, etc.
Очень трудно воспроизвести и отладить
Priority inversion1
1
http://en.wikipedia.org/wiki/Priority_inversion
Цесько В. А. (CompSciCenter)
STM
9 декабря 2013 г.
5 / 63
6. Введение
Идея
Подход STM
Simple
Maintainable
Composable
Не нужно думать о deadlocks и livelocks
Priority inversion — abort низкоприоритетной
транзакции
Но (почти) недопустимы side effects (в т. ч. IO)
Цесько В. А. (CompSciCenter)
STM
9 декабря 2013 г.
6 / 63
8. Введение
Реализации
Scala STM Expert Group
Akka
Stanford
Tel-Aviv University
EPFL
Cisco
etc.
Цесько В. А. (CompSciCenter)
STM
9 декабря 2013 г.
8 / 63
9. Введение
ScalaSTM
С высоты птичьего полёта
Живёт между atomic-блоком и Heap
Перехватывает чтения и записи
Чтения и записи из разных потоков
перемешались — rollback записей и retry
Иначе — commit
Видны только закоммиченые изменения
Принимаем во внимание только Refы
Реализация в виде библиотеки
TSet и TMap
Цесько В. А. (CompSciCenter)
STM
9 декабря 2013 г.
9 / 63
10. Введение
ScalaSTM
Достоинства
Say what you mean
(nested) atomic
Readers scale
CPU cache friendly
Exceptions automatically trigger cleanup
By default
Waiting for complex conditions is easy
retry, chaining
Simple
Just a library
Цесько В. А. (CompSciCenter)
STM
9 декабря 2013 г.
10 / 63
11. Введение
ScalaSTM
Недостатки
Two extra characters per read or write
x: Ref
Read: x()
Write: x() = y
Single-thread overheads
Но полезен rollback при исключениях
Rollback doesn’t mix well with I/O
Но есть хуки
Цесько В. А. (CompSciCenter)
STM
9 декабря 2013 г.
11 / 63
12. Примеры
API
Basic
1
import scala.concurrent.stm._
2
3
4
5
val x = Ref(0) // allocate a Ref[Int]
val y = Ref.make[String]() // type-specific default
val z = x.single // Ref.View[Int]
6
7
8
9
10
11
12
13
14
15
16
atomic { implicit txn =>
val i = x() // read
y() = "x was " + i // write
val eq = atomic { implicit txn => // nested atomic
// both Ref and Ref.View can be used inside atomic
x() == z()
}
assert(eq)
y.set(y.get + ", long-form access")
}
Цесько В. А. (CompSciCenter)
STM
9 декабря 2013 г.
12 / 63
13. Примеры
API
Advanced
1
2
3
// only Ref.View can be used outside atomic
println("y was ’" + y.single() + "’")
println("z was " + z())
4
5
6
7
8
9
10
11
atomic { implicit txn =>
y() = y() + ", first alternative"
if (x getWith { _ > 0 }) // read via a function
retry // try alternatives or block
} orAtomic { implicit txn =>
y() = y() + ", second alternative"
}
12
13
14
15
16
17
val prev = z.swap(10) // atomic swap
val success = z.compareAndSet(10, 11) // atomic compare-and-set
z.transform { _ max 20 } // atomic transformation
val pre = y.single.getAndTransform { _.toUpperCase }
val post = y.single.transformAndGet { _.filterNot { _ == ’ ’ } }
Цесько В. А. (CompSciCenter)
STM
9 декабря 2013 г.
13 / 63
14. Примеры
Doubly-linked list
Use Ref for shared variables
1
import scala.concurrent.stm._
2
3
4
5
6
7
8
9
10
11
class ConcurrentIntList {
private class Node(
val elem: Int,
prev0: Node,
next0: Node) {
val isHeader = prev0 == null
val prev = Ref(if (isHeader) this else prev0)
val next = Ref(if (isHeader) this else next0)
}
12
13
private val header = new Node(-1, null, null)
Цесько В. А. (CompSciCenter)
STM
9 декабря 2013 г.
14 / 63
15. Примеры
Doubly-linked list
Wrap your code in atomic
1
2
3
4
5
6
7
8
def addLast(elem: Int) {
atomic { implicit txn =>
val p = header.prev()
val newNode = new Node(elem, p, header)
p.next() = newNode
header.prev() = newNode
}
}
Цесько В. А. (CompSciCenter)
STM
9 декабря 2013 г.
15 / 63
16. Примеры
Doubly-linked list
Compose atomic operations
1
2
3
4
5
6
7
def addLast(e1: Int, e2: Int, elems: Int*) {
atomic { implicit txn =>
addLast(e1)
addLast(e2)
elems foreach { addLast(_) }
}
}
Цесько В. А. (CompSciCenter)
STM
9 декабря 2013 г.
16 / 63
17. Примеры
Doubly-linked list
Optimize single-operation transactions
Ref.View:
Получение через Ref.single
Можно использовать вне atomic
Поддерживает транзакции из одной операции
swap, compareAndSet, transform, etc.
Пример:
1
2
3
4
5
/*
def isEmpty = atomic { implicit t =>
header.next() == header
}
*/
6
7
def isEmpty = header.next.single() == header
Цесько В. А. (CompSciCenter)
STM
9 декабря 2013 г.
17 / 63
18. Примеры
Doubly-linked list
Wait for conditions to change
1
2
3
4
5
6
7
8
9
10
def removeFirst(): Int =
atomic { implicit txn =>
val n = header.next()
if (n == header)
retry
val nn = n.next()
header.next() = nn
nn.prev() = header
n.elem
}
Цесько В. А. (CompSciCenter)
STM
9 декабря 2013 г.
18 / 63
19. Примеры
Doubly-linked list
Wait for multiple events
1
2
3
4
5
6
7
def maybeRemoveFirst(): Option[Int] = {
atomic { implicit txn =>
Some(removeFirst())
} orAtomic { implicit txn =>
None
}
}
Цесько В. А. (CompSciCenter)
STM
9 декабря 2013 г.
19 / 63
20. Примеры
Doubly-linked list
Composition: select
1
2
3
4
5
6
7
8
9
10
11
12
object ConcurrentIntList {
def select(stacks: ConcurrentIntList*):
(ConcurrentIntList, Int) =
atomic { implicit txn =>
for (s <− stacks) {
s.maybeRemoveFirst() match {
case Some(e) => return (s -> e)
case None => _
}
}
retry
}
Цесько В. А. (CompSciCenter)
STM
9 декабря 2013 г.
20 / 63
21. Примеры
Doubly-linked list
Be careful about rollback (1)
1
2
3
4
5
6
7
8
9
10
11
12
def badToString: String = {
val buf = new StringBuilder("ConcurrentIntList(")
atomic { implicit txn =>
var n = header.next()
while (n != header) {
buf ++= n.elem.toString
n = n.next()
if (n != header) buf ++= ","
}
}
buf ++= ")" toString
}
Цесько В. А. (CompSciCenter)
STM
9 декабря 2013 г.
21 / 63
22. Примеры
Doubly-linked list
Be careful about rollback (2)
1
2
3
4
5
6
7
8
9
10
11
12
override def toString: String = {
atomic { implicit txn =>
val buf = new StringBuilder("ConcurrentIntList(")
var n = header.next()
while (n != header) {
buf ++= n.elem.toString
n = n.next()
if (n != header) buf ++= ","
}
buf ++= ")" toString
}
}
Цесько В. А. (CompSciCenter)
STM
9 декабря 2013 г.
22 / 63
24. Примеры
Indexed Map
API
1
2
3
4
5
6
7
8
9
10
11
12
13
14
scala> case class User(id: Int, name: String, likes: Set[String])
scala> val m = new IndexedMap[Int, User]
scala> m.put(10, User(10, "alice", Set("scala", "climbing")))
res0: Option[User] = None
scala> val byName = m.addIndex { (id,u) => Some(u.name) }
byName: (String) => Map[Int,User] = <function1>
scala> val byLike = m.addIndex { (id,u) => u.likes }
byLike: (String) => Map[Int,User] = <function1>
scala> m.put(11, User(11, "bob", Set("scala", "skiing")))
res1: Option[User] = None
scala> byName("alice")
res2: Map[Int,User] = Map((10,User(10,alice,Set(scala,
climbing))))
scala> byLike("scala").values map { _.name }
res3: Iterable[String] = List(alice, bob)
Цесько В. А. (CompSciCenter)
STM
9 декабря 2013 г.
24 / 63
25. Примеры
Indexed Map
A high-level sketch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import scala.concurrent.stm._
class IndexedMap[A, B] {
private val contents = TMap.empty[A, B]
// TODO def addIndex(view: ?): ?
def get(key: A): Option[B] = contents.single.get(key)
def put(key: A, value: B): Option[B] =
atomic { implicit txn =>
val prev = contents.put(key, value)
// TODO: update indices
prev
}
def remove(key: A): Option[B] =
atomic { implicit txn =>
val prev = contents.remove(key)
// TODO: update indices
prev
}
}
Цесько В. А. (CompSciCenter)
STM
9 декабря 2013 г.
25 / 63
26. Примеры
Indexed Map
Types for the view function and index
Помедитируем:
1
2
def addIndex(view: ((A, B) => Iterable[C])):
(C => Map[A, B]) = ...
Цесько В. А. (CompSciCenter)
STM
9 декабря 2013 г.
26 / 63
27. Примеры
Indexed Map
Tracking and updating indices (1)
1
2
3
4
5
private class Index[C](view: (A, B) => Iterable[C])
extends (C => Map[A, B]) {
def += (kv: (A, B)) // TODO
def -= (kv: (A, B)) // TODO
}
6
7
private val indices = Ref(List.empty[Index[_]])
8
9
10
11
12
13
14
15
16
def addIndex[C](view: (A, B) => Iterable[C]):
(C => Map[A, B]) =
atomic { implicit txn =>
val index = new Index(view)
indices() = index :: indices()
contents foreach { index += _ }
index
}
Цесько В. А. (CompSciCenter)
STM
9 декабря 2013 г.
27 / 63
28. Примеры
Indexed Map
Tracking and updating indices (2)
1
2
3
4
5
6
7
def put(key: A, value: B): Option[B] =
atomic { implicit txn =>
val prev = contents.put(key, value)
for (p <− prev; i <− indices()) i -= (key -> p)
for (i <− indices()) i += (key -> value)
prev
}
8
9
10
11
12
13
14
def remove(key: A): Option[B] =
atomic { implicit txn =>
val prev = contents.remove(key)
for (p <− prev; i <− indices()) i -= (key -> p)
prev
}
Цесько В. А. (CompSciCenter)
STM
9 декабря 2013 г.
28 / 63
29. Примеры
Indexed Map
Index internals
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
private class Index[C](view: (A, B) => Iterable[C])
extends (C => Map[A, B]) {
val mapping = TMap.empty[C, Map[A, B]]
def apply(derived: C) =
mapping.single.getOrElse(derived, Map.empty[A, B])
def += (kv: (A, B))(implicit txn: InTxn) {
for (c <− view(kv._1, kv._2))
mapping(c) = apply(c) + kv
}
def -= (kv: (A, B))(implicit txn: InTxn) {
for (c <− view(kv._1, kv._2)) {
val after = mapping(c) - kv._1
if (after.isEmpty)
mapping -= c
else
mapping(c) = after
}
}
Цесько В. А. (CompSciCenter)
STM
9 декабря 2013 г.
29 / 63
31. Примеры
Dining Philosophers
STM solution
1
class Fork { val inUse = Ref(false) }
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def meal(left: Fork, right: Fork) {
// thinking
atomic { implicit txn =>
if (left.inUse() || right.inUse())
retry // forks are not both ready, wait
left.inUse() = true
right.inUse() = true
}
// eating
atomic { implicit txn =>
left.inUse() = false
right.inUse() = false
}
}
Цесько В. А. (CompSciCenter)
STM
9 декабря 2013 г.
31 / 63
32. Internals
Waiting
Waiting
retry в atomic ≈ wait() в synchronized, но retry:
Безопаснее
STM определяет модификации Ref, ведущие к
пробуждению (вместо notifyAll)
Невозможны «потерянные» пробуждения
Эффективнее
Нет «лишних» пробуждений
Можно ожидать на любых условиях, а не только на
предопределённых
Цесько В. А. (CompSciCenter)
STM
9 декабря 2013 г.
32 / 63
33. Internals
Waiting
Search with backtracking (1)
Optimistic concurrency control as a search with
backtracking:
1
val (x, y) = (Ref(10), Ref(0))
2
3
4
5
6
7
def sum = atomic { implicit txn =>
val a = x()
val b = y()
a + b
}
8
9
10
11
12
13
14
def transfer(n: Int) {
atomic { implicit txn =>
x -= n
y += n
}
}
Цесько В. А. (CompSciCenter)
STM
9 декабря 2013 г.
33 / 63
34. Internals
Waiting
Search with backtracking (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// sum
atomic
| begin txn
| | read x
| |
:
| |
| |
:
| |
| | read y
| roll back
| begin txn
| | read x
| | read y
| commit
+-> 10
attempt
-> 10
-> x read is invalid
// transfer(2)
atomic
| begin txn attempt
| | read x -> 10
| | write x <− 8
| | read y -> 0
| | write y <− 2
| commit
+-> ()
attempt
-> 8
-> 2
Цесько В. А. (CompSciCenter)
STM
9 декабря 2013 г.
34 / 63
35. Internals
Waiting
Retry. Семантика
Вызов retry — сигнал о dead end, даже если все
чтения и записи консистентны
STM откатится и попробует снова
Если некоторые из прочитанных Refов
изменились, то atomic блок может пойти по
другому пути и избежать retry
Условие ожидания retry
Неявно задано потоком управления в atomic-блоке
Цесько В. А. (CompSciCenter)
STM
9 декабря 2013 г.
35 / 63
36. Internals
Waiting
Retry. Эффективность
Примеры:
if (x() <= 10) retry
if (x() == 0 && y() == 0 && z() == 0)
retry
Реализация:
STM отслеживает, к каким Refам обращались
Под капотом — блокирующиеся конструкции
retry: Nothing
Цесько В. А. (CompSciCenter)
STM
9 декабря 2013 г.
36 / 63
38. Internals
Waiting
Alternatives. Пример
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
val msg = atomic { implicit txn =>
if (x() == 0)
retry
x -= 1
"took one from x"
} orAtomic { implicit txn =>
if (y() == 0)
retry
y -= 1
"took one from y"
} orAtomic { implicit txn =>
if (z() == 0)
retry
z -= 1
"took one from z"
}
Цесько В. А. (CompSciCenter)
STM
9 декабря 2013 г.
38 / 63
39. Internals
Waiting
Timeouts
Зачем timeout при retry:
Error logging/handling
No work — waiting thread shutdown
Timeouts in spec of higher-level interface
Способы ограничения retry:
Модифицированный TxnExecutor
(InterruptedException)
retryFor()
Цесько В. А. (CompSciCenter)
STM
9 декабря 2013 г.
39 / 63
40. Internals
Waiting
Timeouts. TxnExecutor
1
2
3
atomic.withRetryTimeout(1000) { implicit txn =>
// any retries in this atomic block will wait for at most
1000 milliseconds
}
4
5
6
7
8
9
val myAtomic = atomic.withRetryTimeout(1, TimeUnit.SECONDS)
myAtomic { implicit txn =>
// this atomic block has a timeout of 1 seconds
}
myAtomic { ... }
10
11
12
13
14
TxnExecutor.transformDefault( _.withRetryTimeout(1000) )
atomic { implicit txn =>
// all atomic blocks now default to a 1 second timeout
}
Цесько В. А. (CompSciCenter)
STM
9 декабря 2013 г.
40 / 63
43. Internals
Maps + Sets
Maps + Sets
Консистентные итераторы у TMap.View и
TSet.View
Быстрые слепки за O(1)
Цесько В. А. (CompSciCenter)
STM
9 декабря 2013 г.
43 / 63
44. Internals
Maps + Sets
Consistent iteration
TMap.View extends mutable.MapLike
get()/put() outside atomic should be atomic
TMap.View.iterator/TSet.View.iterator для
атомарного слепка
Цесько В. А. (CompSciCenter)
STM
9 декабря 2013 г.
44 / 63
45. Internals
Maps + Sets
Inconsistent iteration
1
val m = TMap("one" -> 1).single
2
3
4
5
6
7
8
(new Thread { override def run {
atomic { implicit txn =>
m -= "one"
m += ("ONE" -> 1)
}
} }).start
9
10
for ((k, v) <− m; if v == 1) println(k)
Цесько В. А. (CompSciCenter)
STM
9 декабря 2013 г.
45 / 63
46. Internals
Maps + Sets
Manual snapshots
<TMap|TSet>[.View].snapshot() возвращает
immutable.Map/immutable.Set
<TMap|TSet>.clone()
Цесько В. А. (CompSciCenter)
STM
9 декабря 2013 г.
46 / 63
47. Internals
Maps + Sets
How does it work?
Mutable hash tries from Refs with generation
numbers that control copy-on-write
N. G. Bronson, J. Casper, H. Chafi and K. Olukotun. A
Practical Concurrent Binary Search Tree. 2010.
N. G. Bronson, J. Casper, H. Chafi and K. Olukotun.
Transactional Predication: High-Performance
Concurrent Sets and Maps for STM. In PODC’10:
Proceedings of the 29th Annual ACM Conference on
Principles of Distributed Computing, 2010.
N. G. Bronson. Composable Operations on
High-Performance Concurrent Collections. Ph.D.
Dissertation, Stanford University, 2011.
Цесько В. А. (CompSciCenter)
STM
9 декабря 2013 г.
47 / 63
51. Заключение
Benchmarking
STMBench7
R. Guerraoui, M. Kapalka and J. Vitek. STMBench7:
A Benchmark for Software Transactional Memory.
2007.
A. Dragojevic, R. Guerraoui and M. Kapalka. Dividing
Transactional Memories by Zero. 2008.
Comparison to coarse- and medium-grained locking
See the details4
4
http://nbronson.github.io/scala-stm/benchmark.html
Цесько В. А. (CompSciCenter)
STM
9 декабря 2013 г.
51 / 63
57. Заключение
Bibliography
Bibliography
F. T. Schneider, V. Menon, T. Shpeisman, and
A.-R. Adl-Tabatabai. Dynamic Optimization for
Efficient Strong Atomicity. 2008.
N. G. Bronson, C. Kozyrakis and K. Olukotun.
Feedback-Directed Barrier Optimization in a Strongly
Isolated STM. 2009
V. Menon, S. Balensieger, T. Shpeisman,
A.-R. Adl-Tabatabai, R. L. Hudson, B. Saha and
A. Welc. Practical Weak-Atomicity Semantics for
Java STM. 2008.
K. F. Moore and D. Grossman. High-Level Small-Step
Operational Semantics for transactions. 2008.
Цесько В. А. (CompSciCenter)
STM
9 декабря 2013 г.
57 / 63
58. Заключение
Bibliography continued
Bibliography continued
T. Harris, S. Marlow, S. Peyton-Jones and M. Herlihy.
Composable Memory Transactions. 2005.
R. Hickey. The Clojure Programming Language. 2008
D. Dice, O. Shalev and N. Shavit. Transactional
Locking II. 2006.
T. Riegel, P. Felber and C. Fetzer. A Lazy Snapshot
Algorithm with Eager Validation. 2006.
R. Guerraoui and M. Kapalka. On the Correctness of
Transactional Memory. 2008.
A. Dragojevic, R. Guerraoui and M. Kapalka.
Stretching Transactional Memory. 2009.
Цесько В. А. (CompSciCenter)
STM
9 декабря 2013 г.
58 / 63
59. Заключение
Куда двигаться дальше
Куда двигаться дальше
Herb Sutter. The Free Lunch Is Over. 2009.
Jonas Bon´r. State: You’re Doing It Wrong —
e
Alternative Concurrency Paradigms For The JVM5 .
JavaOne 2009.
ScalaDays 2013. Concurrency — The good, the bad,
the ugly6
Chris Okasaki. Purely Functional Data Structures.
1999
JCIP 2nd edition + JMM
5
http://www.slideshare.net/jboner/
state-youre-doing-it-wrong-javaone-2009
6
http://www.parleys.com/play/51c0bc58e4b0ed877035680a/
Цесько В. А. (CompSciCenter)
STM
9 декабря 2013 г.
59 / 63
61. Домашнее задание
Могут получить зачёт
Могут получить зачёт
Бакрадзе Л.
Грязнов С.
Егоров Д.
Королев Д.
Хомутов В.
Шашкова Е.
Цесько В. А. (CompSciCenter)
STM
9 декабря 2013 г.
61 / 63
62. Домашнее задание
Last Feature Requests
Last Feature Requests
2013-11-18
2013-11-25
2013-12-02
Batches
2013-12-09
Processing
7
FR8: Redis Hashes7
FR9: Compression
FR10: Multithreaded Node + Atomic
FR11: Server Side Filtering and
http://redis.io/commands#hash
Цесько В. А. (CompSciCenter)
STM
9 декабря 2013 г.
62 / 63
63. Вопросы?
Вопросы?
http://incubos.org/contacts/
Общие вопросы — в Twitter: @incubos
Вопросы по лекциям — в комментариях:
http://incubos.org/blog/
Частные вопросы — в почту
vadim.tsesko@gmail.com
Цесько В. А. (CompSciCenter)
STM
9 декабря 2013 г.
63 / 63