40
Архитектура Ленты на Одноклассниках Алина Васильева разработчик сервиса Лента Одноклассники [email protected]

Архитектура Ленты на Одноклассниках

  • Upload
    neueda

  • View
    4.919

  • Download
    3

Embed Size (px)

Citation preview

Page 1: Архитектура Ленты на Одноклассниках

Архитектура Ленты на Одноклассниках

Алина Васильева

разработчик сервиса ЛентаОдноклассники

[email protected]

Page 2: Архитектура Ленты на Одноклассниках

2

Одноклассники

• Социальный портал• Граф друзей

• Аудитория:– 250 млн аккаунтов– 6 млн пользователей онлайн– более 40 млн посетителей в день

в среднем 90 друзей12 групп

Page 3: Архитектура Ленты на Одноклассниках

3

Лента

Page 4: Архитектура Ленты на Одноклассниках

4

Лента

• Один из ключевых сервисов портала

• Цели– показ пользователю действий и событий друзей и групп– распространение контента по порталу– стимулирование пользователей создавать контент

• Задачи– показ интереснейшего контента максимально большому

количеству пользователей– агрегация– группировка– сортировка– выживание в условиях высокой нагрузки

Page 5: Архитектура Ленты на Одноклассниках

5

События

• В ленту попадают события более чем 100 разных типов– Фото– Статусы– Дружбы– Классы– Подарки– Игры– Группы– Музыка– Видео– и многое другое...

Больше всего добавляется классов к фото

По показам лидируют темы из групп

Page 6: Архитектура Ленты на Одноклассниках

6

Запись и хранение событий

• Для достижения цели необходимо записывать и хранить события каждого пользователя

• Главная сущность: Feed

• Для каждого пользователя нужно хранить List<Feed>

class Feed {

long createDate;

short feedTypeId;

Long referenceId;

...}

Page 7: Архитектура Ленты на Одноклассниках

7

Запись и хранение событий

• SQL ?

• SELECT, JOIN, COUNT...

Page 8: Архитектура Ленты на Одноклассниках

8

Нагрузка

• В час пик пользователи генерируют 1 миллион событий в 5 минут (>3000 операций записи в секунду)

• Запросы ленты конкретного пользователя: >4000 в сек• Запросы общей ленты на главной: >9000 в сек

Page 9: Архитектура Ленты на Одноклассниках

9

История развития хранилища фидов

• SQL решение не рассматривалось изначально

– высокая нагрузка

– необходима высокая доступность

– характер данных, запросов и нагрузки

Page 10: Архитектура Ленты на Одноклассниках

10

История развития хранилища фидов

• Oracle Berkeley DB

– Key / Value хранилище CP-типа– Key: long feedOwnerId– Value: List<Feed> byte[]– Хранятся последние N записей (500)

• Через ~2 года добавили Voldemort + Tarantool

– Key / Value хранилище AP-типа– Хранение данных в памяти– Более высокая производительность– Более высокая доступность– Хранятся последние 30 записей– Использовался одновременно с Berkeley

Page 11: Архитектура Ленты на Одноклассниках

11

Переход на Cassandra

• Причины– Нестабильность Berkeley– Ограничение на объём хранимых данных– Упирались в трафик

• необходимо пересылать по сети все данные

• Преимущества– Высокая доступность, распределённость– Масштабирование, восстановление на ходу– Высокая скорость записи– Скорость чтения не зависит от объема– Возможность реализации бизнес-логики

Page 12: Архитектура Ленты на Одноклассниках

12

Cassandra

• Хранение данных в Column Family– Row Key– Column Key + Column Value + Timestamp

Page 13: Архитектура Ленты на Одноклассниках

13

Хранение фидов в Cassandra

Page 14: Архитектура Ленты на Одноклассниках

14

Общая картина

Feed Proxy - координирующее Java-приложение

Page 15: Архитектура Ленты на Одноклассниках

15

Инфраструктура ленты

• Сервера распределены по трём дата-центрам

Feed Proxy кластер:21 000 запросов/сек

Feed Storage кластер:120 000 запросов/сек

Page 16: Архитектура Ленты на Одноклассниках

16

Инфраструктура ленты

