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

Like this? Share it with your network

Share

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

  • 1,688 views
Uploaded on

 

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
1,688
On Slideshare
1,372
From Embeds
316
Number of Embeds
2

Actions

Shares
Downloads
12
Comments
0
Likes
0

Embeds 316

http://it-eburg.com 311
http://it-students.net 5

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

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