» » Как писать меньше кода для MR, или Зачем миру ещё один язык запросов? История Yandex Query Language

 

Как писать меньше кода для MR, или Зачем миру ещё один язык запросов? История Yandex Query Language

Автор: admin от 12-10-2016, 17:45, посмотрело: 291

Исторически во многих уголках Яндекса разрабатывались свои системы хранения и обработки больших объемов данных — с учетом специфики конкретных проектов. При такой разработке в приоритете всегда была эффективность, масштабируемость и надежность, поэтому на удобные интерфейсы использования подобных систем времени, как правило, не оставалось. Полтора года назад разработку крупных инфраструктурных компонентов выделили из продуктовых команд в отдельное направление. Цели были следующими: начать двигаться быстрее, уменьшить дублирование среди схожих систем и снизить порог входа новых внутренних пользователей.

Как писать меньше кода для MR, или Зачем миру ещё один язык запросов? История Yandex Query Language


Очень скоро мы поняли, что тут мог бы здорово помочь общий высокоуровневый язык запросов, который бы предоставлял единообразный доступ к уже имеющимся системам, а также избавлял от необходимости заново реализовывать типовые абстракции на низкоуровневых примитивах, принятых в этих системах. Так началась разработка Yandex Query Language (YQL) — универсального декларативного языка запросов к системам хранения и обработки данных. (Сразу скажу, что мы знаем, что это уже не первая штука в мире, которая называется YQL, но мы решили, что это делу не мешает, и оставили название).

В преддверии нашей встречи, которая будет посвящена инфраструктуре Яндекса, мы решили рассказать о YQL читателям Хабрахабра.

Архитектура


Мы, конечно, могли бы посмотреть в сторону популярных в мире open source-экосистем — таких как Hadoop или Spark. Но всерьез они даже не рассматривались. Дело в том, что требовалась поддержка уже распространенных в Яндексе хранилищ данных и вычислительных систем. Во многом из-за этого YQL был спроектирован и реализован расширяемым на любом из уровней. Все уровни мы по очереди разберем ниже.

Как писать меньше кода для MR, или Зачем миру ещё один язык запросов? История Yandex Query Language

На диаграмме пользовательские запросы перемещаются сверху вниз, но обсуждать затрагиваемые элементы мы будем в обратном порядке, cнизу вверх, чтобы рассказ получился более связным. Для начала пару слов о поддерживаемых на данный момент бэкендах или, как мы их называем, провайдерах данных:


  • Так сложилось, что в Яндексе уже больше пяти лет разрабатываются две реализации парадигмы MapReduce — YaMR и YT, о которой можно подробнее почитать в недавнем посте. Технически они не имеют почти ничего общего ни друг с другом, ни с Hadoop. Поскольку разработка систем такого класса — достаточно дорогое удовольствие, год назад было принято решение провести «MapReduce-тендер». YT победил, и сейчас пользователи YaMR заканчивают на него переходить. Разработка YQL началась почти одновременно со стартом тендера, поэтому одним из основных требований стала поддержка и YT, и YaMR, которую нужно было наладить для облегчения жизни пользователей в переходный период.

  • Про RTMR (Real Time MapReduce) тоже когда-то был отдельный пост. Его поддержка сейчас находится на ранней стадии разработки. Во-первых, этот проект по интеграции позволит новым пользователям внедрять RTMR без спецподготовки. Во-вторых, они смогут единообразно анализировать как поток свежих данных, так и архив, собранный за длительный период и находящийся в распределенной файловой системе YT.

  • В Яндексе систем хранения данных с OLTP-паттерном использования ещё больше, чем основанных на парадигме MapReduce. В качестве пилотного проекта по интеграции с YQL среди них был выбран KiKiMR. Во многом такой выбор был сделан потому, что потребность в дружелюбном интерфейсе KiKiMR сформировалась в одно время с активным ростом популярности YQL. Ещё одна причина была в наличии у команды KiKiMR ресурсов на этот проект. Детальный рассказ про KiKiMR здесь не уместить, но если вкратце, это распределенное отказоустойчивое strict consistent-хранилище данных, в том числе распределенное между дата-центрами. Оно может использоваться в инсталляциях, состоящих и из нескольких машин, и из тысяч узлов. Отличительной особенностью хранилища KiKiMR является встроенная возможность эффективно выполнять операции транзакционно c уровнем изоляции serializable как над отдельными объектами (single-row transactions), так и над группами распределенных объектов хранилища (cross-row/cross-table transactions).

  • Этот список содержит лишь то, что уже реализовано или находится в работе. В планах — расширять ассортимент поддерживаемых в YQL систем и дальше. Например, очень логичным развитием событий станет поддержка ClickHouse, которая сейчас несколько отложена лишь из-за ограниченности ресурсов и отсутствия острой необходимости.