• Выдерживаем потёрю целого дата-центра

Приложенияобновляютсяпутём отключениясерверов в одном ДЦ

Обновлениекластера Proxy:5 минут

Обновлениекластера Storage:30 минут

Page 17: Архитектура Ленты на Одноклассниках

17

Общая лента

• Задача – показ ленты событий от всех друзей

распространениеинформации

получениеинформации

Page 18: Архитектура Ленты на Одноклассниках

18

Общая лента

Page 19: Архитектура Ленты на Одноклассниках

19

Список подписок

• При дружбе пользователи добавляются друг к другу в список подписок (ObservedList)

• Формируется список друзей, за событиями которых пользователь следит и которые попадают к нему в ленту

• Храним список подписок для каждого пользователя

class ObservedList {

List<ObservedItem> items;

...

}

class ObservedItem {

long feedOwnerId;

long lastUserAccessTime; long lastFeedOccurrenceTime;

...

}

Page 20: Архитектура Ленты на Одноклассниках

20

Хранение списка подписок

• SQL снова не подходит– 350 добавлений в секунду (18 млн за сутки)– 9000 чтений в секунду– характер данных и запросов

• Хранили в Berkeley DB, перешли на Cassandra

Page 21: Архитектура Ленты на Одноклассниках

21

1. Получаем список подписок из ObservedList

2. По каждой подписке получаем список фидов из Storage

3. Объединяем, сортируем

Алгоритм сборки общей ленты [simplified]

List<Feed> feeds = new ArrayList<Feed>();

ObservedList observedList = getObservedList(feedFollowerId);

for (ObservedItem item: observedList.getItems()){

List<Feed> userFeeds =

getFeeds(observedItem.getFeedOwnerId());

feeds.addAll(userFeeds);}

Collections.sort(feeds, FEEDS_COMPARATOR);

Выполняетсяна Feed Proxy

Page 22: Архитектура Ленты на Одноклассниках

22

И опять нагрузка

• 9000 запросов получения общей ленты в секунду– даже с учётом кэширования на вебе– помним про 90 друзей и 12 групп у пользователей!– 9000 * 102 = 918 000 походов в базу в секунду

• Базы данных не в состоянии эффективно обработать такое количество запросов

Нужен кеш событий общих лент пользователей

Page 23: Архитектура Ленты на Одноклассниках

23

Feed Cache

• Java-приложение, цель которого получение, хранение и отдача общих лент

Page 24: Архитектура Ленты на Одноклассниках

24

Масштабы Feed Cache

• Самое мощное приложение инфраструктуры ленты

• 64 сервера, распределённые по трём дата-центрам

• Кол-во запросов: 100 тысяч в секунду (~1500 на сервер)

• В кэши входит 100 млн событий в 5 минут

• Трафик: 1 Гб/сек– 10 Мб/сек входящего на 1 сервер– 6 Мб/сек исходящего на 1 сервер

• Объем хранимых данных: 6 ТБ (в RAM)– ~100 ГБ на 1 сервере– в среднем 100 KБ на пользователя

Page 25: Архитектура Ленты на Одноклассниках

25

Хранение данных в Feed Cache

• По ключу идентификатора пользователя хранится список фидов

• Длина списка ограничена– 1000 записей, но, бывает, уменьшаем (при повышенной нагрузке)– специальный алгоритм по вытестению данных из кэша– планируем переход на Cassandra

Page 26: Архитектура Ленты на Одноклассниках

26

Хранение данных в Feed Cache

• Помимо списка фидов хранятся также дополнительные данные– время последнего логина– время последнего открытия ленты– время последнего обновления данных с Feed Proxy– значение последнего выбранного фильтра

• Данные сериализуются и хранятся в Off-Heap памяти

• Раз в 12 часов сервер записывает данные на диск (снепшот)

• При рестарте приложение стартует со снепшота ~8 минут

• При старте без снепшота есть механизмы обеспечивающие плавную загрузку данных

Page 27: Архитектура Ленты на Одноклассниках

27

Кластер Feed Cache

• Шардинг – каждый сервер обслуживает 1/64 часть пользователей– партиционирование по id пользователя

