Pull to refresh
46
0
Алексей @0x0FFF

Архитектор распределенных систем обработки данных

Send message

Как я уже сказал, SRE помогают разрабатывать сам сервис, просто фокусируются на других задачах. Одна из проблем взаимодействия SRE и разработчиков возникает, когда разработчики полностью передают продакшн SRE, а сами SRE занимаются исключительно инфраструктурой этого продакшэна.

В этом случае разработчики пишут софт не понимая, как же он работает в проде, а SRE поддерживают прод не понимая, что за софт на нем крутится и что происходит у него внутри. Отсюда вырастают проблемы, что данные на тестовом стенде никто не обновляет - разработчики пишут софт и не понимают, как именно он взаимодействует с окружением, а SRE понимают эти взаимодействия, но не знают требований к ним.

Судя по фразе «Разработчики — наши клиенты» ваши SRE по большей части являются DevOps. В философии SRE правильнее считать «мы - разработчики», просто фокус SRE на масштабируемости и отказоустойчивости, а разработчиков - на фичах. Когда SRE и швец (сисадмин), и жнец (девопс) и на дуде игрец (внутренняя инфраструктура) - это скорее всего приведет к проблемам.

Также могут задать вопрос на oбъектно-ориентированный дизайн, чтобы посмотреть, насколько хорошо вы разбираетесь в проектировании программного обеспечения. Например, могут попросить спроектировать простенький онлайн-магазин. Правда мне ни разу не попадалось такой задачи, по решению которой действительно можно было бы судить об этом навыке.
Задачи на дизайн обычно начинаются с уровней L4/L5, их не задают джуниурам и тем более стажерам.

По их результатам мне согласились дать оффер и начали искать команду, однако я отказался от этого варианта, поскольку решил закончить магистратуру.
Попасть в Гугл после стажировки — самый простой вариант. После магистратуры вам придется проходить 5 онсайт интервью, среди которых уже будет NALSD, и пройти его значительно сложнее, чем те 2 интервью в рамках Intern Conversion.
3.5 года в Ирландии, и придерживаюсь противоположного мнения — как раз с детьми переезжать сюда лучше, чем одиноким и парам без детей. Для детей здесь хорошие школы, бесплатное медицинское обслуживание, чистый воздух и возможность жить в своем доме с садом, при этом оставаясь в городе. Без семьи я бы скорее переехал в США или Лондон/Цюрих, а для семейных Ирландия — более удачный вариант.

Выкатывать хотфиксы сразу в прод — а вы рисковый. С точки зрения SRE, сначала безусловно делается rollback к предыдущему релизу, а уж потом анализ причин поломки, исправления и т.д. Roll forward — только для чего-то не очень критичного.

Дополнительно ClickHouse сжимает данные, и то, что мы храним данные по столбцам, дает нам преимущество. Данные получаются более отдаленные и лучше сжимаются.

Наверное, оговорка: в одном столбце данные более гомогенные, поэтому и сжимаются лучше.

… есть пример — вычисление средней длительности сессии.

Наверное, в запросе опечатка — на слайде выбирается только avg_duration, но не FirstPartyCookie, то есть запрос возвращает только средние длительности сессий без привязки к кукисам, что в общем-то бесполезно.

Также мы использовали sampling: сказали, что будем читать 1/10 часть данных. ClickHouse делает это эффективно, он выбрасывает ненужные данные сразу после прочтения данных с диска.

Насколько мне известно, в аналитических СУБД основное время тратится именно на общение СУБД с диском. То есть проведение сэмплинга после чтения с диска в большинстве случаев лишено смысла — я практически уверен, что в приведенном примере запросы с сэмплингом и без будут выполняться приблизительно одинаковое время. Другое дело, что сэмплинг на уровне блоков не будет случайным, но это уже другой вопрос.

У нас есть обученная модель, она выдает хорошее качество. Как теперь ее внедрять?
Казалось бы, вопрос простой. Давайте делать просто: каждый понедельник выгружать из ClickHouse данные за предыдущий месяц, запускать питоновские скрипты, получать вероятность покупки и загружать обратно, скажем, в ту же таблицу ClickHouse

Стоп. Зачем выгружать, зачем питоновские скрипты? Давайте сначала остановимся и опишем, какую именно задачу мы хотим решить? В большинстве случаев намного более эффективным будет применение модели в реальном времени — пользователь присылает запрос, и специальный сервис применяет последнюю версию вашей модели к данным конкретного запроса. Почему вы решили, что нужно применить именно оффлайн предпосчет вероятностей, без указания мотивации этого решения?

