Олег Анастасьев "Ближе к Cassandra". Выступление на Cassandra Conf 2013
Upcoming SlideShare
Loading in...5
×
 

Олег Анастасьев "Ближе к Cassandra". Выступление на Cassandra Conf 2013

on

  • 1,363 views

 

Statistics

Views

Total Views
1,363
Views on SlideShare
1,068
Embed Views
295

Actions

Likes
0
Downloads
9
Comments
0

1 Embed 295

http://it-eburg.com 295

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Олег Анастасьев "Ближе к Cassandra". Выступление на Cassandra Conf 2013 Олег Анастасьев "Ближе к Cassandra". Выступление на Cassandra Conf 2013 Presentation Transcript

    • Ближе к Cassandra Олег Анастасьев ведущий разработчик, команда платформы odnoklassniki.ru
    • 7 M онлайн 40M в день, 80M в месяц ! ~ 300 000 www страниц/сек, 20 ms на страницу >280 ГБит/сек ! > 6 600 серверов в 5 ЦОД 99.9% java
    • Cassandra @ * Начинали в 2010 - своя версия, основана на 0.6 - целились в: выживаемость при отказе ЦОД, масштабируемость, простота эксплуатации, адаптируемость * Сейчас - 23 разных кластера - 418 всего нод - 240 TB данных ! - пережили несколько отказов ЦОД
    • “Раз” - котенок ! самый быстрый
    • Класс! 103 927 Вы и 103 927
    • Виджет Класс! * Он везде - На каждой странице по несколько - В ленте активности - На сайтах в Интернетах ! * Он на всем - Картинки и альбомы - Видео - Посты и комментарии - Ссылки на внешние сайты Класс! 103 927
    • Виджет Класс! * Высоко нагруженный - 1 000 000 чтений/сек, 3 000 записей/сек ! * Сложный профиль Класс! 103 927 - Много чтений - Длинный хвост (40% чтений случайны) - Чувствительна к вариациям скорости - 3TB данных (9TB с RF) и растет - ~ 60 млрд класс!ов к ~6 млрд объектов
    • Простое решение SQL табличка 
 RefId:long RefType:byte UserId:long Created 9999999999 PICTURE(2) 11111111111 11:00 ! для отрисовки Вы и 4256 ! SELECT TOP 1 WHERE RefId,RefType,UserId=?,?,? (98% are NONE) ! SELECT COUNT (*) WHERE RefId,RefType=?,? (80% are 0) ! SELECT TOP N * RefId,RefType=? WHERE IsFriend(?,UserId)
    • Простая проблема SQL табличка 
 RefId:long RefType:byte UserId:long Created 9999999999 PICTURE(2) 11111111111 11:00 ! для отрисовки Вы и 4256 ! SELECT TOP 1 WHERE RefId,RefType,UserId=?,?,? (98% are NONE) = N >=1 ! SELECT COUNT (*) WHERE RefId,RefType=?,? (80% are 0) = M>N ! SELECT TOP N * RefId,RefType=? WHERE IsFriend(?,UserId) = N*140
    • Пробуем Cassandra LikeByRef ( refType byte, refId bigint, userId bigint, ! PRIMARY KEY ( (RefType,RefId), UserId) для отрисовки LikeCount ( refType byte, refId bigint, likers counter, ! PRIMARY KEY ( (RefType,RefId)) Вы и 4256 ! SELECT FROM LikeCount WHERE RefId,RefType=?,? (80% are 0) ! SELECT * FROM LikeByRef WHERE RefId,RefType,UserId=?,?,? (98% are NONE) = N*20%
    • >11 M iops * Пробуем решить по быстрому LikeByRef ( ! refType byte, refId bigint, ! userId bigint, ! ! PRIMARY KEY ( (RefType,RefId, UserId) ) ! SELECT TOP N * RefId,RefType=? WHERE IsFriend(?,UserId) - Нужен Order Pres Partitioner (Random не масштабируется) - Запросы по диапазону ключей (KeyRange) - Больше сетевого оверхеда - Партиций >10x, Размер данных > x2
    • Колоночный блум фильтр * Что делает - Хранит пары (PartKey, ColumnKey) в SSTable *-Filter.db ! И это хорошо - Убрали 98 % чтений с диска - Меньше ложных попаданий * Но все таки… - Они стали очень большими * Проблемы с GC Promotion Failures .. фиксим (CASSANDRA-2466)
    • Уже готово ? 1. COUNT() сервер приложений > 400 00 2. EXISTS cassandra - 2 похода для отрисовки (COUNT+RR) - THRIFT медленный, когда много клиентов - EXISTS() дает 200 Gbit/sec (140*8*1Mps*20%)
    • Совместить! get() : LikeSummary odnoklassniki-like Сетевой Бизнес Intf Кеш счетчиков cassandra Кеш соц. графа - one-nio remoting (быстрее родного nio в java) - клиенты знают топологию кластера
    • Вместе это хорошо * Быстрый запрос TOP N друзей 1. Берем друзей из кеша соц графа 2. Проверяем по блум фильтру в памяти 3. Читаем с диска пока получим N ! * Свои кеши - Специализированные под приложение ! * Свое объединение реплик данных - … можно находить и разрешать кофликты
    • Слушаем мутации // Implement it interface StoreApplyListener { boolean preapply(String key, ColumnFamily data); } // and register with CFS store=Table.open(..) .getColumnFamilyStore(..); store.setListener(myListener); * Регистрируем слушателя после применения логов но до госсипа ! * RowMutation.apply() и расширяем логику записей + На репликах, хинты, ReadRepairs
    • Счетчики с быстрым чтением * Кеш счетчиков LikeCount ( refType byte, refId bigint, ip inet, counter int PRIMARY KEY ( (RefType,RefId), - Off heap (sun.misc.Unsafe) - Компакен (30M in 1G RAM) - Читаем только кеш локальной ноды ! * Репликацию кеша - проблема холодного кеша реплик делаем (NOP) записи меньше чтений учитывает длинный хвост
    • Вариации скорости * Что делает Cassandra 1. Взять 1 ноду с данным и CL-1 - дайджест 2. Ждем данные и дайджест 3. Сравниваем и возвращаем (или RR) * Ноды притормаживают - Изза: SEDA, ротируем commit log , внезапно много IO, заткнулась сеть или пропала, внезапно много IO мимо кеша диска… * И что видят клиенты ? - Пики времени обработки запросов - Можно только ждать (до таймаута)
    • Read Latency leveling * “Параллельная” обработка чтений 1. Запрашиваем данные со всех реплик сразу 2. Ждем сколько надо CL ответов реплик ! * И это хорошо - Всегда минимальное время обработки - Та же нагрузка при отказе ЦОД ! * что (не так уж) плохо - “Дополнительная” нагрузка и трафик
    • More tiny tricks * Для SSD io - Deadline IO шедулер - 64k -> 4k размер запроса на чтение ! * Хинт Лог - Коммит лог для хинтов - Ждем доставки всех хинтов на старте ! * Селективый компактор - Чаще читаем из CF - чаще компактим
    • “Два” - котенок ! самый пухлый
    • * Сообщения в чатах - Читаем свежую страницу на открытии - длинный хвост (80%) для остальных - 150 млрд, 100 TB на дисках - Чтений больше: 120k в сек; 8k записей
    • Сообщение это структура Message ( chatId, msgId, ! created, type,userIndex,deletedBy,...
 text ) MessageCF ( chatId, msgId, ! data blob, ! PRIMARY KEY ( chatId, msgId ) - Все сообщения чата в 1 партиции - Каждое представлено блобом для уменьшения накладных расходов ! - Стало плохо Возможны конфиликтующие изменения одного сообщения
 (пользователи, антиспам, чистка,…)
    • Легкое разрешение конфликтов get get (version:ts1, data:d1) (version:ts1, data:d1) write( ts1, data2 ) delete(version:ts1) insert(version: ts2=now(), data2) Messages ( chatId, msgId, version timestamp, data blob PRIMARY KEY ( chatId, msgId, version ) write( ts1, data3 ) delete(version:ts1) insert(version: ts3=now(), data3) (ts2, data2) (ts3, data3) - merged on read
    • Специализированный кеш * Опять. Потому что можем - Off-heap (Unsafe) - Кеширует только свежайшие страницы - Пишет состояние в локальный (system) CF И ключи, и значения последовательное чтение на старте - Компрессия данных в памяти В 2 раза больше памяти бесплатно
    • Делим диски * 4U HDDx24, до 4 TB на сервер - Size tiered compaction = файл до 4 TB - RAID10 ? LCS ? ! * Делим CF на 256 кусочков * Стало хорошо - Более частые, но меньшие сбросы мемтаблиц - Столько же работы для компактора но более мелкими наборами - Можно распределять между дисками
    • Политика распределения * Из коробки - “Берем наиболее свободный по месту диск” * И теперь некоторые из них - слишком нагружены на ввод-вывод ! * По поколениям - На каждом диске хранится одинаковое количество sstables одного поколения работает лучше всех для ЖД
    • “Три” -
 Уродливый и страшный это-ж, братцы, Франкенштейн !
    • * Список чатов - мало данных (230GB) - есть горячий набор, короткий хвост (5%) - список часто пересортировывается - 130k чтений/сек, 21k записей/сек
    • Конфликтные изменения * List<ЧатOverview> в 1 блоб .. или мы получим много могилок ! * Много конфликтов все меняют 1 колонку ! * Определен алгоритм слияния * Нужно детектирования конфликтов
    • Векторные часы * Voldemort - byte[] ключ -> byte[] значение + ВЧ - Все клиенты - координаторы - Заменяемые виды хранилищ ! * Ну и заменили - На СС таблицы от CS 0.6 - Со специализированным кеш кеши. мы знаем как.
    • Скорость * Кластер из 3 нод, RF = 3 - Intel Xeon CPU E5506 2.13GHz 
 RAM: 48Gb, 1x HDD, 1x SSD ! * 8 байт ключ -> 1 KB значение ! * Дает - 75 k чтений/сек и 15 k записей
    • Зачем нам C* ? * Готовые компоненты РБД быстрое хранилище, gossip, надежные асинхронные сообщения, детектор сбоев, топология, последовательная обработка, ... * Данные могут быть структутированы сложнее, чем byte[] ключ -> byte[] значение * Выполнила наши цели * Сделано на java
    • СПАСИБО Олег Анастасьев ! oa@odnoklassniki.ru odnoklassniki.ru/oa @m0nstermind ! github.com/odnoklassniki shared-memory-cache кеш для java вне кучи и в разделяемой памяти one-nio ремотинг быстрее, чем java nio; с автомагической встроенной сериализацией