djobi djoba что значит

Перевод песни Djobi Djoba (Zorro)

Djobi Djoba

Djobi Djoba

Ay niña
Yo te encuentro
Sólita por la calle
Yo me siento ay ‘namorao
Yo me siento ay triste y solo

Djobi Djoba
Cada día te quiero más
Djobi Djobi, Djobi Djoba
Cada día yo te quiero más
Djobi Djobi, Djobi Djoba
Cada día yo te quiero más

Pero me importa
Que la distancia hoy
Ya no nos separa
Que voy acordandome de ti
Y no me diga ay
ay Paragua’ya ya yay.

Djobi Djoba
Cada día te quiero más
Djobi Djobi, Djobi Djoba
Cada día yo te quiero más
Djobi Djobi, Djobi Djoba
Cada día yo te quiero más

Эй, малышка,
Я встречаю тебя
Одну на улице
Я чувствую себя влюблённым.
Я чувствую себя грустным и одиноким.

Djobi Djoba
С каждым днём я люблю тебя всё больше.
Djobi Djobi, Djobi Djoba
С каждым днём я люблю тебя всё больше.
Djobi Djobi, Djobi Djoba
С каждым днём я люблю тебя всё больше.

Но мне важно
Что дистанция сегодня
Уже не отделяет нас.
Я не уйду от тебя,
И не говори мне
ay Paragua’ya ya yay.

Djobi Djoba
С каждым днём я люблю тебя всё больше.
Djobi Djobi, Djobi Djoba
С каждым днём я люблю тебя всё больше.
Djobi Djobi, Djobi Djoba
С каждым днём я люблю тебя всё больше.

Источник

Продвинутые абстракции Kubernetes: Job, CronJob

Что такое Job и CronJob в Kubernetes, для чего они нужны, а для чего их использовать не стоит.
Эта статья — выжимка из лекции вечерней школы «Слёрм Kubernetes».

Job: сущность для разовых задач

Job (работа, задание) — это yaml-манифест, который создаёт под для выполнения разовой задачи. Если запуск задачи завершается с ошибкой, Job перезапускает поды до успешного выполнения или до истечения таймаутов. Когда задача выполнена, Job считается завершённым и больше никогда в кластере не запускается. Job — это сущность для разовых задач.

Когда используют Job

При установке и настройке окружения. Например, мы построили CI/CD, который при создании новой ветки автоматически создаёт для неё окружение для тестирования. Появилась ветка — в неё пошли коммиты — CI/CD создал в кластере отдельный namespace и запустил Job — тот, в свою очередь, создал базу данных, налил туда данные, все конфиги сохранил в Secret и ConfigMap. То есть Job подготовил цельное окружение, на котором можно тестировать и отлаживать новую функциональность.

При выкатке helm chart. После развёртывания helm chart с помощью хуков (hook) запускается Job, чтобы проверить, как раскатилось приложение и работает ли оно.

Таймауты, ограничивающие время выполнения Job

Job будет создавать поды до тех пор, пока под не завершится с успешным результатом. Это значит, что если в поде есть ошибка, которая приводит к неуспешному результату (exit code не равен 0), то Job будет пересоздавать этот под до бесконечности. Чтобы ограничить перезапуски, в описании Job есть два таймаута: activeDeadlineSeconds и backoffLimit.

activeDeadlineSeconds — это количество секунд, которое отводится всему Job на выполнение. Обратите внимание, это ограничение не для одного пода или одной попытки запуска, а для всего Job.

Например, если указать в Job, что activeDeadlineSeconds равен 200 сек., а наше приложение падает с ошибкой через 5 сек., то Job сделает 40 попыток и только после этого остановится.

backoffLimit — это количество попыток. Если указать 2, то Job дважды попробует запустить под и остановится.