Как писать меньше кода для MR, или Зачем миру ещё один язык запросов? История Yandex Query Language

Ядро


Технически YQL, хоть он и состоит из относительно изолированных компонентов и библиотек, внутренним пользователям предоставляется в первую очередь как сервис. Это позволяет выглядеть с их точки зрения как «служба одного окна» и минимизировать трудозатраты на организационные вопросы вроде выдачи доступов или настроек фаервола для каждого из бэкендов. Кроме того, обе реализации классического MapReduce в Яндексе требуют наличия синхронно ожидающего завершения транзакции клиентского процесса, а сервис YQL берет это на себя и позволяет пользователям работать в режиме «запустил и забыл пришел за результатами позже». Но если сравнить модель предоставления сервиса с распространением в виде библиотеки, минусы тоже найдутся. Например, следует гораздо более аккуратно относиться к несовместимым изменениям и релизам — иначе можно в самый неподходящий момент сломать пользовательские процессы.

Основной точкой входа в сервис YQL является HTTP REST API, который реализован как Java-приложение на Netty и не только занимается запуском поступающих запросов на вычисление, но и имеет широкий спектр вспомогательных обязанностей:

  • Несколько вариантов аутентификации.

  • Просмотр списка доступных кластеров с бэкендами, списков таблиц и схем, навигация по ним.

  • Репозиторий сохраненных пользователями запросов, а также история всех запусков (исторически живет в MongoDB, но возможно, в будущем это изменится).

  • Уведомления о завершенных запросах:

    • Рядом с REST API доступен WebSocket endpoint, с помощью которого пользовательские интерфейсы (о них поговорим чуть ниже) способны показывать всплывающие сообщения в реальном времени;

    • Интеграция с внутренними сервисами для отправки писем, смс и сообщений в Jabber;

    • Оповещения через бота в Telegram.



Использование Java позволило достаточно быстро реализовать всю эту бизнес-логику благодаря наличию готовых асинхронных клиентов для всех нужных систем. Поскольку слишком строгих требований по latency пока нет, то проблем со сборкой мусора было мало, а после перехода на G1 они практически исчезли. Ещё, помимо упомянутого выше, для синхронизации между узлами используется ZooKeeper, в том числе в паттерне publisher-subscriber при отправке уведомлений.

Само выполнение пользовательских запросов на вычисление оркестрируется отдельными процессами на С++ под названием yqlworker. Они могут быть запущены как на тех же машинах, что и REST API, так и удаленно. Дело в том, что между ними идет общение по сети с помощью разработанного и широко распространенного в Яндексе протокола MessageBus. Под каждый запрос с помощью системного вызова fork (без exec) создается копия yqlworker. Такая схема позволяет достичь достаточной изоляции между запросами разных пользователей и при этом — благодаря механизму copy-on-write — не потратить время на инициализацию.

Как видно из диаграммы с высокоуровневой архитектурой, Yandex Query Language имеет два представления:

  • Основной синтаксис базируется на SQL и предназначен для написания людьми.

  • Синтаксис s-expressions, в свою очередь, более удобен для кодогенерации.