Вопрос по существу 1: вы храните данные в column-oriented таблицах, и предлагаете применять к этим данным одну из обученных моделей. Проблема в том, что для применения модели зачастую требуются практически все столбцы таблицы. В итоге, колоночная СУБД для вашего запроса собирает полные строки исходных данных — не является ли overkill'ом использование колоночной БД в этом случае? Согласно моему опыту, колоночное хранение данных выигрывает у построчного при использовании <50% столбцов в запросе, а использование 100% столбцов — худший кейс для колоночной БД.

Вопрос по существу 2: вы используете свой XML-подобный формат для хранения моделей. Почему не PMML, являющийся стандартом де-факто в индустрии?
Вопрос не в «цифра не нравится», а предсказание предложенной вами модели расходится с практически наблюдаемыми значениями на 7-8 порядков. 7-8 порядков — это не просто статистическая погрешность
Модель хорошая, но боюсь, что из вашей статьи могут сделать неверные выводы. Особенно режет глаза цифра в 100'000'000 лет для кластера в 1000 нод.

Люди могут прочитать, и пойти деплоить кластеры Hadoop на 1000 нод с r=3 и думать, что они могут спать спокойно. Но, например, при выпадении ToR свича вы потеряете сразу всю стойку. Та же HDFS хранит r=3, но при этом 2 копии по умолчанию приземляются на одну стойку, значит при выпадении стойки приблизительно треть хранимых ей блоков оказывается в единственном экземпляре. Треть полной стойки двухюнитовых серверов — это до 320'000'000 чанков, соответственно каждый из оставшихся в кластере дисков будет в среднем хранить 27'210 чанков, у которых осталась одна последняя живая реплика. Если у сети нет oversubscription, то дореплицироваться эти чанки в идеальном случае будут: 27210 чанков * 1MB / 50 MB/sec ~= 9 минут. Плюс время на обнаружение проблемы. Плюс заметим, что в используемой у вас LRC-8-2-2 нужно еще и контрольные чанки пересчитать, то есть при восстановлении вам придется прочитать раз в 6 больше данных, то есть мы уже говорим о почти часе на абсолютно пустом кластере. Плюс в критический момент оказывается, что Hadoop сам не инициирует восстановление коэффициента репликации, и делать это нужно ручками на уровне файлов или директорий. А во время восстановления кластера выпадение еще одного любого диска — это недоступность данных.

Поэтому я склонен считать что ваши рассуждения, к сожалению, тоже не верны. Автор критикуемой вами статьи не учитывает динамику. Вы учитываете динамику, но не учитываете другие возможные причины отказа — проблемы сетевого оборудования, проблемы питания, возвращение нодами некорректных данных, ошибки памяти, человеческий фактор и т.д. Не учитываете также то, что «динамика» — вещь относительная, и для вашего кластера и кластера Hadoop динамика восстановления будет отнюдь не одинаковая. Добавление же всех этих факторов в модель сделает её настолько сложной, что практическая польза от нее будет весьма спорной. Но на бумаге выглядит хорошо.
Я закладывал 1 день на замену. Даже если все будет работать идеально, системе все равно потребуется время на восстановление потерянных чанков, и в зависимости от нагрузки на кластере это время может быть довольно значительным, полчаса-час. Но как я сказал, я не учитывал множество других факторов. Например, Яндекс в силу объемов данных наверняка использует commodity диски, у которых ARR около 4-5%. Плюс диск не всегда отказывает и исчезает, иногда он начинает просто отдавать битые данные. Диск в наличии, а данные на нем неправильные, на диагностику такой проблемы тоже нужно время.

Вы работаете с реальными кластерами подобных размеров, и сами используете LRC-8-2-2 (то есть можно потерять до 2 реплик из группы без потери данных) — какая у вас статистика по потерям чанков? Неужели действительно ни одной потери? Как следует из вашей формулы с 100 000 000 лет, даже вы имея 100 кластеров в течении 10 лет, получите вероятность отказа вероятность отказа всего 0.001%
Дано:
3-кратная репликация, размер чанка 1 Мб, 4 ТБ диски, 1000 серверов в кластере, каждый сервер с 12 дисками, ARR для диска составляет 1%, 1 день на замену сломавшегося диска.