Параметр backoffLimit очень важен, потому что, если его не задать, контроллер будет создавать поды бесконечно. А ведь чем больше объектов в кластере, тем больше ресурсов API нужно серверам, и что самое главное: каждый такой под — это как минимум два контейнера в остановленном состоянии на узлах кластера. При этом поды в состоянии Completed или Failed не учитываются в ограничении 110 подов на узел, и в итоге, когда на узле будет несколько тысяч контейнеров, докер-демону скорее всего будет очень плохо.

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

Удаление Job

После успешного завершения задания манифесты Job и подов, созданных им, остаются в кластере навсегда. Все поля Job имеют статус Immutable, то есть «неизменяемый», и поэтому обычно при создании Job из различных автоматических сценариев сначала удаляют Job, который остался от предыдущего запуска. Практика генерации уникальных имен для запуска таких Job может привести к накоплению большого количества ненужных манифестов.

В Kubernetes есть специальный TTL Controller, который умеет удалять завершенные Job вместе с подами. Вот только он появился в версии 1.12 и до сих пор находится в статусе alpha, поэтому его необходимо включать с помощью соответствующего feature gate TTLAfterFinished.

ttlSecondsAfterFinished — указывает, через сколько секунд специальный TimeToLive контроллер должен удалить завершившийся Job вместе с подами и их логами.

Манифест

Посмотрим на пример Job-манифеста.

В начале указаны название api-группы, тип сущности, имя и дальше — спецификация.

В спецификации указаны таймауты и темплейт пода, который будет запускаться. Опции backoffLimit: 2 и activeDeadlineSeconds: 60 значат, что Job будет пытаться выполнить задачу не более двух раз и в общей сложности не дольше 60 секунд.

template — это описание пода, который будет выполнять задачу; в нашем случае запускается простой контейнер busybox, который выводит текущую дату и передаёт привет из Kubernetes.

Практические примеры

И посмотрим, что получилось.

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

Статистику по Job можно посмотреть следующей командой.

Видим, что завершились все задания, время выполнения — 5 секунд.

Читайте также:  какой мед лучше для горла

Ненужный Job обязательно надо удалять. Потому что, если мы не удалим его руками, Job и под будут висеть в кластере всегда — никакой garbage collector не придёт и не удалит их.

Если у вас запускаются по 10-20 заданий в час, и никто их не удаляет, они копятся и в кластере появляется много абстракций, которые никому не нужны, но место занимают. А как я уже говорил выше, каждый под в состоянии Completed — это, как минимум, два остановленных контейнера на узле. А докер демон начинает притормаживать, если на узле оказывается несколько сотен контейнеров, и не важно, работают они или остановлены.

Команда для удаления:

Что будет, если сломать Job

Job, который выполняется без проблем, не очень интересен. Давайте мы над ним немного поиздеваемся.

Поправим yaml: добавим в темплейт контейнера exit 1. То есть скажем Job’у, чтобы он завершался с кодом завершения 1. Для Kubernetes это будет сигналом о том, что Job завершился неуспешно.

Применяем и смотрим, что происходит: один контейнер создался и упал с ошибкой, затем ещё и ещё один. Больше ничего не создаётся.

В статистике подов видим, что создано три пода, у каждого статус Error. Из статистики Job следует, что у нас создан один Job и он не завершился.

Если посмотреть описание, то увидим, что было создано три пода, и Job завершился, потому что был достигнут backoffLimit.

Обратите внимание! В yaml лимит равен 2. То есть, если следовать документации, Job должен был остановиться после двух раз, но мы видим три пода. В данном случае «после выполнения двух раз» значит 3 попытки. Когда мы проделываем то же самое на интенсиве с сотней студентов, то примерно у половины создаётся два пода, а у оставшихся три. Это надо понять и простить.

Проверка ограничения по времени

Сделаем бесконечный цикл и посмотрим, как работает ограничение по времени — activeDeadlineSeconds.

Ограничения оставим теми же (60 секунд), изменим описание контейнера: сделаем бесконечный цикл.

Если посмотреть в логи, то увидим, что каждую секунду у нас появляется новый «Hello» — всё как надо.

Через 60 секунд под оказывается в статусе Terminating (иногда это происходит через ± 10 сек).

