Как устроены базы данных «ВКонтакте»?
На первом митапе VK Tech Talks | Backend разработчик Команды ВКонтакте Борис Минаев рассказал о том, для чего нужны свои базы данных и как их создать.
Работа «ВКонтакте» начиналась, как и у всех остальных сайтов в то время: пользователь приходит на NGINX или Apache, который даёт статику, затем за динамическим контентом идут в PHP, а PHP идёт в MySQL за пользовательскими данными, которые там лежат.
Но со временем увеличивалась аудитория, росло количество серверов и запросов, и в итоге данные решения стали себя оправдывать. Для эффективного использования серверов стали заменять одни части на другие: PHP был заменён на kPHP, а MySQL-базы были заменены на самонаписанные базы, которые отвечали за какую-то отдельную часть сайта, которые называют движками.
При работе с kPHP транслируется PHP-код в C++, потом берется компилятор g++ и собирается бинарник, который умеет слушать некоторые порты и отвечает на запросы. При этом сами разработчики пишут на том же PHP, который транслируется в «плюсы», что позволяет делать более эффективный код, который работает быстрее.
Движок отвечает за некоторые данные, которые он хранит. Главным отличием от других баз данных заключается в том, что движок понимает, какие данные он хранит, и он может их использовать.
Раньше все движки писались на C, в последние пару лет их пишут на C++, а иногда и на Go.
Микросервисы, как и движки, отвечают за какую-то свою часть данных, а также каждый из них отдалён от других микросервисов. Но движки, в отличие от микросервисов, работают напрямую с данными и их хранением на диске.
Сначала было всего несколько движков. Но позже движки стали создавать для самых высоконагруженных частей сайта, а также для некоторых специфичных задач. На данный момент «ВКонтакте» имеет более 70 движков.
Использование специфики данных, знание, как они устроены, а также возможность использовать другие алгоритмы, дают более быструю работу баз данных «ВКонтакте», чем у стандартных баз данных.


Стоит учесть, что большинство оптимизаций нужно проводить только когда это большой проект, в котором большое количество серверов.
Свои базы данных понадобятся, только если:
- большие масштабы, а также используются много серверов;
- специализированная компания, которая пишет базы данных для крупных проектов.
Простую базу данных можно написать за пару дней, но она при этом не будет иметь крутые преимущества, но она сможет хранить данные и отвечать на запросы пользователей.
Что следует учесть при создании баз данных:
Для своих первых движков «ВКонтакте» использовали протокол Memcached. Это текстовый протокол, который позволяет общаться с Memcached-серверами. Протокол имеет всего несколько запросов, из которых можно выделить два основных: сохранить ключ и достать ключ. Протокол может использоваться для более сложного общения с движками.
Преимущество использования протокола заключается в PHP.
К недостаткам можно отнести:
- Он текстовый, что занимает больше трафика в сети, больше времени на расшифровку и т. д.
- Не понятно, что за числа в запросе.
- Не понятно, как посылать запрос.
Сейчас используется протокол RPC/TL. Его преимущества:
- он бинарный;
- запросы занимают меньше места;
- имеет схему, по которой формируется запрос;
- ошибки отображаются ещё при моменте формирования запроса.
К недостатку можно отнести, что придётся написать своё расширение для PHP, чтобы отправлять запросы.
Поверх чего используется протокол:
Все запросы, которые приходят к движку, можно разделить на два типа:
- запросы, меняющие данные;
- запросы, не меняющие данные.
Если движок перезапускается, то нужно понять, что за данные были в него сохранены, для этого можно ввести лог всех событий, которые изменили данные. Его можно записать в текстовый файл и перечитывать при запуске, но со временем этот лог будет растить и со временем на перезапуск движка будет требоваться больше времени.
Более удобным будет, если из всего лога событий сохранять одну строчку и сохранять в отдельный файл. Такие файлы называются снимками или снепшотами. При перезапуске движка будет прочитываться текущий снимок и события после него.
Генерация снимка — это довольно затратное действие: оно сильно утилизирует диски, потому что записывается много данных. Для этого необходимо уметь держать нагрузку пик, а во время меньших нагрузок — генерировать снимки.
Также есть возможность использовать снимки частично, загружая в оперативную память пул пользователя, от которого идёт запрос. А при долгом не использовании данных выгружать их на жёсткий диск.
Шардирование данных:
Благодаря тому, что данные генерируются ночью, их можно хранить в массивах, что даёт быстрый доступ к ним. Массивы хранятся в снимке. А все изменённые данные хранятся в сбалансированном дереве.
Ещё одной оптимизацией является сжатие данных. На стороне отправителя сжимаются данные, что позволит использовать в 2-3 раза меньше оперативной памяти, а на стороне получателя данные разжимаются.
Можно сделать следующие выводы:
Вот и всё!
Посмотреть полную версию доклада можно в трансляции мероприятия:
независимое интернет-издание о социальных сетях и современных технологиях.
Автор: Лена Гамель
Корректор: Арсений Метелев
