Мы уже писали о том, как организована работа поиска писем в Яндекс.Почте. С тех много всего изменилось и улучшилось, поэтому мы решили поделиться опытом и рассказать вам об этих изменениях.
В день в Почту приходит порядка 100M писем, 10M из которых — с аттачами. Несмотря на то, что лишь 10% писем содержат вложение, среди писем с вложениями существенная доля тех, в которых файлов больше одного. В среднем получается, что общее количество писем равно суммарному количеству аттачей к ним.
Средний размер письма с аттачем составляет 400 кб, а письма без аттача 4 кб. Суммарный размер аттачей в одном письме может достигать 30 мб. ТОП 10 типов аттачей: .jpg, .pdf, .xls, .rar, .doc, .zip, .eml, .mp3, .tif, .docx. Практически все файловые форматы кроме текстового, содержат существенное количество избыточно служебной информации. Так например: .docx формат, содержит всреднем всего 10 % текстовой информации, а из jpg мы получаем всего 0,25% метаинформации для индексации в поиск.
Это дает суммарный объем входящего трафика порядка 25 Тб в сутки, который увеличивается в разы, чтобы обеспечить функционирование большого и сложного продукта Почта. Для обслуживания такой нагрузки в Яндекс.Почте создана большая сетевая, серверная и сервисная инфраструктура, в которую входит несколько кластеров, распределенных по разным датацентрам.
Все входящие в почту письма попадают в систему доставки — кластер состоящий из сотни серверов. Система доставки пытается сохранить письма в хранилище писем, хранилище метаинформации о письмах и отправить их в поиск — то есть сразу в три разных места, каждое из которых выполняет свои задачи.
Хранилище писем отвечает за хранение и отдачу по запросу всего содержимого каждого письма и исторически почему-то называется mulca. Для хранения писем в Яндекс.Почте развернуто 700 мулечных серверов. Здесь хранятся содержание писем, заголовки, вложения — одним словом, всё, что относится к письму.
Хранилище метаинформации служит для быстрого показа инбокса и содержит только описательную часть письма. Например, поля «От кого», «Кому», «Тема», имя папки, в которой находится письмо в данный момент, его текущая метка, дата написания и т.п. Кластер метаинформации занимает 60 серверов.
Поисковое хранилище — это поисковый индекс, содержащий всю информацию из письма, которая нужна, чтобы обеспечить быстрый полнотекстовый поиск по почтовому ящику с учетом морфологии. Обслуживанием поиска, выполняя задачи индексации и поиска, занимаются сто сорок серверов одновременно.
Письмо считается доставленным, если оно попало в хранилище писем и в хранилище метаинформации. Доставка писем в поиск осуществляется после покладки в хранилища. Под доставку писем в поиск выделен отдельный кластер Services, состоящий из двадцати пяти серверов. На этом кластере расположены очереди писем, ожидающих индексации, и программы, выполняющие подготовку данных для индексации.
Таким образом, письма, попадая в почту, проходят длинный путь. Сначала они складываются в хранилище, потом они попадают в кластер Services, а там готовятся к отправке в поиск.
Но поиск по письмам — это не только поиск по телу письма, но и поиск по содержимому аттачей. Чтобы его обеспечить, файлы, присланные в качестве вложения, нужно предварительно обработать, извлечь текст и уже в текстовом виде отправлять в поиск.
Несколько лет назад мы, не меняя озвученную выше первоначальную архитектуру, запустили поиск по содержимому аттачей. Это повлекло за собой ряд проблем. Во-первых, некоторые типы файлов (особенно .pdf) обрабатывались долго — до нескольких минут, и оттормаживали доставку новых писем в поиск. Во-вторых, между программой индексации и программой конвертации на кластере Services постоянно шла конкуренция за ресурсы, что также замедляло попадание новых писем в поиск. И в-третьих, когда мы стали присылать в кластер Services целиком всё письмо с аттачами, то фактически удвоили почтовый трафик внутри сетей Яндекса. Внутрисетевой трафик увеличился на 25 Тб в сутки, а это нагрузка на полезные для персональных сервисов и для Яндекса в целом ресурсы: сервера, сетевую инфраструктура и суммарную производительность сети.
Итак, нам нужно было бороться за качество сервиса. Нельзя было допустить, чтобы письма приходили в поиск спустя минуты. Тем более, что до запуска поиска по аттачам 95% всех входящих писем попадали в поиск меньше, чем за секунду.
Появилась мысль доставлять письма целиком только в хранилище, а в поиск отдавать лишь структурированный текст прямо из хранилищ. Предварительно проведенные исследования показали, что средний размер текста, необходимого для поиска, в 10 раз меньше среднего размера письма в почте. Следовательно, если в поиск будет приходить только текст, то и потребляемый поиском сетевой трафик будет в 10 раз меньше, что сэкономит примерно 22 Тб в сутки. Кажется, что уже ради экономии трафика игра стоит свеч.
Также была заманчивой идея использовать для предобработки файлов в поиск производительность хранилищ, на два порядка превышающую небольшой кластер Services. Это позволило бы нам ускориться. Так и сделали.
Чтобы озвученную идея можно было реализовать, а мы могли бы получать содержимое писем и аттачей прямо из хранилища, на его серверах необходимо было разместить программу извлечения содержимого аттачей. Эта программа базируется на библиотеке Apache Tika, поэтому для простоты и созвучности с русским языком разработчик назвал ее Tikaite. Размещая Tikaite на mulca-х было важно не навредить хранению писем, поэтому мы детально изучили нагрузку и увидели, что хранилища загружены по дисковому пространству и имеют достаточный свободный ресурс производительности процессора, который можно использовать.
Мы разместили в хранилище программу извлечения текста из разных форматов с жесткими ограничениями: программе было предоставлено 50% производительности процессора и был выделен 1 Гб оперативной памяти на каждом из серверов. Такие ограничения позволили нам запустить процесс конвертации в хранилище и не помешать процессу хранения.
В итоге мы снизили паразитный внутрисетевой трафик и увеличили производительность системы доставки писем в поиск на два порядка — снова 95% писем стали попадать в поиск в течение секунды. На сдачу мы получили дополнительный бонус в 25-ти свободных серверов кластера доставки писем в поиск. Если изначально мы планировали увеличивать кластер Services в 2 раза и получить тут 50 серверов, чтобы справляться с постоянно растущим потоком, то теперь, когда все необходимые для поиска данные готовятся прямо в хранилище писем, у нас по факту целый кластер из 25 серверов стал свободным. Так что в ближайшем будущем мы сможем использовать его для других задач, о чем непременно расскажем.
P.S. А еще для поиска по почте периодически требуется переиндексация всех накопленных за все время существования Яндекс.Почты писем. Это случается, когда необходимо поменять алгоритм поиска, а данных в поиске для этого недостаточно. В это время мы фактически перерабатываем весь массив хранящихся в почте писем, а это сейчас примерно 10 петабайт. И уж тут-то получается просто колоссальная экономия по сетевому трафику и производительности.
P.P.S. Несмотря на полученные результаты, мы не планируем останавливаться на достигнутом. Будем стремимся сделать доставку писем в поиск одновременно с покладкой их в хранилище и для этого будем использовать освободившийся кластер. Ждите информацию об этом в новых публикациях про поиск в Яндекс.Почте.
Автор: bgarkushin