Вспомним, как в Kubernetes реализована концепция остановки подов. Когда приходит время остановить под, то есть все контейнеры в поде, контейнерам посылается sigterm-сигнал и Kubernetes ждёт определённое время, чтобы приложение внутри контейнера отреагировало на этот сигнал.

В нашем случае приложение — это простой bash-скрипт с бесконечным циклом, реагировать на сигнал некому. Kubernetes ждёт время, которое задано в параметре graceful shutdown. По дефолту — 30 секунд. То есть если за 30 секунд приложение на sigterm не среагировало, дальше посылается sigkill и процесс с pid 1 внутри контейнера убивается, контейнер останавливается.

Спустя чуть более 100 секунд под удалился. Причем ничего в кластере не осталось, потому что единственный способ остановить что-то в контейнере — это послать sigterm и sigkill. После этого приходит garbage collector, который удаляет все поды в статусе Terminating, чтобы они не засоряли кластер.

В описании Job мы увидим, что он был остановлен, так как активность превысила допустимую.

Поле restartPolicy

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

Это политика по умолчанию, и если её применить в Job, то Job-контроллер не сможет получить информацию о том, что под был завершён с ошибкой. С его точки зрения под будет очень долго выполняться, а то, что kubelet перезапускает упавший контейнер, Job-контроллер не увидит.

CronJob: создание объектов Job по расписанию

Job позволяет выполнить разовые задачи, но на практике постоянно возникает потребность выполнять что-то по расписанию. И вот здесь Kubernetes предлагает CronJob.

CronJob — это yaml-манифест, на основании которого по расписанию создаются Job’ы, которые в свою очередь создают поды, а те делают полезную работу.

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

В манифесте CronJob указывают расписание и ещё несколько важных параметров.

И два параметра, которые влияют на историю выполнения.

Посмотрим на манифест CronJob и поговорим о каждом параметре подробнее.

schedule — это расписание в виде строчки, которая имеет обычный cron-формат. Строчка в примере говорит о том, что наш Job должен выполняться раз в минуту.

concurrencyPolicy — этот параметр отвечает за одновременное выполнение заданий. Бывает трёх видов: Allow, Forbid, Replace.

Allow позволяет подам запускаться. Если за минуту Job не отработал, все равно будет создан ещё один. Одновременно могут выполняться несколько Job’ов.

Например, если один Job выполняется 100 сек., а Cron выполняется раз в минуту, то запускается Job, выполняется 61 сек., в это время запускается ещё один Job. В итоге в кластере одновременно работают два Job’a, которые выполняют одну и ту же работу. Возникает положительная обратная связь: чем больше Job’ов запущено, тем больше нагрузка на кластер, тем медленнее они работают, тем дольше они работают и тем больше одновременных подов запускается — в итоге всё застывает под бешеной нагрузкой.

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

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

Читайте также:  какой линолеум самый прочный для коридора

jobTemplate — это шаблон, из которого создаётся объект Job. Ну а всё остальное мы уже видели в манифесте Job.

Посмотрим, что получилось:

Увидим название CronJob, расписание, параметр запуска, количество активных Job’ов и сколько времени они работают.

Раздел Suspend — временная приостановка CronJob. В данном случае указано значение False. Это значит, что CronJob выполняется. Можно отредактировать манифест и поставить опцию True, и тогда он не будет выполняться, пока мы его снова не запустим.

Active — сколько Job’ов создано, Last Schedule — когда последний раз исполнялся.

Теперь можно посмотреть статистику по Job’ам и подам.

Видно, что создан один Job.

Под создан, он выполнил полезную работу.

Что получается: CronJob создал Job, Job создал под, под отработал, завершился — всё здорово.

Ещё раз посмотрим на CronJob:

Last Schedule был 19 секунд назад. Если посмотреть на Job, то увидим, что у нас появился следующий Job и следующий под.

Возникает вопрос: а что будет, если CronJob отработает хотя бы пару недель? Неужели у нас в кластере будет столько же Job’ов и подов в статусе Completed, сколько в этой паре недель минут?

