Что такое ctl потоки данных
Что такое ctl потоки данных
CTL (от англ. cross-the-line) — совокупность рекламно-маркетинговых инструментов и технологий. В основе CTL лежит сбалансированный комплекс следующих факторов: цели и задачи кампании, предпочтения целевой аудитории по форме и механике, конкретные УТП и/или особенности продукта и, как следствие, выбор оптимальной коммуникации.
В отличие от BTL, где целевая аудитория зачастую «размыта» и для ее достижения используется стандартные механики, CTL подразумевает четкую сегментацию целевой аудитории, определение параметров кампании и использует наиболее эффективную коммуникацию в зависимости от особенностей продукта и предпочтений конкретного сегмента ЦА.
• Если УТП продукта не очевидно для ЦА либо незначительно для принятия решения о покупке.
• Когда стандартные механики, традиционно применимые для продвижения продукта, не приводят к желаемому результату.
• Если целевая аудитория «размыта» либо нечетко сегментирована.
• В случае существующих законодательных либо иных ограничений.
Смотреть что такое «CTL» в других словарях:
CTL — can refer to: *Computation tree logic *Cut to length logging *Complex Text Layout languages *cytotoxic T cell (cytotoxic T lymphocyte) *Commission de transport de la Ville de Laval *Coal to liquids, the chain of chemical processes to transform… … Wikipedia
CTL — CTL, sigle composé des trois lettres C, T et L, peut faire référence à : Charleville dans le Queensland, en Australie, selon la liste des codes AITA des aéroports, CTL de l anglais Coal to liquid ou en français charbon liquide. Désigne en… … Wikipédia en Français
ctl — ctl; CTL; … English syllables
CTL — UK US noun [U] ► INSURANCE ABBREVIATION for CONSTRUCTIVE TOTAL LOSS(Cf. ↑constructive total loss) … Financial and business terms
CTL — (cytotoxic T lymphocyte) killer T cells, immune system cell that kills cancerous or infected cells, primary type of cell involved in cell mediated immunity (Immunology) … English contemporary dictionary
CTL* — Die Computation Tree Logic (kurz CTL) ist eine Temporale Logik, die speziell zur Spezifikation und Verifikation von Computersystemen dient. Meist wird sie auch mit CTL* bezeichnet. CTL bezeichnet dann eine spezielle Teilmenge der CTL* Formeln.… … Deutsch Wikipedia
CTL — Die Abkürzung CTL steht für Cobalt Titan Lithium, Spezial Knopfzelle, aufladbar Complex Text Layout, Schriftsysteme, die nicht von links nach rechts ausgerichtet sind. Computation Tree Logic Control Track Longitudinal, ein Bildzählimpuls auf der… … Deutsch Wikipedia
CTL — See cytotoxic T cells … Dictionary of molecular biology
2.2 Потоки
От переводчика: данная статья является седьмой в цикле переводов официального руководства по библиотеке SFML. Прошлую статью можно найти тут. Данный цикл статей ставит своей целью предоставить людям, не знающим язык оригинала, возможность ознакомится с этой библиотекой. SFML — это простая и кроссплатформенная мультимедиа библиотека. SFML обеспечивает простой интерфейс для разработки игр и прочих мультимедийных приложений. Оригинальную статью можно найти тут. Начнем.
1. Приступая к работе
Что такое поток?
Большая часть из вас уже знает, что такое поток, однако объясним, что это такое, для новичков в данной теме.
Поток — это по сути последовательность инструкций, которые выполняются параллельно с другими потоками. Каждая программа создает по меньшей мере один поток: основной, который запускает функцию main(). Программа, использующая только главный поток, является однопоточной; если добавить один или более потоков, она станет многопоточной.
Так, короче, потоки — это способ сделать несколько вещей одновременно. Это может быть полезно, например, для отображения анимации и обработки пользовательского ввода данных во время загрузки изображений или звуков. Потоки также широко используется в сетевом программировании, во время ожидания получения данные будет продолжаться обновление и рисование приложения.
Потоки SFML или std::thread?
В своей последней версии (2011), стандартная библиотека C++ предоставляет набор классов для работы с потоками. Во время написания SFML, стандарт C++11 еще не был написан и не было никакого стандартного способа создания потоков. Когда SFML 2.0 был выпущен, было много компиляторов, которые не поддерживали этот новый стандарт.
Создание потоков с помощью SFML
Хватит разглагольствований, давайте посмотрим на код. Класс, дающий возможность создавать потоки с помощью SFML, называется sf::Thread, и вот как это (создание потока) выглядит в действии:
В этом коде функции main и func выполняются параллельно после вызова thread.launch(). Результатом этого является то, что текст, выводимый обеими функциями, смешивается в консоли.
Точка входа в поток, т.е. функция, которая будет выполняться, когда поток запускается, должна быть передана конструктору sf::Thread. sf::Thread пытается быть гибким и принимать различные точки входа: non-member функции или методы классов, функции с аргументами или без них, функторы и так далее. Приведенный выше пример показывает, как использовать функцию-член, вот несколько других примеров.
Последний пример, который использует функтор, является наиболее мощным, поскольку он может принимать любые типы функторов и поэтому делает класс sf::Thread совместимым со многими типами функций, которые напрямую не поддерживаются. Эта функция особенно интересна с лямбда-выражениями C++11 или std::bind.
Если вы хотите использовать sf::Thread внутри класса, не забудьте, что он не имеет стандартного конструктора. Поэтому, вы должны инициализировать его в конструкторе вашего класса в списке инициализации:
Если вам действительно нужно создать экземпляр sf::Thread после инициализации объекта, вы можете создать его в куче.
Запуск потока
После того, как вы создали экземпляр sf::Thread, вы должны запустить его с помощью запуска функции.
launch вызывает функцию, которую вы передали в конструктор нового потока, и сразу же завершает свою работу, так что вызывающий поток может сразу же продолжить выполнение.
Остановка потоков
Поток автоматически завершает свою работу, когда функция, служащая точкой входа для данного потока, возвращает свое значение. Если вы хотите ждать завершения потока из другого потока, вы можете вызвать его функцию wait.
Функция ожидания также неявно вызывается деструктором sf::Thread, так что поток не может оставаться запущенным (и бесконтрольным) после того, как его экземпляр sf::Thread уничтожается. Помните это, когда вы управляете вашими потоками (смотрите прошлую секцию статьи).
Приостановка потока
В SFML нет функции, которая бы предоставляла способ приостановки потока; единственный способ приостановки потока — сделать это из кода самого потока. Другими словами, вы можете только приостановить текущий поток. Что бы это сделать, вы можете вызвать функцию sf::sleep:
sf::sleep имеет один аргумент — время приостановки. Это время может быть выражено в любой единице, как было показано в статье про обработку времени.
Обратите внимание, что вы можете приостановить любой поток с помощью данной функции, даже главный поток.
sf::sleep является наиболее эффективным способом приостановить поток: на протяжении приостановки потока, он (поток) практически не потребляет ресурсы процессора. Приостановка, основанная на активном ожидании, вроде пустого цикла while, потребляет 100% ресурсов центрального процессора и делает… ничего. Однако имейте в виду, что продолжительность приостановки является просто подсказкой; реальная продолжительность приостановки (больше или меньше указанного вами времени) зависит от ОС. Так что не полагайтесь на эту функцию при очень точном отсчете времени.
Защита разделяемых данных
Все потоки в программе разделяют некоторую память, они имеют доступ ко всем переменным в области их видимости. Это очень удобно, но также опасно: с момента параллельного запуска потока, переменные или функции могут использоваться одновременно разными потоками. Если операция не является потокобезопасной, это может привести к неопределенному поведению (т. е. это может привести к сбою или повреждению данных).
Существует несколько программных инструментов, которые могут помочь вам защитить разделяемые данные и сделать ваш код потокобезопасным, их называют примитивами синхронизации. Наиболее распространенными являются следующие примитивы: мьютексы, семафоры, условные переменные и спин-блокировки. Все они — варианты одной и той же концепции: они защищают кусок кода, давая только определенному потоку право получать доступ к данным и блокируя остальные.
Наиболее распространенным (и используемым) примитивом является мьютекс. Мьютекс расшифровывается как «Взаимное исключение». Это гарантия, что только один поток может выполнять код. Посмотрим, как мьютексы работают, на примере ниже:
Этот код использует общий ресурс (std::cout), и, как мы видим, это приводит к нежелательным результатам. Вывод потоков смешался в консоли. Чтобы убедиться в том, что вывод правильно напечатается, вместо того, чтобы быть беспорядочно смешанным, мы защищаем соответствующие области кода мьютексом.
Первый поток, который достигает вызова mutex.lock(), блокирует мьютекс и получает доступ к коду, который печатает текст. Когда другие потоки достигают вызова mutex.lock(), мьютекс уже заблокирован, и другие потоки приостанавливают свое выполнение (это похоже на вызов sf::sleep, спящий поток не потребляет время центрального процессора). Когда первый поток разблокирует мьютекс, второй поток продолжает свое выполнение, блокирует мьютекс и печатает текст. Это приводит к тому, что текст в консоли печатается последовательно и не смешивается.
Мьютекс — это не только примитив, который вы можете использовать для защиты разделяемых данных, вы можете использовать его во многих других случаях. Однако, если ваше приложение делает сложные вещи при работе с потоками, и вы чувствуете, что возможностей мьютексов недостаточно — не стесняйтесь искать другую библиотеку, обладающую большим функционалом.
Защита мьютексов
Не волнуйтесь: мьютексы уже потокобезопасны, нет необходимости их защищать. Но они не безопасны в плане исключений. Что происходит, если исключение выбрасывается, когда мьютекс заблокирован? Он никогда не может быть разблокирован и будет оставаться заблокированным вечно. Все потоки, пытающиеся разблокировать заблокированный мьютекс, будут заблокированы навсегда. В некоторых случаях, ваше приложение будет «заморожено».
Чтобы быть уверенным, что мьютекс всегда разблокирован в среде, в которой он (мьютекс) может выбросить исключение, SFML предоставляет RAII класс, позволяющий обернуть мьютекс в класс sf::Lock. Блокировка происходит в конструкторе, разблокировка происходит в деструкторе. Просто и эффективно.
Помните, что sf::Lock может также быть использован в функциях, которые имеют множество возвращаемых значений.
Распространенные заблуждения
Вещь, часто упускаемая из виду: поток не может существовать без соответствующего экземпляра sf::Thread. Следующий код можно часто увидеть на форумах:
Программисты, которые пишут подобный код, ожидают, что функция startThread() будет запускать поток, который будет жить самостоятельно и уничтожаться при завершении выполнения функции (переданной в качестве точки входа). Этого не происходит. Функция потока блокирует главный поток, как если бы программа не работала.
В чем дело? Экземпляр sf::Thread является локальным для функции startThread(), поэтому немедленно уничтожаются, когда функция возвращает свое значение. Вызывается деструктор sf::Thread, происходит вызов wait(), как утверждалось выше, результатом этого становится блокировка главного потока, который ожидает завершения функции потока, вместо параллельного выполнения с ней.
Так что не забывайте: вы должны управлять экземплярами sf::Thread, чтобы они жили так долго, как требуется функции потока.
Google’s Certificate Transparency как источник данных для предотвращения атак
Мы подготовили перевод статьи Райана Сирса об обработке логов Google’s Certificate Transparency, состоящей из двух частей. В первой части дается общее представление о структуре логов и приводится пример кода на Python для парсинга записей из этих логов. Вторая часть посвящена получению всех сертификатов из доступных логов и настройке системы Google BigQuery для хранения и организации поиска по полученным данным.
С момента написания оригинала прошло уже три года и с тех пор количество доступных логов и, соответственно, записей в них возросло многократно. Тем более важно правильно подойти к обработке логов, если целью является максимизация количества получаемых данных.
Часть 1. Parsing Certificate Transparency Logs Like a Boss
Чтобы понять, с какими объемами данных придется иметь дело, давайте посмотрим, сколько записей содержится в каждом логе из списка с сайта CTL:
На выходе получаем:
285,037,607 на момент написания статьи. Это не такой большой объем данных, но все равно придется приложить определенные усилия, чтобы эффективно организовать хранение и поиск по сертификатам. Подробнее об этом во второй части.
Стоит отметить, что API выдает количество записей в логе, значительную часть которых составляют PreCerts (о них далее) и не представляют особого интереса. Также важно учитывать, что сертификаты могут дублироваться между разными логами, к примеру, данный сертификат присутствует одновременно в 6 различных логах, поддерживаемых Chrome. Таким образом, реальное число сертификатов значительно меньше, чем суммарное число записей в логах.
Тем не менее, на момент написания перевода, учитывая только логи, удовлетворяющие политике Google и включенные в Chrome, в списке присутствует 46 логов, содержащие в сумме 6,861,473,804 записей, что уже потребует значительных ресурсов для полной обработки.
Анатомия CTL
Получение записей из CTL осуществляется по HTTP, что позволит нам легко получать данные с помощью современных библиотек. К сожалению, сами данные в записях представляют собой запутанные бинарные структуры, что несколько усложняет процесс парсинга. Пример записи в логе:
Про PreCerts
Мне потребовалось довольно много времени, чтобы разобраться, что вообще такое PreCert (можете попробовать сами, почитайте RFC, и, по всей видимости, я такой не один. Сохраню вам кучу времени на раздумья и поиски в гугле и сформулирую назначение PreCerts следующим образом:
PreCerts это отдельный тип сертификата, выпускаемого CA до того, как тот выпустит “настоящий” сертификат. Фактически, это копия исходного сертификата, но содержащая специальное расширение x509 v3, называемое poison и отмеченное как критическое. Таким образом, сертификат не будет валидирован как платформами, распознающими это расширение, и знающими что это PreCert, так и платформами, которые это расширение не распознают.
Мой опыт в ИБ говорит о том, что такая мера не сильно эффективна, хотя бы потому, что баги при парсинге x509/ASN.1 встречаются довольно часто и отдельные реализации могут быть уязвимы к различным махинациям, которые в конечном счете позволят валидировать PreCert. Я понимаю, зачем это было сделано, но складывается ощущение, что полностью убрать PreCerts и оставлять в CTL только сертификаты, действительно выпущенные CA, было бы намного разумнее.
Парсим бинарные структуры
Как для человека, занимающегося реверс-инжинирингом и время от времени участвующего в разных CTF, задача парсинга бинарных структур для меня не нова. Большинство людей в таких случаях обращаются к модулю struct, но много лет назад, во время работы на Филлипа Мартина, он познакомил меня с отличной библиотекой Construct, которая заметно упрощает парсинг подобных структур. Ниже приведены структуры, которые я использовал для парсинга, а также пример их использования для обработки записей:
Получаем массив X509 сертификатов из цепочки с сертификатом из leaf_input в качестве первого элемента
Как можете заметить, Construct позволяет довольно легко определять бинарные структуры на Python.
Часть 2. Retrieving, Storing and Querying 250M+ Certificates Like a Boss
Сбор сертификатов
На момент написания перевода большинство логов Google (Argon, Xenon, Aviator, Icarus, Pilot, Rocketeer, Skydiver) предоставляют лишь по 32 записи для каждого запроса, но для ускорения получения записей можно одновременно отправлять несколько запросов на один и тот же лог, насколько позволяет пропускная способность, но работает такой подход не для всех логов.
Отдельные логи позволяют получать по 1024 и более записей за раз, но большинство CTL, помимо Google, выдает по 256 записей за один запрос.
Так как задача одновременно IO-bound (получение записей по http) и CPU-bound (парсинг сертификатов), для эффективной обработки необходимо будет подключить как асинхронность, так и многопроцессность.
Так как не было никаких инструментов, которые позволили бы легко и безболезненно получить и распарсить все CTL (помимо не особо примечательной утилиты от Google, было решено потратить немного времени и написать свой инструмент, который соответствовал бы всем нашим потребностям. Результатом стал Axeman, который использует asyncio и замечательную библиотеку aioprocessing для загрузки, парсинга и сохранения сертификатов в несколько CSV файлов, ограничиваясь при этом только скоростью интернет-соединения.
Эксплуатация облака
После получения инстанса (_прим. перев._ так в Google Cloud называются VM) c 16 ядрами, 32Гб памяти и SSD на 750Гб (спасибо Google за бесплатные 300$ на счете для новых аккаунтов!), я запустил Axeman, который загрузил все сертификаты меньше чем за сутки и сохранил результаты в /tmp/certificates/$CTL_DOMAIN/
Где хранить все эти данные?
На начальном этапе для осуществления хранения и поиска по данным был выбран Postgres, но, хотя я и не сомневаюсь, что с правильной схемой Postgres легко бы справился с 250 миллионами записей (в отличии от моей первой попытки, в которой на один запрос уходило примерно 20 минут!), я начал искать решения, которые:
позволяют дешево хранить большой объем данных
обеспечивают быстрый поиск
позволяют легко обновлять данные
Вариантов было несколько, но с точки зрения стоимости, почти все рассмотренные варианты (AWS RDS, Heroku Postgres, Google Cloud SQL) были весьма затратны. К счастью, так как наши данные в принципе никогда не изменяются, у нас появляется дополнительная гибкость в выборе платформы для размещения данных.
В целом, это как раз тот тип поиска по данным, который прекрасно ложится на модель map/reduce с использованием, к примеру, Spark или Hadoop Pig. Просматривая предложения различных провайдеров в категории “big data” (хотя в нашей задаче данных явно мало для включения в эту категорию), я наткнулся на Google BigQuery, который удовлетворяет всем обозначенным параметрам.
Скармливаем данные BigQuery
Загрузка данных в BigQuery осуществляется довольно легко, благодаря предоставляемой Google утилите gsutil. Создаем новый бакет для наших сертификатов:
И видим следующий результат в нашем бакете:
Далее создаем новый датасет в BigQuery:
Теперь мы можем импортировать данные из хранилища в наш новый датасет. К сожалению, в BigQuery нет кнопки “пожалуйста, импортируй все папки рекурсивно”, так что придется импортировать каждый CTL отдельно, но занимает это не так долго. Создаем таблицу и импортируем наш первый лог (обратите особое внимание на отмеченные настройки):
Так как схема нужна всякий раз при импорте очередного лога, воспользуемся опцией “Edit as Text”. Использованная схема:
Далее просто повторяем процесс для каждого лога. Убедитесь, что каждый импорт завершился успешно (ошибки обычно можно игнорировать, просто убедитесь, что вы задали адекватное значения для максимального количества ошибок). В итоге должен получиться примерно такой датасет:
Что в итоге получилось
Настало время пожинать плоды наших трудов и опробовать систему на различных запросах.
В последнее время часто говорят о доменах, использующих punycode и связанных с ними омоглифных атаках. Попробуем следующий запрос:
И всего через 15 секунд получаем результат со всеми punycode доменами из всех известных CTL!
Рассмотрим другой пример. Попробуем получить все сертификаты доменов Coinbase, записанные в Certificate Transparency:
Всего через две секунды получаем все интересующие нас результаты:
Небольшая загадка
Проводя исследования, я обнаружил нечто странное. Домен flowers-to-the-world.com постоянно возникал в различных логах. Практически каждый лог имел огромное число сертификатов, содержащих этот домен:
Whois позволяет определить, что этот домен принадлежит Google, так что мне интересно, не является ли это частью какой-то тестовой рутины. Если вы инженер Google, который может разузнать что-то у товарищей, занимающихся Certificate Transparency, было бы очень интересно услышать об этом.
Ответ инженера Google в комментариях под оригинальным постом
Ответ инженера Google в комментариях под оригинальным постом
Привет, Райан. Пишет Пол Хэдфилд из команды Certificate Transparency.
flowers-to-the-world.com действительно принадлежит Google. Мы используем этот домен чтобы генерировать сертификаты, которые затем добавляются в каждый CTL в рамках периодической проверки логов на соответствие стандартам RFC6962. Проверка проводится с целью удостоверится, что логи работают в соответствии со стандартами и имеют приемлемый аптайм.
Наблюдаемое распределение количества раз, которое домен встретился в каждом логе, является в основном функцией от того, сколько этот лог существует, но также зависит от того, насколько быстро лог может добавить новый сертификат в свое дерево Меркла.
Принципы построения систем потоковой аналитики
Проектирование систем потоковой аналитики и потоковой обработки данных имеет свои нюансы, свои проблемы и свой технологический стек. Об этом мы поговорили в очередном открытом уроке, прошедшим накануне запуска курса «Data Engineer».
На вебинаре обсудили:
Когда нужна потоковая обработка? Stream vs Batch
Прежде всего, следует разобраться, когда нам нужна потоковая, а когда пакетная обработка. Давайте поясним сильные и слабые стороны этих подходов.
Итак, минусы пакетной обработки (batch):
Пример 2. Аналитика для веб-портала:
Таким образом, во втором примере лучше использовать стримы.
Элементы СПОД
Инженеры обработки данных захватывают, перемещают, доставляют, преобразовывают и хранят эти самые данные (да-да, хранить данные — это тоже активный процесс!).
Следовательно, чтобы построить систему потоковой обработки данных (СПОД), нам будут нужны следующие элементы:
Инструменты для обработки потоков данных
На роль загрузчика данных у нас есть несколько «кандидатов»:
Apache Flume
Первый, о ком поговорим — это Apache Flume — инструмент для транспортировки данных между различными источниками и хранилищами.
Выше мы создаём один простейший канал, который “сидит” на порту, берёт оттуда данные и просто их логирует. В принципе, для описания одного процесса это ещё нормально, но когда у вас таких процессов десятки, конфигурационный файл превращается в ад. Кто-то добавляет некие визуальные конфигураторы, но зачем мучиться, если есть инструменты, которые делают это из коробки? Например, те же NiFi и StreamSets.
Apache NiFi
По сути, выполняет ту же роль, что и Flume, но уже с визуальным интерфейсом, что большой плюс, особенно когда процессов много.
Пару фактов о NiFi
У нас есть поле для творчества и этапы обработки данных, которые мы туда накидываем. Есть много коннекторов на все возможные системы и т. д.
StreamSets
Это тоже система управления потоком данных с визуальным интерфейсом. Она разработана выходцами из Cloudera, легко устанавливается в виде Parcel на CDH, имеет особую версию SDC Edge для сбора данных с устройств.
Состоит из двух компонент:
Неприятный момент — у StreamSets есть как бесплатная, так и платная части.
Шина обмена данными
Теперь давайте разберёмся, куда мы эти данные будем заливать. Претенденты:
Во всех остальных случаях, Kafka — отличный выбор. По сути, это брокер сообщений с горизонтальным масштабированием и огромной пропускной способностью. Он отлично интегрирован во всю экосистему инструментов для работы с данными и выдерживает большие нагрузки. Обладает универсальнейшим интерфейсом и является кровеносной системой нашей обработки данных.
Внутри Kafka делится на Topic — некий отдельный поток данных из сообщений с одинаковой схемой или, хотя бы, с одинаковым назначением.
Чтобы обсудить следующий нюанс, нужно вспомнить, что источники данных могут немного различаться. Очень важен формат данных:
Отдельного упоминания заслуживает формат сериализации данных Apache Avro. Система использует JSON для определения структуры данных (схемы), которые сериализуются в компактный бинарный формат. Следовательно, мы экономим огромное количество данных, а сериализация/десериализация происходит дешевле.
Вроде бы всё неплохо, но наличие отдельных файлов со схемами порождает проблему, так как нам нужно между разными системами обмениваться файлами. Казалось бы, это просто, но когда вы работаете в разных отделах, ребята на другом конце могут что-нибудь поменять и успокоиться, а у вас всё поломается.
Чтобы не передавать все эти файлы на флешках, дискетах и наскальных рисунках, существует специальный сервис — Schema registry. Это сервис для синхронизации avro-схем между сервисами, которые пишут и читают из Kafka.
В терминах Kafka продюсер — это тот, кто пишет, консьюмер — тот, кто потребляет (читает) данные.
Хранилище данных
Претенденты (на самом деле вариантов много больше, но возьмем лишь несколько):
Как этого добиться в стриминговых системах:
Что касается ClickHouse, то это аналитическая база данных от Yandex. Её главное назначение — аналитика на таблице, наполняемой большим потоком сырых данных. Из плюсов — есть движок ReplacingMergeTree для дедупликации по ключу (дедупликация предназначена для экономии места и может оставлять дубликаты в некоторых случаях, нужно учитывать нюансы).
Остаётся добавить несколько слов про Divolte. Если помните, мы говорили о том, что некоторые данные нужно захватывать. Если вам нужно быстро и на коленке организовать аналитику для какого-нибудь портала, то Divolte — отличный сервис для захвата пользовательских событий на веб-странице через JavaScript.
Практический пример
Что попытаемся сделать? Попробуем построить пайплайн, чтобы в реальном времени собирать Clickstream-данные. Clickstream — виртуальный след, который пользователь оставляет во время нахождения на вашем сайте. Будем захватывать данные с помощью Divolte, а писать их в Kafka.
Для работы нужен Docker, плюс потребуется клонировать следующий репозиторий. Всё происходящее будет запущено в контейнерах. Чтобы согласованно запустить сразу несколько контейнеров будет использоваться docker-compose.yml. Кроме того, есть Dockerfile, собирающий наш StreamSets с определёнными зависимостями.
Также есть три папки:
Для запуска вводим следующую команду:
И наслаждаемся тем, как медленно, но верно запускаются контейнеры. После запуска мы можем перейти по адресу http://localhost:18630/ и сразу же потрогать Divolte:
Итак, у нас есть Divolte, который уже получил какие-то события и записал их в Kafka. Попробуем их высчитать с помощью StreamSets: http://localhost:18630/ (пароль/логин — admin/admin).
Чтобы не мучиться, лучше импортировать Pipeline, назвав его, к примеру, clickstream_pipeline. А из папки examples импортируем clickstream.json. Если всё ок, увидим следующую картину:
Итак, мы создали connection к Кафке, прописали, какая Кафка нам нужна, прописали, какой топик нас интересует, потом выбрали те поля, которые нас интересуют, потом поставили слив в Кафку, прописав, в какую Кафку и какой топик. Отличия в том, что в одном случае, Data format — это Avro, а во втором — просто JSON.
Идём дальше. Мы можем, например, сделать превью, которое захватит в реальном времени из Кафки определённые записи. Далее всё записываем.
Выполнив запуск, увидим, что у нас в Кафку летит поток событий, причём это происходит в реал-тайме:
Теперь можно сделать для этих данных хранилище в ClickHouse. Чтобы работать с ClickHouse, можно использовать простой нативный клиент, выполнив следующую команду:
Обратите внимание — в этой строке указана сеть, к которой нужно подключаться. И в зависимости от того, как у вас называется папка с репозиторием, название сети у вас может отличаться. В общем случае команда будет следующей:
Список сетей можно посмотреть командой:
Что же, осталось всего ничего:
1. Сначала «подпишем» наш ClickHouse на Кафку, «объяснив ему», какого формата данные там нам нужны:
2. Теперь создадим реальную таблицу, куда будем класть итоговые данные:
3. А потом обеспечим связь между этими двумя таблицами:
4. А теперь выберем необходимые поля:
В итоге выбор из целевой таблицы даст нужный нам результат.
Вот и всё, это был простейший Clickstream, который можно построить. Если хотите выполнить вышеописанные шаги самостоятельно, смотрите видео целиком.