Расчет:
  • 1000 серверов, каждый с 12 дисками, итого в кластере 12'000 дисков. Отдельные диски вмещают до 4 ТБ / 1 МБ = 4'000'000 чанков.
    Когда один диск ломается, 4'000'000 его чанков становятся недоступными. Каждый из оставшихся в кластере дисков будет содержать приблизительно 4'000'000 / 12'000 = 333 чанка данных, хранившихся на сломанном диске. Это означает, что любые 2 отказавших диска в кластере приведут к тому, что 333 чанка в кластере останутся с единственной репликой. Эти 333 чанка должны лежать на разных дисках. Итого, когда любые 2 жестких диска в кластере одновременно выходят из строя, отказ любого из 333 жестких дисков, содержащих последнюю реплику наших данных, приведет к потере данных.
  • 12000 дисков в кластере и ARR 1%, дает нам 12000 * 1% = 120 отказов жестких дисков в год. Если замена происходит в течение 1 дня, то когда один жесткий диск вышел из строя, вероятность того, что сломается еще один, равна 11999 * 1% * 1/365 ~= 33%. Поскольку у нас 120 сломанных дисков в год, каждый из которых требует ремонта в течение 1 дня, примерно 120 * 33% ~= 39,5 дней в году, мы будем работать в кластере с двумя отказавшими дисками.
  • В кластере с двумя отказавшими дисками мы зависим от 333 других дисков, содержащих последнюю живую реплику данных. Какова вероятность того, что один из них откажет? 333 диска * 1% ARR * 39,5 дней в году без 2 дисков / 365 = 36%, в год. Таким образом, примерно раз в три года вы потеряете один чанк своих данных. Для многих приложений недоступность одного чанка — это уже проблема.

Так или иначе, это никак не 100'000'000 лет. Теперь добавим сверху падения других компонент кроме дисков, проблемы с сетью, перезагрузки серверов (накатываем обновления, например), когда часть чанков тоже становится недоступна, время на обнаружение проблемы с диском и восстановление данных, и т.д. Итоговая цифра намного больше соотносится с реальностью, чем ваши вычисления. Уж вы-то в Яндексе должны знать на основании своего опыта, что для кластера с 1000 машин и 3-кратной репликацией потеря данных будет происходить раз в год или чаще.
Коллега, есть такое понятие как «tail latency». Нельзя судить о времени отклика нагруженного сервиса только по среднему, зачастую та же 95-я и 99-я перцентили намного важнее.

Интересный выбор статьи для перевода. Мне довелось поработать в Pivotal, и Элизабет была моим прямым руководителем какое-то время.


Про интервью — все действительно так, но есть несколько но:


  1. Это онсайт-интервью. Перед ним проводится несколько телефонных интервью, где задачки уже ближе к алгоритмическим, и где производится основной отсев неподходящих кандидатов. Если вы попали на онсайт, то с вероятностью около 50% вас возьмут.
  2. Задача этого интервью — не только проверка навыков, но и оценка того, как хорошо вы вольетесь в коллектив, насколько приятно будет другим разработчикам с вами работать.

По поводу траты времени — собеседования во все крупные компании занимают полный день. У Pivotal 2000+ сотрудников, и оценочная стоимость компании $2b+, то есть они могут себе позволить подобные интервью.


Задачи же на собеседование у Гугла сложные только потому, что у них огромное количество кандидатов претендует на небольшое количество позиций. Если давать простые задачи, то чересчур много кандидатов их решит полностью и правильно, как потом выбирать среди них? Если давать задачи, очень приближенные к реальности, то чересчур много будет зависеть от субъективного восприятия собеседующего, что тоже нехорошо.

Я утрировал. СУБД обычно не используются для организации очередей. Скорее СУБД можно использовать для регистрации событий исходной системы, для последующей их пакетной обработки (и, соответственно, хранения истории). Писатели и так не блокируют друг друга (параллельные insert уже давно исполняются СУБД без блокировки), а читателей при пакетной обработке не много и не нужно дикости вроде полной блокировки таблицы, как в примере автора. Для классического кейса с большим количеством параллельных читателей для распределения нагрузки, СУБД будет работать плохо

Что хорошо в очередях, и из-за чего появилось много решений для организации очередей — им не нужна полноценная ACID. А по поводу произвольной выборки — та же Kafka умеет читать из произвольного места в очереди.
Плакал, читая вашу статью:
Нам понадобилась очередь, и мы решили использовать для ее организации СУБД. А там блокировки, да и хранит данные она на диске, непорядок! Решили использовать модный распределенный ObjectStore для организации очереди, он работает побыстрее, но все равно оверхед большой и управлять им сложно, не то. Затем для реализации очереди мы решили использовать распределенный in-memory key-value store (а почему бы и нет?). Затем не распределенный in-memory key-value store. Затем мы решили все-таки попробовать продукты, реализующие функционал очередей, но что-то у них настройка больно мудреная, и мы не осилили