Из запроса, вне зависимости от выбранного синтаксиса, создается граф вычислений (Expression Graph), который логически описывает необходимую обработку данных с использованием примитивов, популярных в функциональном программировании. К таким примитивам относятся: ?-функции, отображение (Map и FlatMap), фильтрация (Filter), свёртка (Fold), сортировка (Sort), применение (Apply) и многие другие. Для SQL-синтаксиса лексер и парсер, основанные на ANTLR v3 строят Abstract Syntax Tree, по которому затем строится граф вычислений. Для синтаксиса s-expression парсер практически тривиален, поскольку грамматика крайне проста, а программы и так оперируют этими абстракциями.

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

  • Типизация. YQL — принципиально строго типизированный язык. Доводов в пользу этого было много, начиная от корней в SQL, где подразумевается схематизация, и заканчивая более широким простором для ускорения — например, за счет генерации нативного кода на лету. Кроме простых типов данных, поддерживается несколько видов контейнеров (Optional, List, Dict, Tuple и Struct) и специальных типов, например непрозрачный указатель (Resource).

  • Оптимизация. На этой стадии происходят не только эквивалентные преобразования, призванные сократить время выполнения. Помимо них выполняется простое приведение плана действий к виду, который бэкенд способен исполнить. В частности, логические операции, которые бэкенд может нативно выполнить, заменяются на физические. Таким образом, в YQL есть свой фреймворк для оптимизаторов, которые можно условно разделить на три категории:

  • общие правила логических оптимизаций;

  • общие правила, специфичные для конкретных бэкендов;

  • оптимизации, выбирающие ту или иную стратегию выполнения в runtimе (к ним мы ещё вернёмся).


  • Выполнение. Если после оптимизации не осталось ошибок, граф приобретает вид, выполнимый с использованием API бэкенда. Большую часть времени yqlworker именно это и делает. Оставшиеся в графе вычислений логические операции исполняются с помощью узкоспециализированного интерпретатора, по возможности — на вычислительных мощностях бэкендах.


На любой из стадий жизни запроса он может быть сериализован обратно в синтаксисе s-expressions, что крайне удобно для диагностики и понимания происходящего.

Интерфейсы


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

Консольный клиент


Как писать меньше кода для MR, или Зачем миру ещё один язык запросов? История Yandex Query Language

На картинке показан интерактивный режим с автодополнением, подсветкой синтаксиса, цветовыми темами, уведомлениями и прочими украшательствами. Но консольный клиент может запускаться и в режиме ввода-вывода из файлов или стандартных потоков, что позволяет интегрировать его в произвольные скрипты и регулярные процессы. Есть как синхронный, так и асинхронный запуск операций, просмотр плана запроса, прикрепление локальных файлов, навигация по кластерам и прочие основные возможности.

Такая богатая функциональность появилась по двум причинам. С одной стороны, в Яндексе есть заметный пласт людей, предпочитающих работать преимущественно в консоли. С другой, это было сделано, чтобы выиграть время на разработку полнофункционального веб-интерфейса, о котором мы ещё поговорим.

Любопытный технический нюанс: консольный клиент реализован на Python, но распространяется как статически слинкованное нативное приложение без зависимостей, которое компилируется под Linux, OS X и Windows. Кроме того, он умеет автоматически самостоятельно обновляться — примерно как современные браузеры. Всё это было достаточно просто организовать благодаря внутренней инфраструктуре Яндекса для сборки кода и подготовки релизов.

Python-библиотека


Как писать меньше кода для MR, или Зачем миру ещё один язык запросов? История Yandex Query Language

Python является вторым по распространенности языком программирования в Яндексе после C++, поэтому клиентская библиотека YQL реализована именно на нем. На самом деле она изначально разрабатывалась как часть консольного клиента, а затем была выделена в независимый продукт, чтобы появилась возможность использовать её в других Python-окружениях, не изобретая аналогичный код заново.

Например, многие аналитики любят работать в среде Jupyter, для которой на основе данной клиентской библиотеки был создан так называемый %yql magic:

Как писать меньше кода для MR, или Зачем миру ещё один язык запросов? История Yandex Query Language

Вместе с консольным клиентом поставляются две специальные подпрограммы, которые запускают преднастроенный Jupyter или IPython с уже доступной клиентской библиотекой. Именно онии показаны выше.

Веб-интерфейс


Как писать меньше кода для MR, или Зачем миру ещё один язык запросов? История Yandex Query Language

Основной инструмент изучения языка YQL, разработки запросов и аналитики мы оставили на закуску. Благодаря отсутствию технических ограничений консоли, в веб-интерфейсе все функции YQL доступны в более наглядной форме и всегда находятся под рукой. Часть возможностей интерфейса показана на примерах других экранов:


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

    Как писать меньше кода для MR, или Зачем миру ещё один язык запросов? История Yandex Query Language

    Логика автодополнения запросов у консольного клиента и веб-интерфейса общая. Она умеет достаточно точно учитывать контекст, в котором происходит ввод. Это позволяет ей подсказывать только релевантные ключевые слова или имена таблиц, колонок и функций, а не всё подряд.

  • Работа с сохраненными запросами

    Как писать меньше кода для MR, или Зачем миру ещё один язык запросов? История Yandex Query Language

    При сохранении запроса под именем они попадают в мини-аналог репозитория кода с возможностью просмотра истории и возврата к предыдущим версиям.

  • План выполнения запроса

    Как писать меньше кода для MR, или Зачем миру ещё один язык запросов? История Yandex Query Language

    Здесь показана наиболее простая и универсальная реализация JOIN в терминах MapReduce.