Когда CronJob’ы только появились и были на стадии альфа-тестирования, примерно это и происходило: делали CronJob раз в минуту, смотрели — работает, всё здорово, а через неделю кластер становился неработоспособным, потому что количество остановленных контейнеров на узлах было ошеломляющим. Теперь же ситуация изменилась.

Снова откроем манифест и посмотрим, что было добавлено:

Появились опции failedJobHistorLimit со значением 1 и successfulJobHistoryLimit со значением 3. Они отвечают за количество Job’ов, которые остаются одновременно в кластере. То есть CronJob не только создаёт новые Job’ы, но и удаляет старые.

Когда только контроллер CronJob создавался, эти опции не были установлены по умолчанию и CronJob за собой ничего не удалял. Было много возмущений от пользователей, и тогда поставили дефолтные лимиты.

И на сладкое — про startingDeadlineSeconds

В параметре startingDeadlineSeconds указывают количество секунд, на которое можно просрочить запуск Job. Если по каким-то причинам Job не создался и с момента, когда его надо было создать, прошло больше секунд, чем указано в этом параметре, то он и не будет создан. А если меньше, то хоть и с опозданием, Job будет создан.

Тут есть небольшая ловушка, если concurrencyPolicy разрешают одновременное создание Job, то при большом значении параметра startingDeadlineSeconds возможен одновременный запуск десятков пропущенных Job одновременно. Для уменьшения всплеска нагрузки в код Kubernetes захардкожены лимиты и запрещающие процедуры:

Если параметр startingDeadlineSeconds не указан в манифесте:

CronJob контроллер при создании Job смотрит на время последнего запуска — значение LastscheduleTime в status: и считает, сколько времени прошло с последнего запуска. И если это время достаточно велико, а точнее за этот промежуток времени CronJob должен был отработать 100 раз или больше, но у нее этого не получилось:

В этом случае происходит нечто странное: CronJob перестает работать, новые Job’ы больше не создаются. Сообщение об этом приходит в Events, но хранится там недолго. Для восстановления работы приходится удалять CronJob и создавать его заново.

И еще более странное:

Если установлен параметр startingDeadlineSeconds, то поведение немного меняется. 100 пропущенных запусков должны уложиться в количество секунд, указанных в этом параметре. т. е. если в расписании стоит выполняться раз в минуту, а startingDeadlineSeconds меньше 6000 секунд, тогда CronJob будет работать всегда, но в этом случае при политике Allow возможен одновременный запуск множества Job.

И наконец, любопытный side-эффект:

Если установить опцию startingDeadlineSeconds равной нулю, Job’ы вообще перестают создаваться.

Если вы используете опцию startingDeadlineSeconds, указывайте её значение меньше, чем интервал выполнения в расписании, но не ноль.
Применяйте политику Forbid. Например, если было пропущено 5 вызовов и наступило очередное время исполнения, то контроллер не будет 5 раз запускать пропущенные задачи, а создаст только один Job. Это логичное поведение.

Особенность работы CronJob

A cron job creates a job object about once per execution time of its schedule. We say «about» because there are certain circumstances where two jobs might be created, or no job might be created. We attempt to make these rare, but do not completely prevent them. Therefore, jobs should be idempotent.

Вольный перевод на русский:

CronJob создаёт объект Job примерно один раз на каждое время исполнения по расписанию. Мы говорим «примерно», потому что иногда бывают случаи, когда создаются два Job’а одновременно или ни одного. Мы делаем всё, чтобы сделать подобные случаи как можно более редкими, но полностью избежать этого не получается. Следовательно, Job’ы должны быть идемпотентны.

Идемпотентны — должны выполняться на одной и той же среде несколько раз и всегда возвращать одинаковый результат.

В общем, используйте CronJob на свой страх и риск.