Это же основы. ПО для организации очередей писалось не дураками, и писалось именно потому, что другие инструменты конкретно для задачи организации очередей подходят плохо. ActiveMQ, ZeroMQ, RabbitMQ, Kafka и многие другие — создавались именно для того, чтобы снизить оверхед на операции с очередями, гарантировать сохранность данных и их последующую обработку. По определению никакие СУБД, key-value store, object store и прочие не будут решать эту задачу лучше, за исключением ситуации, когда у вас одно сообщение в секунду и вам не важно, будет ли оно в итоге обработано или потеряно.
Это приятное дополнение к функциональности Postgres, но использовать его нужно с умом. Если на машине с Postgres подсистема ввода-вывода является узким местом, то параллельное сканирование может только усугубить картину, ухудшив общую производительность системы.

К тому же, параллельное сканирование — это движение в сторону OLAP, и тут стоит вспомнить, что на одной машине совмещать OLAP и OLTP далеко не лучшее решение, т.к. несколько параллельных запросов аналитиков в 8 воркеров каждый создадут такую нагрузку на IO, что с SLA транзакционной части придется попрощаться
— Нет, я так не говорю. Количество записей на диск не зависит от количества трансормаций, оно зависит от количества shuffle. Каждый раз, когда Spark производит shuffle, все данные приземляются на диск. У вас может быть одна трансформация join, которая будет исполнена в виде reduce-side join, и оба участвующих RDD будут перераспределены (shuffle) по кластеру перед join'ом. А может быть трансформация «filter», которая всегда пайплайнится с другими трансформациями, и соответственно никакого приземления данных на диск не будет
— Нет, такого варианта нет. Данные во время shuffle всегда приземляются на диск. По-другому асинхронное выполнение тасков работать и не может
Советую вам ориентироваться не на презентации, а на код

Вот оригинальный комментарий из кода менеджера shuffle в Spark:
/**
 * In sort-based shuffle, incoming records are sorted according to their target partition ids, then
 * written to a single map output file. Reducers fetch contiguous regions of this file in order to
 * read their portion of the map output. In cases where the map output data is too large to fit in
 * memory, sorted subsets of the output can are spilled to disk and those on-disk files are merged
 * to produce the final output file.
 */

Если по коду, то здесь происходит запись на диск, которая вызывается отсюда, в свою очередь вызывается отсюда, объявляется здесь и вызывается тут. Это наиболее актуальная имплементация, т.н. Tungsten, а вот более старая

Как я и говорил, специалистов, способные разделять реальность и маркетинг, не так уж много.

И да, в презентации говорится про «storage»: они имеют в виду возможность Spark кэшировать данные, а не то, что во время shuffle он не сбрасывает данные на диск
Apache HAWQ интегрирован с YARN, то есть глобальный менеджер ресурсов в кластере будет и HAWQ не сможет забрать себе всё. Но нужно понимать, что YARN управляет только квотами на память и CPU, то есть IO может стать узким местом. Еще стоит учесть, что совмещать на одном кластере аналитические и транзакционные системы — моветон. То есть HAWQ + Sqoop + Flume + Spark будут вместе жить нормально, а вот HAWQ + HBase — уже не очень
К сожалению, таких данных у меня нет. Но ожидаемо, что запросы к Hive-таблицам будут медленнее. Нативные таблицы парсятся кодом HAWQ (написанным на C), а для обращения к Hive таблицам нужно поднимать Java-десериализаторы, соответствующие формату хранения, что довольно долго.

Но Apache HAWQ — это open source, и вы свободно можете протестировать его и самостоятельно увидеть разницу в производительности
Не согласен с вами касательно MPP. Основная идея MPP как раз в том, что она массивно-параллельная, то есть много процессов параллельно выполняют одну и ту же задачу над разными данными. MapReduce и подобные подходы не являются MPP, т.к. в этих системах нет гарантии параллельного выполнения задач, это системы пакетной обработки данных. По сути это «data parallelism» против «task parallelism» — первый параллельно обрабатывает одни и те же данные набором процессоров, а второй разбивает задачу на независимые «таски» и назначает их свободным процессорам по мере их доступности и глобальных приоритетов

Про Kudu — да, прочитайте их публикацию

Лично я считаю, что популярность Hadoop обусловлена потребностью рынка и маркетингом. А когда начинается использование Hadoop, все «корпоративные» клиенты хотят иметь к нему SQL-интерфейс, при этом быстрый и с транзакциями — вот и потребность

Information

Rating
Does not participate
Location
Dublin, Dublin, Ирландия
Registered
Activity