• У каждого сервера есть «заместитель», на который перенаправляются запросы в случае недоступности

• Обновление приложений всего кластера занимает ~1 час (обновление по ¼ серверов)

Page 28: Архитектура Ленты на Одноклассниках

28

Feed Cache - Отдача данных

• Feed Cache запрашивает новые события с Feed Proxy по истечению временного периода (15 минут) – инфраструктура уже выдерживает обновления раз в 1 минуту

Page 29: Архитектура Ленты на Одноклассниках

29

Время последнего события

• И всё же нагрузка на хранилище фидов получается черезмерно большая

• При каждом обновлении на Feed Proxy обходить базы всех друзей неоправданно дорого• ведь новые события могли появиться всего у пары из них, а то

вообще ни у кого

• Решение - отдельно хранить дату добавления последнего события в ленту пользователя

• Отдельная база: Voldemort + Tarantool (key / value)– long feed_owner_id long last_create_date

Page 30: Архитектура Ленты на Одноклассниках

30

База UpdateInfo

• При добавлении нового события обновляется timestamp в базе UpdateInfo

• Далее это значение проверяется при сборке событий для общей ленты

Page 31: Архитектура Ленты на Одноклассниках

31

• Перед запросом в базу Feeds проверяется значение UpdateInfo - появились ли новые события

Алгоритм сборки общей ленты [improved]

public List<Feed> collectRecentFeeds(long feedFollowerId, long

lastUpdated){

1. ПОЛУЧАЕМ СПИСОК ПОДПИСОК (OBSERVED LIST)2. ДЛЯ КАЖДОЙ ПОДПИСКИ

3. ПРОВЕРЯЕМ UpdateInfoif (hasNewFeeds(item.getId(),

lastUpdated)){4. ПОЛУЧАЕМ ФИДЫ5. ДОБАВЛЯЕМ ФИДЫ В ОБЩИЙ

СПИСОК}

}...

}Хотя в UpdateInfo тоже ходим не каждый раз.

Значения кэшируются в ObservedList.

Page 32: Архитектура Ленты на Одноклассниках

32

Группировка событий

• Проблема – повторяющиеся бесполезные события

Page 33: Архитектура Ленты на Одноклассниках

Группировка событий

• Решение – группировка событий

33

• Исключение событий

Page 34: Архитектура Ленты на Одноклассниках

34

Группировка событий

• Решение – инфраструктура мержеров событий

List<Feed> feeds = getFeeds();for (Merger merger: mergers){

merger.mergeFeeds(feeds);}

Длина спискауменьшаетсяна ~25%

Page 35: Архитектура Ленты на Одноклассниках

35

Приоритеты событий

• Проблема – событий много, нужно показать пользователю самое интересное

• Решение – подсчёт весов событий и пересортировка на их основании

• Вес подсчитывается при входе события в Feed Cache

• Также анализируется состояние кэша– подсчитывется сколько событий каких типов уже присутствует в кэше

множество дополнительных коэффициентов и параметров

Page 36: Архитектура Ленты на Одноклассниках

36

Feed Stats

• Отдельное Java-приложение с хранением данных в Cassandra

• Сбор статистики о предпочтениях пользователей

• Записывает действия, которые пользователь совершает по отношению к своим друзьям– 53 000 записей в секунду

• На основании собранной статистики подсчитывает веса друзей

• Далее этот вес используется лентой при подсчёте веса события

Page 37: Архитектура Ленты на Одноклассниках

37

Полная картина

Page 38: Архитектура Ленты на Одноклассниках

38

Real-time доставка событий

• Проблема: чтобы увидеть новые события пользователю необходимо обновить страницу

• С учётом многоуровнего кэширования и ограничений новое событие может прийти в ленту с задержкой

• Задача: доставлять события в ленты пользователей моментально и автоматически

Page 39: Архитектура Ленты на Одноклассниках

39

Real-time доставка событий

После добавления нового события Feed Storage нотифицирует Feed Cache друзей в онлайне, отсылая им фид, который далее переправляется прямо на Web

Page 40: Архитектура Ленты на Одноклассниках

Спасибо!

Алина Васильева

разработчик сервиса ЛентаОдноклассники

[email protected]/alina

[email protected]