В качестве альтернативы CronJob можно использовать под, в котором запущен самый обычный crond. Без выкрутасов. Старый добрый cron работает без проблем, и мы всегда знаем, что задачи будут выполнены один раз. Надо только побеспокоиться, чтобы внутри пода с кроном не выполнялись одновременно несколько задач.

Изучить продвинутые абстракции и попрактиковаться в работе с Kubernetes можно с помощью видеокурса Kubernetes База. В октябре 2020 мы обновили курс, подробности здесь.

Автор статьи: Сергей Бондарев — практикующий архитектор Southbridge, Certified Kubernetes Administrator, один из разработчиков kubespray с правами на принятие pull request.

Источник

Что такое концепция Jobs To Be Done и для чего она используется

Любой продукт выполняет работу. Можно нанять даже чашку кофе, шоколадку и молочный коктейль! Не верите? Рассказываем о концепции JTBD.

Что такое Jobs To Be Done?

Jobs To Be Done — это необычный подход к проектированию продукта.

Читайте также:  Что значит флеболиты малого таза

Название концепции переводится так: «Работа, которая должна быть выполнена». JTBD помогает создавать только те продукты, которые нужны пользователю и отвечают его потребностям, а следовательно, востребованы.

Пишет про управление в Skillbox. Работала координатором проектов в Русском музее, писала для блога агентства
CRM-маркетинга Out of Cloud.

А при чём тут работа?

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

Клиент «нанимает» продукт, чтобы с его помощью закрыть свои потребности. Например, Instagram одни используют, чтобы делиться фотографиями с друзьями, а другие — для бизнеса, чтобы продвигать товары и услуги.

А можно подробнее пояснить?

Конечно. В JTBD важно понять, зачем и при каких обстоятельствах клиент покупает продукт.

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

С кофе понятно, а если мой продукт сложнее?

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

А как я узнаю, кто пользователи моего продукта?

В JTBD важно определить работу продукта, то есть для чего пользователи захотят его использовать, а не кто они такие.

Поэтому вместо User Story (пользовательской истории) или метода персон, привычных при создании продукта, в JTBD обычно применяют Job Story, или историю работы. Она помогает описать ситуации, в которых у людей появляются потребности, — итогом становится «наём» на работу того или иного продукта.

Как понять, какую работу может выполнять продукт?

Для этого нужно собрать информацию о пользователях и ответить на вопрос, зачем клиент «нанимает» или собирается «нанять» ваш продукт. То есть понять, какой продукт он использовал раньше, что пошло не так и почему он захотел поменять или найти новый продукт. А также что получилось в результате и что есть сейчас.

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

А что будет, если я ошибусь?

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

А как тогда не ошибиться?

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

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

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

А в JTBD нужно сегментировать пользователей?

Нужно, но только не по индивидуальным характеристикам, а по их потребностям.

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

С пользователями в целом понятно. А что насчёт конкурентов?

Согласно JTBD, конкуренты — это не не всегда те, кто создаёт похожий продукт или услугу. Иногда реальные конкуренты — те, которые на первый взгляд совсем не связаны с вашим продуктом. Чтобы определить ваших конкурентов, найдите ответ на вопрос: «Кто ещё выполняет ту же работу?»

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

Звучит просто. Наверное, в концепции есть и свои нюансы?

Да, это так. Для начала важно знать, что внутри концепции Jobs To Be Done существуют два подхода. В них по-разному понимают работу продукта.

Первый — Jobs-as-Progress, его используют Клейтон Кристенсен и Алан Клемент. С их точки зрения, работа, которую выполняет продукт, должна менять жизнь пользователя к лучшему.

Второй подход — Jobs-as-Activities, его поддерживает Тони Ульвик. В этой версии работа продукта — это набор задач, которые хочет решить пользователь. Их можно описывать через процесс и результат.

Я хочу глубже разобраться в концепции. Как это сделать?

Лучше разобраться в концепции JTBD помогут эти материалы:

Кроме того, кроме теории можно посмотреть кейсы компаний, которые используют этот подход, например, Intercom, Wrike, Useful.

Источник

Сказочный портал