… и не только

Все ручки в самом REST API аннотируются по коду и на основе этих аннотаций с помощью Swagger автоматически генерируется подробная онлайн-документация. Из неё можно попробовать позадавать запросы без единой строчки кода. Это позволяет легко использовать YQL, даже если перечисленные выше готовые варианты по каким-то причинам не подошли. Например — если вы любите Perl.

Возможности


Настала пора поговорить о том, какого плана задачи можно решать с помощью Yandex Query Language и какие возможности предоставляются пользователям. Эта часть будет скорее тизисной, чтобы не удлинять и без того длинный пост.

SQL


  • Основной диалект YQL основан на стандарте SQL:1992 с вкраплениями из более новых версий. Все основные конструкции поддерживаются, но полная совместимость в тонкостях, которые оказались не очень востребованы, — ещё в разработке. Благодаря этому многим новым пользователям, которые раньше работали с какими-либо базами данных с SQL-интерфейсом, приходится изучать язык далеко не с нуля.

  • На бэкендах, работающих в парадигме MapReduce, целевые таблицы (для простоты) создаются автоматически. Запросы чаще всего состоят из SELECT произвольного уровня сложности и опционально содержат INSERT INTO.

  • В OLTP-сценариях поддерживаются полноценные DDL (CREATE TABLE) и CRUD (плюс UPDATE, REPLACE, UPSERT и DELETE).

  • Для многих ситуаций, которые в стандартном SQL либо не поддерживаются, либо получились бы слишком громоздкими, в YQL добавлены различные расширения синтаксиса, например:


    • Именованные выражения

      Как писать меньше кода для MR, или Зачем миру ещё один язык запросов? История Yandex Query Language

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

    • Работа с типами-контейнерами

      Как писать меньше кода для MR, или Зачем миру ещё один язык запросов? История Yandex Query Language

      Доступен как синтаксис для получения элементов по ключу или индексу, так и набор специализированных встроенных функций.


    • FLATTEN BY

      Как писать меньше кода для MR, или Зачем миру ещё один язык запросов? История Yandex Query Language

      За этим ключевым словом закреплена возможность размножать строки исходной таблицы с вертикальным разворачиванием контейнеров (списков или словарей) переменной длины из колонки с соответствующим типом данных.

      Звучит немного запутанно — проще показать на примере. Возьмём таблицу следующего вида:













      [a, b, c]1
      [d]2
      []3
      Применив FLATTEN BY к левой колонке, получим такую таблицу:

















      a1
      b1
      c1
      d2
      Подобное преобразование может быть удобным, когда по ячейкам из колонки-контейнера нужно посчитать какую-либо статистику (скажем, через GROUP BY) или когда в ячейках — идентификаторы из другой таблицы, с которой нужно сделать JOIN.

      Самое забавное во FLATTEN BY вот что: оно называется по-разному во всех системах, которые умеют так делать. Из того, что мы нашли, нет ни одного повтора:

      • ARRAY JOIN — ClickHouse,

      • unnest — PostgreSQL,

      • $unwind — MongoDB,

      • LATERAL VIEW — Hive,

      • FLATTEN — Google BigQuery,



    • явные PROCESS (Map) и REDUCE (Reduce).

      Как писать меньше кода для MR, или Зачем миру ещё один язык запросов? История Yandex Query Language

      Позволяют встраивать в запросы на YQL cуществующий код, написанный в парадигме MapReduce, в сочетании с механизмом пользовательских функций, о котором пойдет речь ниже.




User Defined Functions

