def encrypt_mail(email):if email.user=="badperson":store(email)else:store(encrypt(email))
Здравствуй, %юзернейм%, сегодня я расскажу тебе о том, как правильно зарегистрировать электронную почту
Наверное такого заголовка в ленте постов у вас ещё не было, да? :-) Если мы введём этот вопрос в поисковой системе, то узнаем, что для того чтобы зарегистрировать ящик электронной почты вам нужно зайти на выбранный вами сервис электронной почты, нажать кнопку Зарегистрировать, указать фамилию и имя, выбрать свободный логин, придумать надёжный пароль, указать контрольный вопрос и ответ на него, если есть телефон то привязать. Вроде бы всё. На самом деле Яндекс подсказывает что по этому запросу есть примерно 9 миллионов ответов и мои весьма ценные советы вроде бы никому не нужны, поскольку такая мелочь как регистрация электронной почты в наше время уже ни у кого не вызывает проблем, но, тем не менее, я всё же хочу поделиться с вами опытом о том, как правильно зарегистрировать электронную почту. К сожалению, описанный мною сценарий не избавит вас от дальнейших проблем на 100%, но поможет избавиться от самых очевидных.
В разрезе современной реальности электронная почта это один из двух главных ключей ко всем вашим ресурсам (второй ключ мобильный телефон). Конечно у вас может быть регистрация через сервисы Гугла, Вконтакте, Фейсбук, СберID и т.п., но поскольку для регистрации в этих сервисах вам нужна электронная почта и/или телефон, то будем считать что почта и телефон самые главные.
В наше время чтобы начать бизнес нужно начать общаться с людьми и те предприниматели, кто уже набрался достаточно опыта в бизнесе, обычно для нового бизнеса сразу же заводят новую почту и новый телефон. Это как системные администраторы из анекдота о том, что сисадмины делятся на тех, кто не делает резервные копии и тех, кто уже делает, а, в свою очередь, те, кто делает резервные копии делятся на тех, кто пока ещё не проверяет возможность восстановления из них и уже проверяет. Если у вас ещё нет правила регистрировать новую почту и новый телефон для каждого нового крупного проекта (я имею ввиду бизнес-проекты), то давайте заведём это правило прямо сейчас. А что тут вообще может пойти не так, спросите вы? Раньше я говорил, что, мол, нет никакого смысла перебирать все, что может пойти не так, гораздо проще принять это как аксиому и поэтому предлагал не останавливаться на этом этапе, а сразу же пойти дальше к этапу создания электронной почты. Практика показала, что моё предложение не работает, поэтому приведу часть списка причин, по которым это нужно делать: личную почту и телефон никому не оставишь; при уходе с проекта вас будут донимать звонками и письмами; нужно будет заводить личную почту если хотите давать эту кому-то; будут закидывать спамом и заваливать звонками в любое время. И ещё 100 причин, поэтому давайте сделаем вид, что вы мне поверили, и будем считать, что теперь для каждого нового бизнеса вы будете заводить новую электронную почту.
В плане информационной безопасности этот этап критически важен, так как в дальнейшем практически все сервисы будут завязаны именно на электронную почту и то, насколько хорошо вы все просчитаете заранее, в дальнейшем без преувеличения может повлиять на судьбу бизнеса.
Условно все ящики можно поделить на публичные, т.е. предназначенные для общения с контрагентами и технические, предназначенные для регистрации в различных сервисах. Если вы регистрируете ящик для бизнеса, то в дальнейшем, скорее всего, этот доступ вы начнете предоставлять или передавать, поэтому лучше сразу регистрировать пару ящиков, один технический, один публичный.
Этап первый: почта собственника
А как их, собственно, регистрировать, спросите вы? Давайте по порядку (тут и далее рассматривается вариант регистрации ящика на бесплатный сервисах):
1. Вам нужно определиться с сервисом (Мейл, Яндекс, Гугл или что-то еще) где вы будете регистрировать ваш ящик.
2. Заполните достоверную информацию о себе (как бы банально это не звучало).
3. Запишите все данные о регистрации: дата, время, браузер, IP адрес и другую важную информацию, это пригодится вам в том случае, если потребуется восстанавливать пароль.
4. Привяжите ящик к своему номеру телефона (желательно к тому, которым никто потом не сможет воспользоваться).
5. Установите пароль и запишите его.
6. После активации ящика СМЕНИТЕ ПАРОЛЬ, чтобы рабочий пароль отличался от первого пароля.
После этого у вас будет ящик электронной почты, ради которого и затевался этот квест, а так же все данные о регистрации. Я настоятельно рекомендую удалить из ящика все письма, отправленные в первую секунду его жизни почтовым сервисом, очистить корзину, установить двухфакторную авторизацию и т.п. Хуже не станет. А ещё, самое главное, уберите все данные о регистрации ящика далеко-далеко, но так, чтобы не забыть куда убрали и не потерять. Данные могут никогда не пригодиться, а может случиться так, что через 5 или 10 лет весь ваш бизнес будет зависеть от того, найдете вы эту бумажку или нет.
Этап второй: почта сотрудников
Каждому сотруднику нужна своя электронная почта и это факт. Самая большая ошибка, которую только можно допустить попросить сотрудника работать со своей почты. В этом случае вы в принципе не будете иметь к ней доступа (почта же личная, верно?), при увольнении или уходе в отпуск доступ вам так же не дадут. Обширная практика показывает, что это работает не только в том случае, когда сотрудник использует личную почту, но и в том, если он регистрирует почту специально для работы. Рано или поздно у него там появляется личная переписка, привязываются различные сервисы и т.п.
Разумное решение регистрировать все ящики самому по аналогии с ящиком для руководителя (т.е. скрупулезно сохраняя все данные о регистрации и привязывая к своему номеру телефона), а лучшее использовать почту на домене организации, для чего, кстати, можно использовать все те же Мейл, Яндекс и Гугл они предоставляют возможность подключать свой домен и работать из привычного интерфейса, а так же предлагают специфические плюшки для корпоративных пользователей (бесплатно или платно, в зависимости от потребностей). Тут все совсем просто: вы сами все регистрируете и раздаете пары логин/пароль сотрудникам, при необходимости в любой момент вы можете вернуть или передать доступ буквально одним нажатием кнопки.
Этап третий (и последний): наставления пользователям
Раздаем инструкции конечным пользователям, желательно подробные. По какому адресу заходить на почту, где скачать мобильное приложение, как поменять пароль и т.п. Я понимаю, что все эти данные можно взять в инструкциях почтового сервиса, но практика показывает, что для многих это запредельно и проще давать на бумаге подготовленный текст. Обычно там же я помещаю первых пароль от ящика с требованием сразу же сменить, хотя прекрасно понимаю, что вряд ли кто будет менять.
Не забывайте про то, что почти все сервисы позволяют пересылать все письма в никуда (т.е. когда отправитель ошибся в написании адреса почтового ящика) на конкретный ящик не забудьте настроить. Так же не забывайте отключать доступ к почте у уволенных сотрудников.
Вместо заключения
Напоминаю, что есть федеральный закон О рекламе (N 38-ФЗ) и закон О персональных данных (N 152-ФЗ), согласно этим законам если вдруг ваши менеджеры или кто-нибудь ещё решит скачать где-то базу e-mailов и начать просто так писать на них, то этот метод поиска клиентов может оказаться весьма затратным для вашей организации (постов на Хабре много почитайте). И вот не говорите что это всё паранойя и т.п.
А ещё я бы советовал создать приказ или регламент на тему того, в каких целях можно использовать корпоративную почту, в каких нельзя, можно ли самому регистрировать новую почту и т.п. А то сотрудник уйдёт, а проблемы останутся (это я по своему опыту знаю).
location ^~ /zx/
{
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;
proxy_pass ${web.upstream.zx};
}
sp.nameidformat:urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress ,
sp.entityid: >>example.ru/zx/auth/samlMetadata?domain=example.ru<<,
sp.assertion_consumer_service.url: >>example.ru/zx/auth/saml<<,
idp.single_sign_on_service.url: >>dev-3299935.okta.com/app/dev-3299935_zextrassamlintegration_1/exkvjcggn7C7jrhc75d6/sso/saml<<,
idp.entityid: >>www.okta.com/exkvjcggn7C7jrhc75d6<<,
idp.x509cert: >>MIIDpjCCAo6gAwIBAgIGAXmC9e8bMA0GCSqGSIb3DQEBCwUAMIGTMQswCQYDVQQGEwJVUzETMBEG A1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UECgwET2t0YTEU MBIGA1UECwwLU1NPUHJvdmlkZXIxFDASBgNVBAMMC2Rldi0zMjk5OTM1MRwwGgYJKoZIhvcNAQkB Fg1pbmZvQG9rdGEuY29tMB4XDTIxMDUxOTA0NDkyNloXDTMxMDUxOTA0NTAyNlowgZMxCzAJBgNV BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4gRnJhbmNpc2NvMQ0wCwYD VQQKDARPa3RhMRQwEgYDVQQLDAtTU09Qcm92aWRlcjEUMBIGA1UEAwwLZGV2LTMyOTk5MzUxHDAa BgkqhkiG9w0BCQEWDWluZm9Ab2t0YS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB AQCOJA7bhf/LO89VpuGTHur77RbwKlJg3Eni/P4JKowSVrQD6PghwprCdzThyTsKWcHwESZoYwEL WdrZ6CVzDZWAegWJnaJivfiFlFjsEZ15UHOGizMBM3VI0ePWjaWJ6O2DM9BID2mGULnXUDbQXbf6 rE1EHxzlxzCKIBWmT8ut/JsA/lmBm0YNi4BKfP06KXCLianxoH+fEETNd/NH2mXwgHdxMV1BS/mm TAHSJtkDfWxTM+dTGngrjMANKvmChGjSO1ZXFs/pm+vx0o6ffYcoeXnfgodBX3FZ7aTFBTk0s5Se Wms1utjfa8qhHbrolErqqIc1PPBngEFvzcLjFAfRAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAByU jjdAc5tdH+QFAHS0CJNYa9VNaapxuEFrlR3ZdAztIaczKUqYfHqHdXuDHYCjdHXhLFHwntBsnphk M2sk8D2zG0wpoYsEA3IrvbXoTwwqDzACpLF37S7Pfn0RjE5IvvJ9WP4DoZa9ikM/p0N+H7fpqkU2 xavoiNGOMqot9xpWrytM0P+luXereriOOzVaBS1+DuhA4INhze5luyc52X18T4HrJ3iGivfXR2os L8/PI4gZwR956Ju8tDEcmFVCelLN4FlN3ITogPK+SyKHhlTBuSGHidrGKQJBRmkLhk6lhKWTHjWP mI88ECqrA63+QvxU4KRUl1zzRgKVwrgzos4=<<
А вы знаете, что такое груминг?Не в контексте гибкого подхода к разработке или стрижки собак. Грумингом также называют процесс взаимного вычесывания у обезьян. С его помощью приматы выстраивают отношения друг с другом, создают социальные связи и проходят процесс социальной адаптации. Результатами этого процесса являются условные единицы взаимного уважения, которые учитываются в иерархической системе стаи. Для общества людей, так же как и для приматов, инстинкт самосохранения группы, или иерархический инстинкт, тесно связан с индивидуальным инстинктом самосохранения. Поэтому нам столь важно уметь выстраивать отношения внутри группы. Нейроны, ответственные за размышления об отношениях в обществе, также отвечают и за другие мыслительные процессы.
Насколько наш мозг умеет думать о своих отношениях с людьми, настолько же хорошо мы способны думать обо всем прочем, включая, например, математическое мышление или построение других сложных интеллектуальных объектов.
zmgsautil deleteAccount -a galsync.kf9song4@msk.company.ru
zmgsautil createAccount -a galsync@msk.company.ru -n GAL --domain msk.company.ru -t zimbra -s mail.company.ru -f GAL
Генеральный директор Zextras Паоло Сторти прокомментировал свое решение поддержать Zimbra Open Source: В конце 90-х я начал работать системным администратором Linux. Позже, сосредоточился на предоставлении почтовых решений с открытым исходным кодом. Это было время напряженной работы. Интеграция и поддержка множества разнородных компонентов была постоянной проблемой, ночи и дни были потрачены на то, чтобы найти подходящее решение. Потом появилась Zimbra, и это стало для меня поворотным моментом: мне сразу понравилась возможность предложить комплексное решение, в котором все части идеально сочетаются друг с другом. Как поклонник коммуникационных систем и сторонник Open Source, я нашел в Zimbra все, о чем мечтал. Это причина, по которой я предоставил свою сборку Zimbra 9, чтобы продолжить проект, в который я твердо верю.
Недавно на Хабре вышли две статьи про новую корпоративную почтовую систему Mailion от МойОфис (1, 2) уникальную российскую разработку, которая отличается беспрецедентными возможностями масштабирования и способна работать в системах с более чем 1 миллионом пользователей.
Несложно подсчитать, что для обслуживания такого числа пользователей потребуется колоссальный объем дискового пространства вплоть до десятков петабайт. При этом почтовая система должна уметь быстро обрабатывать эту информацию и надежно хранить её. Сегодня мы объясним общие принципы организации хранения данных внутри почтовой системы Mailion и расскажем, к каким оптимизациям мы прибегли, чтобы значительно снизить количество операций ввода/вывода и сократить требования к инфраструктуре.
Хабр, привет! Меня зовут Виталий Исаев, я занимаюсь разработкой объектного хранилища почтовой системы Mailion. Этой статьёй мы открываем цикл публикаций, посвящённых архитектуре нашего хранилища, его масштабированию, отказоустойчивости и устройству его внутренних подсистем.
Структура электронного письма формировалась в течение последних пятидесяти лет. Этапы её развития зафиксированы несколькими стандартами. Первое электронное письмо было отправлено между компьютерами системы ARPANET ещё в 1971 г. Но разработчикам стандартов потребовалось ещё 11 лет на разработку RFC 822, который стал прообразом современного представления электронной почты. В нём был описан общий коммуникационный фреймворк текстовых сообщений. В это время электронное письмо рассматривалось просто как набор текстовых строк, а передача структурированных данных (изображений, видео, звука) не подразумевалась и никак не регламентировалась.
Примерно в середине 1990-х родилась концепция специальных расширений MIME (RFC 2045, RFC 2046, RFC 2047), которые позволили включать в состав электронного письма бинарные форматы данных в закодированном виде.
В 2001 году новый стандарт RFC 2822 отменил некоторые устаревшие положения RFC 822, и ввёл понятие частей сообщения message parts, или, проще говоря, "партов". А благодаря MIME появилась возможность создавать multipart-письма, которые могли бы состоять из множества частей различных типов. Наиболее актуальным стандартом электронной почты является RFC 5322, он был разработан в 2008 году.
На сегодняшний день типичное почтовое сообщение состоит из заголовка и "партов". В заголовке в структурированном виде хранятся метаданные, такие как идентификатор письма, электронные адреса отправителя и получателя, дата отправки и другие служебные поля. К "партам", которые составляют само тело письма, относятся основной и альтернативный текст, изображения, прикреплённые файлы. Объём заголовочной части письма редко превышает 1 килобайт текста, тогда как размер тела письма ограничен лишь лимитами почтовой системы и может достигать десятков и даже сотен мегабайт.
Когда письма поступают в Mailion по любому из транспортных каналов (SMTP, IMAP, API), они не сохраняются как единое целое, а разбиваются на составные части. В Mailion мы извлекаем информацию о структуре письма и некоторые другие служебные данные, и затем сохраняем их в хранилище метаинформации. "Парты" писем, которые составляют основной объем данных, направляются в объектное хранилище.
Рис. 1. Разбиение электронного письма на фрагменты и сохранение по частям в хранилище метаданных и объектном хранилище.
Поток данных, который проходит через почтовую систему, отличается следующими важными особенностями:
Письма часто пишутся и ещё чаще читаются. Работа пользователей с почтовой системой порождает огромное количество операций ввода-вывода в хранилище.
Письма иммутабельны однажды отправленное или полученное письмо хранится в почтовой системе в неизменном виде на протяжении всего своего жизненного цикла. Черновики писем могут редактироваться, но сами письма никогда.
Многие письма частично совпадают по содержимому. Например, в длинной цепочке писем могут встречаться взаимные цитирования. Это порождает совпадающие фрагменты текста. Пересылка писем со вложениями приводит к дублированию вложенных файлов. Кроме того, всеми сотрудниками одной компании используется в подписи идентичная картинка с логотипом. В корпоративной среде помимо этих совпадений бывают и другие, которые создаются информационными системами предприятия, например, шаблонными письмами с ответами календаря или системы управления задачами.
В корпоративной среде часто встречаются полные дубликаты писем. Это связано как с широким применением рассылок (например, отправка новостей компании всем сотрудникам), так и с практикой использования копий и скрытых копий. Наконец, у каждого письма всегда есть минимум две копии для отправителя и получателя, и в случае внутрикорпоративной переписки обе копии хранятся в одной и той же почтовой системе.
После детального анализа особенностей потока данных мы сформулировали основной принцип проектирования хранилища: оно должно эффективно проводить дедупликацию почтовых сообщений. Правильная работа с дубликатами позволяет экономить не только дисковое пространство, но и операции ввода-вывода за счёт кэширования наиболее часто встречающихся фрагментов данных. Недорогие, но ёмкие HDD-накопители не отличаются высокой пропускной способностью, их показатели IOPS часто являются лимитирующим фактором для производительности всей системы. Благодаря дедупликации данных увеличивается не только экономическая эффективность хранилища, но и его производительность.
Представьте, что вам необходимо выполнить массовую рассылку письма по компании с 1000 сотрудников. В подписи отправителя письма находится картинка с логотипом компании, её размер составляет 256 Кб. Давайте оценим затраты ресурсов на чтение рассылки всеми сотрудниками компаниями.
В классических почтовых системах mbox-формата, в которых копии писем разных пользователей хранятся в разных файлах, данная операция будет порождать поток произвольных чтений (random read) с диска. Стандартные HDD в этом режиме работы выдают производительность около 100 IOPS. При размере блока в 4 Кб чтение картинки в худшем случае, когда блоки файла при записи не были размещены последовательно, потребует 64 операции чтения. Следовательно, для чтения всех писем с картинками будет необходимо выполнить 64000 операции (64 операции * 1000 пользователей). Для того, чтобы обработать данную операцию за 1 секунду, потребуется 640 HDD одновременно. Если же в системе присутствует только один накопитель, то он будет работать со 100% утилизацией более 10 минут.
Дедупликация позволяет обойтись лишь однократной загрузкой картинки с диска, после чего она попадёт в кеш и при дальнейших запросах будет отдаваться напрямую оттуда. Экономическая эффективность системы с дедупликацией многократно превышает эффективность системы с классической архитектурой.
Безусловно, дедупликация не бесплатна и сильно усложняет процесс записи и чтения, налагает дополнительные расходы на CPU и RAM. Однако иммутабельность данных частично компенсирует этот рост сложности. Благодаря неизменности писем, можно не поддерживать операцию записи по смещению (при необходимости его можно реализовать по принципу copy-on-write) и сохранять интерфейс хранилища максимально простым. На данный момент он состоит из записи, чтения, удаления данных и ещё пары вспомогательных методов.
На момент старта проекта Mailion ни в одном из известных нам объектных хранилищ с открытым кодом подобные оптимизации не были реализованы. Например, в Minio отказались от реализации дедупликации ещё в 2017 г. Попытки доработки других готовых решений, таких, как Elliptics, Riak или Swift, при очевидных и значительных трудозатратах также не гарантировали успеха. ZFS в течение долгих лет не поддерживалась в Linux и по причине лицензионных разногласий официально не может поставляться в дистрибутивах, отличных от Oracle, да и к производительности дедупликации в этой файловой системе есть вопросы.
В Ceph дедупликация появилась в 2019 г., но Ceph имеет репутацию сложного для эксплуатации хранилища с большим количеством историй неуспеха. Многим известны истории отказа Ceph в Росреестре и DigitalOcean и даже потеря бизнеса компанией DataMouse. В багтрекере Ceph можно найти большое количество тикетов с зависаниями, сегфолтами и другими ошибками. Причем некоторые баги, даже в статусе Immediate, могут не устраняться по полгода и больше. Это наводит на мысли о том, что Ceph дорог не только с точки зрения эксплуатации, но и с точки зрения разработки: ресурсы разработчиков будут уходить на стабилизацию самого Ceph, а не на разработку собственного продукта.
Мы убедились в отсутствии подходящих для наших задач продуктов с открытым исходным кодом, и решили разработать собственное хранилище с поддержкой дедупликации в самом ядре системы. Мы вдохновились программной статьей аналитиков из компании Storage Switzerland, в которой кратко описываются принципы проектирования современных программно-ориентированных хранилищ, и решили назвать наш продукт Dispersed Object Store (DOS). Код DOS написан на языках Go (95%), C и C++ (5%).
Иерархия сущностей DOS включает в себя четыре уровня:
документы;
версии документов;
чанки (chunks);
сегменты.
Версия документа является синонимом традиционного понятия объект. Каждый успешный запрос на запись в DOS порождает новую версию определённого документа. В зависимости от бизнес-логики клиента каждый документ может обладать либо единственной версией, либо целой коллекцией версий. При этом версии одного документа могут быть упорядочены, например, по значению логического времени создания версии.
Каждый документ со стороны публичного API адресуется идентификатором, который состоит из пространства имён (namespace) и собственно ключа (key). В рамках одного пространства имён все ключи являются уникальными. Непосредственно в хранилище из внешнего идентификатора и с помощью криптографической хеш-функции генерируется внутренний ключ (storekey), который обладает свойством глобальной уникальности. Во внутренних API все документы адресуются уже через storekey.
В DOS применяется стриминговая запись. В рамках обработки одного запроса на запись поток данных, который поступает на сервер, частично буферизуется в оперативной памяти и только по накоплению определенного объёма сохраняется в персистентном хранилище. Полной буферизации крупных файлов не происходит никогда, поскольку это привело бы к чрезмерным расходам RAM. Частичная буферизация данных (но не только она) предопределяет в модели данных DOS появление чанков крупных байтовых последовательностей. Каждая версия документа может состоять из одного или нескольких чанков.
Чанки, в свою очередь, с помощью специальных алгоритмов разделяются на сегменты более короткие байтовые последовательности. Они выступают в роли элементарных единиц хранения в DOS. У сегментов тоже есть свои идентификаторы, ими являются хеши от их содержимого. В каком-то смысле, внутренним адресом данных в DOS являются сами данные (эта идея не нова и используется, например, в P2P-файловом хранилище IPFS).
Все документы, версии, чанки и сегменты в совокупности формируют внутренние метаданные DOS. Для персистентного хранения метаданных (документов и сегментов) вводятся индексы. В качестве хранилища индексов используется широко известная встраиваемая key-value база данных RocksDB. Индексы с метаданными должны размещаться на быстрых SSD дисках.
В свою очередь раздробленные на сегменты данные размещаются в бэкендах хранения на медленных HDD дисках. На ранних этапах разработки для этого использовался простой файловый бэкенд, в котором каждое тело сегмента хранилось в отдельном файле. Впоследствии был разработан более совершенный блобовый бэкенд, в котором сегменты объединяются в крупные файлы (блобы), тем самым экономятся файловые дескрипторы и снижается количество переключений контекста между пространством пользователя и пространством ядра.
Рис. 2. Иерархия внутренних сущностей DOS.
В нашей системе дедупликация реализована на двух разных уровнях: на уровне сегментов (блочная дедупликация); на уровне версий документов.
Каждый из этих подходов имеет свои плюсы и минусы. Дедупликация на уровне сегментов достигается за счёт совместного использования одних и тех же сегментов различными версиями документов. Каждый сегмент поддерживает внутри себя счётчик ссылок (reference counter) со стороны версий документов. В момент записи новой версии документа поток входящих данных разбивается на сегменты. Для каждого из них по индексу выполняется проверка существования. Если подобный сегмент встречается впервые, то выполняется его запись в бэкенд. Если же сегмент уже сохранялся ранее, то он просто получает новую ссылку со стороны только что созданной версии документа. Тем самым обеспечивается хранение каждого сегмента в единственном экземпляре.
Этот способ дедупликации работает постоянно и позволяет обнаруживать совпадения между разными версиями документов, которые могут отличаться по размеру, времени создания, типу данных и другим параметрам. Он вносит значительный вклад в оптимизацию дискового пространства и операций ввода-вывода. Популярные сегменты, постоянно использующиеся при обработках запроса на чтение, почти наверняка окажутся в кешах.
Однако есть и минусы: существенные накладные расходы на поддержание счётчиков ссылок. Например, одна ссылка потребует от 8 до 40 байт, поэтому для очень популярных сегментов с сотнями тысяч ссылок такие счётчики могут достигать размера в несколько десятков мегабайт. Индекс сегментов раздувается, тяжёлые сегменты становятся слишком большими для пересылки по сети, в результате начинает возрастать время отклика. Для решения этой проблемы приходится вводить сложную систему шардирования счётчика ссылок.
В результате хеширования содержимого сегмента создается идентификатор, обладающий свойством глобальной уникальности. Коллизии идентификаторов сегментов неизбежно приведут к повреждению данных, поэтому для хеширования используется криптографическая функция BLAKE3. Она вносит весомый вклад в потребление CPU при обработке запроса на запись. В случае, если клиент готов ради экономии CPU пожертвовать глобальной уникальностью (например, для короткоживущих данных в небольших инсталляциях хранилища), он может выбрать более быстрые хеш-функции, не обладающие свойством криптографической стойкости.
Второй способ дедупликации несёт значительно меньше накладных расходов, но требует более глубокого вовлечения клиента. Внутрь версии документа встроена очень компактная структура счётчика копий (copy counter). Клиенту DOS предоставляются методы для проверки наличия версии документа и модификации её счётчика копий. Если бизнес-логика клиента позволяет выявить ранее записанную версию, то её повторная запись сводится лишь к дешёвой операции инкремента счётчика копий. В почтовой системе именно так реализовано сохранение партов письма: клиент использует хеш от содержимого парта для построения идентификатора документа, проверяет наличие документа с таким идентификатором и при его наличии просто увеличивает счётчик копий нужной версии на единицу. Иммутабельность данных версии документа даёт гарантию того, что все накопленные инкременты счётчика копий версии относились к одним и тем же данным.
Дедупликация на уровне версий документов фактически обеспечивает ещё один (очень экономичный) вариант записи, при котором оптимизируется не только дисковое пространство и операции ввода-вывода, но ещё и CPU и RAM, а также снижается нагрузка на сеть за счёт облегчения запросов.
Рис. 3. Два уровня дедупликации данных в DOS.
Если сегмент существует в единственном экземпляре, то что произойдёт в случае его потери? Если диск, на котором хранится популярный сегмент выйдет из строя, будет ли это означать невозможность чтения всех ссылающихся на него версий?
Для борьбы с этой проблемой в хранилищах самых разных классов (компакт-диски, RAID-массивы, промышленные СХД) традиционно используются коды коррекции ошибок. Наибольшую популярность получили коды Рида-Соломона (Подробнее в статьях на Хабре: 1, 2, 3).
В DOS во время записи чанк разбивается на заданное количество сегментов равного размера (data segments, d). С помощью кодирования Рида-Соломона из сегментов данных генерируются избыточные сегменты (parity segments, p). При потере любые p из d + p сегментов могут быть восстановлены из имеющихся d с помощью обратной операции. Таким образом, отказоустойчивость приобретается путём дополнительных расходов дискового пространства. Конкретные значения параметров определяются на этапах внедрения и эксплуатации системы. Исходя из потребностей в отказоустойчивости инсталляции, пользователи могут выбирать между стоимостью хранения и возможностью восстановления (часто встречаются комбинации d + p = 2 + 1 и d + p = 5 + 2).
Для гарантии восстановления каждого чанка DOS размещает все входящие в его состав сегменты на бэкенды, которые находятся на независимых HDD. Таким образом, при выходе из строя одного диска не произойдет повреждение сразу нескольких сегментов одного чанка.
При чтении чанка выполняется вычитывание не только сегментов данных, но и избыточных сегментов. Если какие-то из сегментов оказались потеряны, удалены, либо была нарушена их целостность, выполняется попытка их регенерации и повторного сохранения.
Конечно, коды Рида-Соломона могут спасти далеко не всегда. Поэтому в DOS имплементирован ещё один способ восстановления данных: при запросе на инкремент счётчика копий клиент может получить ответ о том, что версия была повреждена и что надо заново записать точно такую же. В этом случае вновь записанная версия восстановит старые поврежденные.
Отдельного рассмотрения требует тема отказоустойчивости метаданных. Мы вернёмся к ней позже в публикациях, посвящённых кластеру DOS.
Во время обработки запроса на запись DOS буферизует первые несколько килобайт из входящего потока и отправляет их в библиотеку сигнатурного анализа файлов. Оттуда хранилище получает вычисленный MIME-тип данных. В контексте DOS все возможные MIME-типы подразделяются на группы форматов. Для каждой из групп в DOS организован отдельный конвейер преобразований (pipeline) и разные оптимизации.
Текстовые данные хорошо сжимаются. Для некоторых текстов с помощью алгоритмов ZSTD, Snappy, Brotli удаётся добиться более чем двукратного сжатия. Это существенная экономия дискового пространства и операций ввода-вывода, и она стоит дополнительных затрат CPU на компрессию и декомпрессию.
Для текстовых данных также можно повысить вероятность обнаружения дубликатов с помощью алгоритма content-defined chunking (CDC). Сущность алгоритма заключается в вычислении хеша Рабина в небольшом окне, скользящем по входящему потоку данных. В позициях, на которых вычисленный хеш принимает определённое значение, ставится граница между чанками. В результате поток разбивается на небольшие чанки разных размеров, однако при этом повышается вероятность обнаружения аналогичных чанков в других версиях с частично совпадающим содержимым.
В отношении данных бинарных форматов, по которым нет понимания, как правильно организовать оптимизацию, применяется подход к работе с обычной байтовой последовательностью. Такой поток данных быстро разбивается на крупные чанки одного размера и в неизменённом виде отправляется на хранение в бэкенд.
Рис. 4. Различия в конвейерной обработке бинарных и текстовых данных в DOS.
Таким образом, конвейер для бинарных данных настроен на повышение пропускной способности сервера и на снижение времени отклика. А конвейер текстовых данных оптимизирует уровень потребления дискового пространства и IOPS ценой повышенного потребления CPU. Насколько же эффективны эти оптимизации?
Мы выполнили эксперименты с помощью генератора текстов, созданного коллегами из отдела разработки поискового ядра, и показали, что для характерного в корпоративной среде потока данных можно достичь примерно двукратного сокращения потребления дискового пространства.
В систему сохраняется 10000 писем. Письма состоят только из текста и не включают в себя какие-либо бинарные объекты. Медианный размер письма около 500 Кб. При этом 70% писем имеют 50% совпадающих данных, остальные полностью уникальны. Полностью эквивалентные письма отсутствуют, поскольку они дедуплицировались бы на уровне счётчиков копий и сильно завысили бы итоговый результат. Настройки кодирования Рида-Соломона d + p = 2 + 1, избыточность данных составляет 50%.
При прохождении через текстовый конвейер объем данных изменяется следующим образом: Входящий поток разделяется на чанки и компрессируется со средним коэффициентом сжатия 2.3. Затем кодирование Рида-Соломона увеличивает количество данных в 1.5 раза. Дедупликация cегментов (блочная дедупликация) снижает полученный с учётом избыточности объем данных в 1.17 раза.
Итоговое отношение записанных данных к хранимым данным составляет 2.3 * 1.17 / 1.5 = 1.79. При этом в нашей модели количество метаданных составляет 0.2% от количества данных, однако этот показатель очень вариативен и сильно зависит как от настроек конвейера, так и от характера и количества самих данных.
В условиях совместного владения сегментами удаление версии документа становится нетривиальной операцией. Её нужно проводить очень аккуратно, чтобы, с одной стороны, не удалить данные, которые ещё кому-то нужны, а с другой не допустить утечек дискового пространства. Связи между всеми сущностями в DOS можно представить в виде большого ациклического ориентированного графа, в котором начальными вершинами являются документы, а конечными вершинами - сегменты. Также есть и промежуточный уровень версий документов. Для каждой из сущностей действуют свои правила удаления: Документ удаляется, если не содержит версий. Версия документа удаляется, если её счетчик копий равен нулю либо истекло время её жизни (TTL). Сегмент удаляется, если не имеет ссылок со стороны версий документов.
Клиент напрямую работает лишь с версиями документов; доступный клиенту метод удаления позволяет декрементировать счётчик копий у конкретной версии. Далее в действие приходят два асинхронных сборщика мусора (GC), один из которых проходит по индексу документов, а другой по индексу сегментов. GC документов удаляет версии с обнулённым счётчиком копий или истекшим TTL, собирает пустые документы и очищает счётчики ссылок сегментов от идентификаторов удаляемых версий. GC сегментов удаляет сегменты с пустыми счётчиками ссылок. Оба GC запускаются в фоновом режиме в периоды, свободные от пользовательской нагрузки.
Рис. 5. Иллюстрация работы сборщиков мусора (1 - граф связей в исходном состоянии; 2 - клиент декрементирует до нуля счётчик копий у одной из версий; 3 - GC документов удаляет версию и владеющий ей документ, GC сегментов удаляет сегмент без ссылок; 4 - граф связей в итоговом состоянии).
Хранение больших объёмов электронной почты - крайне непростая и ресурсоёмкая задача. Однако производительность и экономическую эффективность почтовой системы можно значительно увеличить, если реализовать дедупликацию и компрессию электронных писем. Если вам близка эта тема, и вы тоже хотите создавать уникальные российские программные продукты, то приходите на работу в МойОфис. Прямо сейчас нашей команде требуется разработчик бэкенда откликайтесь, возможно, это именно вы.
В этой статье мы рассмотрели ключевые оптимизации, которые реализованы в объектном хранилище DOS. В дальнейших публикациях мы продолжим описание его архитектуры, а сейчас будем рады обсудить с вами возникшие вопросы в комментариях.