Не все виды преобразований данных удобно выражать декларативно. Иногда проще написать цикл или воспользоваться какой-нибудь готовой библиотекой. Для таких ситуаций YQL предоставляет механизм пользовательских функций, они же User Defined Functions, они же UDF:


  • С++ UDF

    • «Из коробки» доступно более 100 функций на C++, разделенных более чем на 15 модулей. Примеры модулей: String, DateTime, Pire, Re2, Protobuf, Json и др.

    • Физически C++ UDF — динамически подгружаемые библиотеки (.so) с ABI-safe-протоколом вызова и регистрации функций.

    • Есть возможность написать свою C++ UDF, собрать её локально (система сборки имеет готовый набор настроек сборки для UDF), загрузить стандартным образом в хранилище и сразу же начать использовать в запросах, приложив её по URL.

    • Для простых UDF можно использовать готовые C++-макросы, скрывающие детали, а при необходимости доступны гибкие интерфейсы для разных потребностей.



  • Python UDF

    • Когда производительность не так важна, а для решения задачи нужно быстро сделать вставку с императивной бизнес-логикой, очень удобно разбавить декларативный запрос кодом на Python. Большинство сотрудников Яндекса знают Python, а если кто-то не знает — на базовом уровне он изучается за единицы дней.

    • Скрипт на Python можно либо написать как inline вперемешку с SQL или s-expressions, либо приложить к запросу отдельным файлом. Вообще, механизм доставки файлов до места вычислений с клиента или по URL универсален и может использоваться для всего необходимого, например для файлов-словарей.

    • Поскольку в Python используется динамическая типизация, а в YQL — статическая, то от пользователя требуется объявить сигнатуру функции на границе. Сейчас она описывается снаружи с помощью дополнительного мини-языка: дело в том, что на этапе типизации не хочется запускать интерпретатор. В будущем, возможно, прикрутим поддержку Python 3 type hints.

    • Технически поддержка Python в YQL реализована через C++ UDF со встроенным интерпретатором Python и небольшой синтаксический сахар в SQL-парсере для её вызова.



  • Streaming UDF. Чтобы можно было плавно перейти с других технологий, и для некоторых особых случаев есть способ запустить произвольный скрипт или исполняемый файл в потоковом режиме. В итоге получим UDF, преобразующую один список строк в другой.



Аггрегационные функции

Внутри у агрегационных функций используется общий framework с поддержкой DISTINCT b выполнения как на верхнем уровне, так и в GROUP BY (в том числе и с ROLLUP/CUBE/GROUPING SETS из стандарта SQL:1999). А отличаются эти функции лишь бизнес-логикой. Вот некоторые примеры:

  • Стандартные: COUNT, SUM, MIN, MAX, AVG, STDDEV, VARIANCE;

  • Дополнительные: COUNT_IF, SOME, LIST, MIN_BY/MAX_BY, BIT_AND/OR/XOR, BOOL_AND/OR;

  • Статистика:

    • MEDIAN и PERCENTILE (по алгоритму TDigest);

    • HISTOGRAM — адаптивные гистограммы по числовым значениям, не требующие никакого знания их распределения, (по алгоритму на основе Streaming Parallel Decision Tree).


  • User Defined Aggregation Functions: для совсем специфичных задач можно передать в framework агрегационных функций свою бизнес-логику, создав несколько вызываемых значений с определенной сигнатурой с помощью описанного выше механизма UDF, например на Python.



Из соображений производительности, в терминах MapReduce для агрегационных функций автоматически создается Map-side Combiner с объединением промежуточных результатов агрегации в Reduce. DISTINCT сейчас всегда работает точно (без приближенных вычислений), поэтому требует дополнительного Reduce для разметки уникальных значений.

JOIN таблиц

Слияние таблиц по ключам — одна из самых популярных операций, которая часто нужна для решения задач, но правильно реализовать которую в терминах MapReduce — почти целая наука. Логически в Yandex Query Language доступны все стандартные режимы плюс несколько дополнительных:

Как писать меньше кода для MR, или Зачем миру ещё один язык запросов? История Yandex Query Language

Чтобы скрыть детали от пользователей, для основанных на MapReduce бэкендов стратегия выполнения JOIN выбирается на лету в зависимости от требуемого логического типа и физических свойств участвующих таблиц (это так называемая cost based optimization):



























СтратегияКраткое описаниеДоступна для логических типов
Common Join1-2 Map + ReduceВсе
Map-side Join1 MapInner, Left, Left only, Left semi, Cross
Sharded Map-side Joink паралелльных Map (k <= 4 по-умолчанию)Inner, Left semi с уникальной правой, Cross
Reduce Without Sort1 Reduce, но требует заранее правильно отсортированного входав разработке


Направления развития


Среди наших ближайших и среднесрочных планов по Yandex Query Language:

  • Больше бэкендов в статусе production.

  • Генерация нативного кода и векторизация вместо специализированного интерпретатора.

  • Продолжение оптимизации ввода-вывода и выбора стратегий выполнения на лету в зависимости от физических свойств таблиц.

  • Оконные функции на основе стандарта SQL:2003.

  • Поддержка SQL:1992 в полном объеме, создание ODBC/JDBC-драйверов с последующей интеграцией с популярными ORM и инструментами бизнес-аналитики.

  • Наглядная демонстрация прогресса выполнения операций.

  • Расширенный ассортимент доступных языков программирования для UDF — посматриваем на javascript V8, Lua и Python 3.

  • Интеграция с:

    • распределенным отказоустойчивым сервисом запуска задач по расписанию (a la cron) или наступлению событий,

    • инструментами визуализации (внутренний аналог Яндекс.Статистики).




Подводим итоги



  • Как показывают цифры (см. врезку), YQL стал продуктом, очень востребованным среди сотрудников Яндекса. Тем не менее, объемы обработанных с его помощью данных не так велики. Это обусловлено тем, что исторически все продакшен-процессы работают на низкоуровневых интерфейсах, подходящих под требования их систем. То есть их постепенный перевод на YQL только начинается.

  • Внутри Яндекса мы поначалу сталкивались с сопротивлением следующего вида: работая в парадигме MapReduce долгие годы, многие уже настолько к ней привыкли, что не хотят переучиваться. В Аркадии, основном монолитном репозитории кода Яндекса, у каждого сотрудника есть свой уголок. Там исторически лежат буквально сотни программ на C++, написанных исключительно чтобы отфильтровать какой-нибудь специфичный лог или просто таблицу в MapReduce под конкретную задачу. Но после набора первой критической массы довольных пользователей подобный скептицизм встречается всё реже.

  • Возвращаясь к вопросу, «почему не Hive, Spark SQL или любой другой SQL over ***: в первую очередь нас интересовала именно поддержка активно используемых в Яндекс систем. Хотелось упростить миграции проектов, то есть все компоненты из диаграммы в начале поста всё равно пришлось бы разрабатывать и/или дорабатывать. При этом пришлось бы подстраиваться под устои open source-сообщества. Кроме того, были бы трудности с тем, что Java-разработчиков в Яндексе примерно на порядок меньше, чем C++-разработчиков, а люди с опытом разработки ядра этих open source-проектов — дефицит даже в США. И в результате совершенно не факт, что получилось бы лучше или быстрее. YQL создан с нуля примерно за год командой примерно из 10 человек, большинство из которых участвовали не full time.

  • Сконцентрировавшись исключительно на SQL диалекте, мы бы закрыли двери перед заметным классом людей, которым удобнее описывать макропреобразования данных и бизнес-логику однородным образом на одном языке программирования. В Яндексе уже существовала библиотека такого класса для Python под названием Nile: мы вместо имевшегося в ней runtime реализовали (за её публичным API) генерацию и запуск YQL-запросов на s-expressions. Сейчас мы находимся в процессе доработок для переключения на него по умолчанию. Другие языки программирования, где такой интерфейс был бы востребован, в Яндексе гораздо менее распространены, но в будущем не исключено появление аналогов и для, например, Java.

  • Нам было бы очень интересно выложить YQL с каким-то подмножеством бэкендов в open source — чтобы попробовать составить конкуренцию экосистемам от Apache Software Foundation: Hadoop и Spark. К сожалению, в самое ближайшее время этого не случится ввиду разного рода сложностей: например, отсутствия инструментов для частичной публикации Аркадии или многочисленных завязок на внутреннюю инфраструктуру. Но мы уже потихоньку начали двигаться в этом направлении.



Напоследок — ещё раз приглашаем на встречу в нашем офисе в ближайшую субботу, 15 октября, где мы подробнее расскажем о разных аспектах инфраструктуры в Яндексе.

Как писать меньше кода для MR, или Зачем миру ещё один язык запросов? История Yandex Query Language

Источник: Хабрахабр

Категория: Программирование, Яндекс

Уважаемый посетитель, Вы зашли на сайт как незарегистрированный пользователь.
Мы рекомендуем Вам зарегистрироваться либо войти на сайт под своим именем.

Добавление комментария

Имя:*
E-Mail:
Комментарий:
Полужирный Наклонный текст Подчеркнутый текст Зачеркнутый текст | Выравнивание по левому краю По центру Выравнивание по правому краю | Вставка смайликов Выбор цвета | Скрытый текст Вставка цитаты Преобразовать выбранный текст из транслитерации в кириллицу Вставка спойлера
Введите два слова, показанных на изображении: *