Pull to refresh

Comments 96

Вопрос на билет:
Кто-нибудь из выступающих на конференции пользуется своим продуктом (badoo)?
Кому помог?

Задаю такой вопрос т.к. сам пробовал его лет 10 назад, когда проект начинался. На то время было удобно. Год назад решил снова посмотреть, после того, как увидел публикации здесь на хабре в блоге компании. Пользоваться стало крайне неудобно.
UFO just landed and posted this here
выступающих немного — малая выборка — но несколько разработчиков нашли себе жен на badoo. что именно неудобно, напишите, интересно.
UFO just landed and posted this here
Я так же как и автор вопроса, пользовался приложением в самом начале.
И так же как автор, после поста на хабр, решил запустить badoo.
Что первое оттолкнуло, это множество монетизации, как уже заметили.
После захода спустя годы, мне зачем то показывается табличка для оценки сервиса «Нравится Badoo?»
Как он мне может нравиться, если я только зашел? Ну это так, что первое бросилось в глаза.
Убрав табличку, вижу какую то девушку. Мне она на данный момент не интересна, но занимает все рабочее поле.
Висят циферки, что я кому то нравлюсь.
Хочешь что то глянуть и на тебе, мозаика. Нет, я люблю мозаику, но тут она мне явно не интересна.
Тыкаешь на мозаику, думаешь — сейчас посмотрим кто там беспокоит. Ан нет, заплатите деньгу.
Ну собственно на этом я закрыл проект и больше не возвращался.

Раньше (лет 10 назад) было как то по другому и направление проекта было другое.
Насколько я помню, знакомство в Х радиусе. Сейчас даже не знаю, есть эта функция или нет, но искать не стал.

P.S.
Еще тыкнул пункт — двойники. Алгоритм конечно хромает жестко.
Я далеко не азиат (глаза большие=) ) и на том фото мне лет 20-25, а находит китайцев/малазийцев которым лет 50.

Вопрос Александру Гутникову:


Скажите пожалуйста, как у вас сделана локализация для статики (JS/CSS)? Используете ли вы готовые решения вроде webpack и модулей для локализации, или у вас какие-то свои решения?


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


Как сделана сборка статики? Кешируете ли вы промежуточные результаты? И как это всё работает на development-окружении, особенно что касается разработки со стороны backend? Им нужно запускать, грубо говоря, gulp dev каждому, или оно само запускается?

Очень интересный вопрос! Подписываюсь.
Юрий, спасибо за вопросы.

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

Для сжатия используем UglifyJS, для сборки большей части статики мы используем webpack. Всем кому нужно работать над js/css — запускают его локально, тем же кто работает только с серверной частью — по умолчанию отдается собранная актуальная статика из мастера — им ничего запускать не нужно.
Тогда еще маленький вопрос: если по умолчанию отдается статика из мастера, то как разрабатываются новые фичи на бэкенде? Т.е. бэкенд сначала разрабатывает отдельно апи, а вы потом его просто используете? Возникает ли необходимость дебажить интеграцию JavaScript-части вместе с бекенд-разработчиками? Как это происходит?
Юра, кажется из-под твоего аккаунта пишет кто-то другой :)
У нас все достаточно гибко, любой разработчик может настроить для себя проксирование статики из:
1) мастера ( по дефолту )
2) из шота ( про шоты можно почитать вот в этой статье например habrahabr.ru/company/badoo/blog/317700 )
3) с девела другого разработчика

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

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

Насколько широко вы используете Go, где и для чего, почему ровно столько и не больше/меньше и планируете ли увеличивать или уменьшать его использование в своих проектах?


Судя по всему, он бы отлично лег на задачи A-Team, например.


Как жизнь с Protobuf? Не слишком ли много времени на возню с ним уходит при отладке/тестировании/и т.д.?

Спасибо за вопрос.

Вы правы в A-Team действительно некоторые задачи решаются на Go, в основном это узкоспециализированые сервисы, которые решают конкретную задачу.
Сильно уменьшать или увеличивать его долю не планируем. Мы стараемся использовать те инструменты которые лучше подходят для задачи не разводя при этом зоопарка.

Ну в вашем стеке уже есть как минимум PHP, Java/Scala, C, Go. То есть его использование не добавляет зоопарка.


А "узкоспециализированые" это какие? Ну то есть какие задачи для Го, а какие – нет, с вашей точки зрения?

Go мы часто используем для задач, которые плохо ложатся на php и хорошо — на Go (concurrency ж киллер фича).
Если при этом же нет жестких требований по контролю памяти или cpu — тогда Go в самый раз.

Например — у нас есть сервис, который шедулит задачи в нашем скриптовом облаке. Сервис (с прекрасным названием LSD) доставки логов между машинами (a-la facebook scribe).

Еще — хороший кейс, имхо, для Go — когда нужна интеграция данных из кучи источников. Например — для распределенного кеша, нужны данные о пользователе, его контактах, последних онлайн действиях и координатах.
Сходить в кучу источников, объединить данные в правильном выходном формате — очень удобно и быстро делается на Go.
Стесняюсь спросить: а зачем писать свой сервис для доставки логов между машинами, если имеются уже готовые решения, например fluentd. Или это политика компании — использовать самописные решения?
Спасибо.
Ну как всегда это есть комбинация специфических требований (которые проистекают из-за горы уже написанного кода и внедренных систем), усталости от существующих инструментов (т.е. «блин, теперь приходится еще и это поддерживать самим, ибо оно у нас постоянно ломается»), и — не стану скрывать — некоторого желания сделать под себя «как нам надо» (ну not invented here).

Сначала был facebook scribe, который просочился повсюду и захватил умы. Он ломался, мы его слегка патчили, но терпели. Потом fb забросил его (да и код не отличался поддерживаемостью anyway).
После какого-то из раундов борьбы — мы сказали — да ну его, давайте заменим.

Смотрели fluentd — было опасение, что не потянет стриминг (гигабит с тачки например), да и у нас далеко не везде json — надо дофига переделывать. (Могу слегка наврать, было лет 5 назад).

Flume — не хочется ставить jvm на все машины.
rsyslog — олдскульно, юзаем в некоторых задачах, не очень понравился по полу-техническим, полу-субьективным причинам.

Все-таки пожалуй здесь две основных причины
1. Есть уже готовые работающие вещи, которые заточены некоторым образом (в нашем случае — под scribe, текстовые логи, доставку в виде файликов в одном каталоге и т.п.).
2. Есть чемпион, который говорит — чуваки, я счас все запилю классно и так, что этот проект реально будет завершен не через год (3 миллиона строк кода на пхп, 3000+ серверов, 150+ server-side девелоперов). А будет через месяца два. И это происходит как раз, когда мы понимаем — что уже наболело и надо делать.

p.s. мы юзаем на самом деле кучу разных вещей для разного рода «стриминга»: rsyslog тот же, logstash-forwarder был, scribe был. kafka есть.

p.s.2. github.com/badoo/lsd — не самый свежий код, правда.
Есть чемпион, который говорит — чуваки, я счас все запилю классно и так, что этот проект реально будет завершен не через год (3 миллиона строк кода на пхп, 3000+ серверов, 150+ server-side девелоперов). А будет через месяца два.

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

И правильно стесняетесь. Такие вопросы задавать стыдно.
Насчет protobuf — в чем сложность с ним при отладке?
Если речь про «он же бинарный» — у нас есть простые инструменты превращения бинарки в json. Например — даже конфиги сервисов описываются в .proto, но фактически пишутся/генерируются и хранятся в json (слегка пропатченном, с комментами и tail comma).
Вопрос yagolub, Какой подход вы используете для версионирования API, насколько легко/сложно поддерживать несколько версий?
Спасибо за вопрос!

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

Вопрос Алексею Рыбаку. Зачем, и каково это — после 12 лет в одной компании, которая все эти 12 лет делает по-сути один сервис, сменить место работы :)
Зачем: Badoo перевёл позицию главы разработки в Лондон. Несколько лет мы проводили достаточно серьёзную «перебалансировку» инженерных групп, лондонский офис сильно вырос, так что это абсолютно разумно. По личным причинам я не захотел переезжать. Каково: уточните вопрос. Весело, работы — море. Но вы не правы, что Badoo делает один сервис. Badoo начинался как соц-сеть, у меня на Badoo, например, до сих пор сотни фотографий с тех времён. Были фото-альбомы, ленты активности друзей, комментарии, что-то наподобии «групп» — мы выли воодушевлены тем, что тогда называлось web 2.0 и экспериментрировали очень много, даже сделали однажды аналог чат-рулетки (и быстро закрыли, потому что там началось адище). Совершенно другой сервис, но мы его делали на той же архитектуре, ничего не меняли, что лишний раз подтверждает, что мы изначально выбрали удачные подходы в разработке. Затем большая часть аудитории стала мобильной, Badoo стал mobile-first компанией. Затем Badoo стал превращаться в платформу, на базе которой растет уже несколько продуктов. Ну и для меня лично этот опыт был как три-четыре разные работы — совершенно разный и очень полезный опыт.
В технологиях Badoo крут, спору нет, и это не сарказм.
Но мне интересно узнать вот что — где реализоваться человеку, который так долго выстраивал разработку в отдельно взятой компании со специфическим продуктом и технологическим стеком? Ещё и не покидая России…
Не поверю что уже пенсия, огород и рыбалка? :)

Стек почти не имеет значения.

UFO just landed and posted this here

banuchka смотрели ли на какие-нибудь системы управления контейнерами типа Kubernetes? Есть ли планы по внедрению или какие-то аргументы почему оно вам не подходит?

Привет,
лучше всего посмотреть вот тут: habrahabr.ru/company/yamoney/blog/339350, youtu.be/pp9nTXa2DTQ. Буквально менее месяца назад я рассказывал в том числе про это.

Если отвечать тут, не переходя по ссылкам: смотрели на все, на которые стоило смотреть, в том числе K8S, Mesos, Nomad. Конкретных планов по внедрению не было и нет. Они могут появиться, если внезапно в какой-то день мы на нашем тестовом стенде поймем, что «вот она серебряная пуля».

Ну серебрянной пули не существует.
По нашему опыту, тот же настроенный k8s с шаблонами всех конфигов в скелете сервиса позволяет достаточно легко и быстро распиливать монолит на сервисы и деплоить их в "облако". Проблем по стабилизации, конечно, дофига, но разработчикам сервисов удобно. 30 секунд и твой сервис работает. И никакой беготни по админам/девопсам/еще кому-то.

Спасибо, я слышал, что k8s хорош. Девопсов у нас нет, а разработчики до нас, скорее всего, не добегут.
Процесс деплоя сервиса на prod окружение несколько сложнее, чем просто «разработчик захотел», а раз это так, то как вывод – мы не упираемся в скорость поднятия в облаке. Облака-то тоже нет :)
Вопрос Антону Турецкому:
Используете ли docker в продакшн? И, если да:
— используете ли вы data-only контейнеры для доставки кода или упаковываете код сразу в контейнер (например, с php)?
— какой оркестратор используете и почему?
— сколько нод в docker-кластере, в скольки датацентрах и на скольки континентах они расположены?
— чем мониторите docker-контейнеры (cAdvisor, свои решения, что-то еще?)
— перечислите, какие docker-контейнеры используете. Например, у меня в стеке разворачиваются:
  1. data-only контейнер с кодом
  2. nginx
  3. php-fpm
  4. redis
  5. memcached
  6. websocket
  7. sdcv (консольный словарь)
  8. staticus (https://github.com/KIVagant/staticus)
  9. node-exporter
  10. cadvisor

Заранее спасибо за ответы!
Привет!
Docker в production используем, про последние актуальные цифры(что где и сколько) вы можете посмотреть в моем докладе на мероприятии habrahabr.ru/company/yamoney/blog/339350. Ссылка на видео – youtu.be/pp9nTXa2DTQ.

— используете ли вы data-only контейнеры для доставки кода или упаковываете код сразу в контейнер (например, с php)?

Контейнеры с php кодом приложения(читай Badoo) мы как таковые не используем. Причина тому – наличие отдельных(выделенных) машин, на которых кроме nginx+php-fpm, а также кода, более ничего нет. Применение контейнеров там, по нашему мнению, не оправдано и не нужно.
Однако у нас есть некоторые сервисы, которым нужно:
  • php
  • наличие кода

Для таких случаев делаем так:
  • — на машине, на которой предположительно планируется запуск сервиса, который требует вышеописанное, создается «data-»/«mapping-» контейнер, который содержит в себе все необходимые маунты. Обычно это php, code, которые в свою очередь линкуются на директории хост системы.
  • — управление версиями кода и php выполняется стандартными инструментами НЕ для контейнеров
  • — запускается тот самый сервис, используя инструкцию "--volumes-from mapping_container"
  • — актуальность маунтов «вспомогательного» контейнера, конечно мониторится
  • Еще бывает такое, что сервис должен где-то хранить statefull данные – для этого мы применяем named volumes, что удобно и, скорее всего, очевидно.


— какой оркестратор используете и почему?

На данный момент самописный свой. Ответ на этот вопрос скрывается также в ссылках на последнее видео.

— сколько нод в docker-кластере, в скольки датацентрах и на скольки континентах они расположены?

Нод:
# mco find hosts -F docker_package=true | wc -l
687

Дата центры:
4 или 6(смотря как считать); 2 континента
— чем мониторите docker-контейнеры (cAdvisor, свои решения, что-то еще?)

Стабильный и основной инструмент:
Если кратко, то у нас на хостах запущен «мониторинговый» контейнер, который:
  • — читает эвенты от демона docker
  • — читает системные метрики
  • — отправляет это в zabbix/graphite

Если чуть подробнее, то советую посмотреть на вот эти 2 выступления, где я касался данного вопроса: tech.badoo.com/ru/presentation/191/docker-v-badoo и tech.badoo.com/ru/presentation/137/docker-v-rabote-vzglyad-na
Параллельный, находящийся в разработке инструмент:
  • — prometheus
  • — grafana
  • — telegraf

Telegraf запускается на хосте, собирает host & dockerd related информацию и открывает порт, на котором готов отдавать статистику для и в формате Prometheus. Prometheus берет информацию из Consul по маске наличия сервиса docker на хосте. Далее в grafana рисуем картинки + тестируем алертинг от Prometheus.
На данный момент это прототип, хоть лично мне он очень нравится :)
— перечислите, какие docker-контейнеры используете. Например, у меня в стеке разворачиваются:

Это не будет иметь никакого смысла, т.к. 90% названий вам, скорее всего, ничего не скажут. Мы не используем контейнеры с dockerhub(за редчайшим исключением) и собираем их самостоятельно, даже если это просто nginx || redis – это будет собранный нами контейнер на базе SLES.
Супер, спасибо за расширенный ответ и за ссылки, пойду изучать!

В дополнение к Антону отвечу почему PHP код мы не выкладываем контейнерами. Причины довольно простые: мы хотим выкладываться часто (сейчас это 2 раза в день на продакшен и, по статистике, каждые минут 10 на стейджинг), при этом PHP приложение представляет из себя монолит, один код которого занимает ~200Mb, завендорено ещё столько же (можно уменьшить елси почистить тесты и много чего ещё в них). При раскладке на продакшен всё это нужно доставить на сотни серверов, потому нам приходится постоянно изменять собственную систему деплоя. Более подробно об этом можно посмотреть в докладе Юры youROCK Насретдинова на Youtube.

Спасибо за информацию и ссылку на доклад!
В моем случае код php и vendor (без тестов), упакованные в docker-контейнер занимают 358Mb, пока решили выкатывать этот контейнер отдельно (как data-only) не обновляя без надобности остальные.
Хотя docker-капитан Bret Fisher советовал мне добавлять код в контейнер с php-fpm (который сам весит ~600Mb) — мол, это «лучшие практики»…

В принципе, благодаря слоям, не требуется каждый раз скачивать и записывать эти самые 600 Мб. То есть можно сделать базовый образ из текущего состояния репозитория (условно ветки master) и потом при сборке нового контейнера делать git pull. Но со временем всё равно разница будет накапливаться и нужно будет базовый контейнер пересоздавать. Если при сборке нужно ещё что-то генерировать, то такой способ, конечно, уже будет работать плохо. Собственно, это является одной из причин, почему ИМХО для деплоя PHP тот же rsync в 2 директории подходит намного лучше.

Доставку вообще никто не мешает делать не через docker distribution!

Речь скорее не про доставку, а про то, что на машину всё равно будет записывать намного большее количество данных, чем по факту было изменений. Если для компилируемых языков диффы между бинарями делать никто не будет, то вот для того же PHP/Python/Ruby можно относительно легко сделать деплой только изменений.

можно относительно легко сделать
это в теории, а на деле ты сам все прекрасно помнишь!

А что, по-моему MDK вполне нормально зашел :). Были конечно небольшие косяки, но это не моя вина. Весь код со всех машин должен был по ошибке стереться под Рождество, а не ночью в рабочий день.

Юра, мы скучаем!

Вопрос к Ярославу Голубу


В одной конторе было серверное приложение с толстыми клиентами для разных устройсв.


Клиенты умели работать с файликами в бинарном формате и обмениваться ими с сервером.


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


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


Оказалось, что если передать клиенту файлик с фичей, он падает.


А падать этому старому проверенному клиенту нельзя, потому что его использует ешё одна крупная контора.


Костыль и велосипед
Разработчики, забив большой болт на спецификацию формата и внешний вид кода, реализуют всё так, что старый клиент считает новый формат комментариями.


И вот этот набор костылей релизят.


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


Нужно делать как все
Если наша контора будет нормально работать с форматом, можно расширить клиентуру, но забить на старые не обновлённые устройства нельзя.


Вернее можно, но только когда истечёт срок поддержки.


Есть идея отдавать сервером файл в правильном формате в зависимости от версии клиента, но на сервере конверсию форматов придётся реализовать с нуля.


Как вы обрабатываете такие ситуации?

Спасибо за вопрос!

Если я правильно понял — то суть проблемы в том, что у вас есть два несовместимых протокола, старый и новый, причем последний ломает старые клиенты? Если это так, то мы в Badoo с этим справляемся так: избегаем такого.
Либо изменения протокола должны быть такими, чтобы старые клиенты продолжали работать как ни в чем не бывало, либо старые клиенты о новом протоколе ничего знать не должны. Решается это в основном тем, что сервер новым клиентам отвечает по новому, более лучшему протоколу, а старым — по старому.

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

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


И вот, мы запилили в клиент поддержку двух форматов — код получился совсем жуткий, но это было лучше, чем ничего. В этой новой двухформатной версии клиента была одна фишка — он сохранял файлы в той версии формата, в которой он их считал. Так как в новом, хорошем формате у нас пока ничего не было — всё и работало по старому.


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


Следующим шагом мы убрали поддержку старого формата (в котором фича сделана комментариями), и зарефакторили код. Теперь у нас остались старые клиенты, которые работали с новым форматом нормально и новые клиенты, которые не умели работать со старым форматом, которого в природе уже не осталось.


Такой вот хитрый план.

Вопрос товарищу demi_urg:


Как вы относитесь к новым SQL-базам с автоматическим шардингом? Например CockroachDB или TiDB (https://github.com/pingcap/tidb)? Пробовали ли вы их использовать для чего-нибудь? Как вы решаете проблему в текущих условиях, когда нужно одновременно закоммитить что-то на двух и более серверах? Например когда нужно послать подарок пользователю (нужно атомарно уменьшить баланс пользователя и добавить подарок другому, который может жить на другом шарде).


Как вы шардируете мемкеш? Если про схему хранения данных в MySQL и про фотографии вы рассказывали на конференциях, то про шардирование кеша я такого не припомню, хотя это тоже интересно, как мне кажется.


Ну и последний вопрос — как вы относитесь к ClickHouse, прижился ли он у вас и как вы шардируете данные в нём, если прижился?

Юрий, спасибо за вопрос.

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

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

С мемкешом у нас все просто. У нас стоит N серверов ключи по которым раскидываются равномерно по определенному хешу. В случае выпадения одного из мемкешей мы просто теряем 1/N кеша и получаем небольшой прирост запросов на базы, что вообщем то не критично.

ClickHouse у нас используется для обсчета статистики. Подробнее про него я попрошу ответить ребят из BI.
В настоящий момент мы проводим эксперименты по применению ClickHouse к нашей системе потоковой агрегации событий. В общем и целом, нам удалось найти схему хранения, которая удовлетворяет нашим задачам. Осталось дело за одним нюансом — мы ждём кастомного партицирования. Нужно оно нам из соображений партицирования — мы не хотим хранить месяц данных (на самом деле — два, т.к. удалять можно только по месяцу), т.к. нам нужно максимум 1-2 дня.
Когда система войдёт в production использование, мы выпустим статью на эту тему.
Вопрос Александру Рыбаку:
Я от сервер сайд разработчиков все время слышу что в хайлоаде не бывает офсетов, нельзя посчитать общее количесво объектов у пользователя, запрашивать данные большими кусками и ещё куча других орграничений. Есть ли какой-то подход чтобы обойти все это и дать фронтэнду и мобильным разработчикам удобное апи? Вы сталкивались с такими проблемами? Как вы их решаете?
Перепутал. Извините.

Вам интересно услышать ответ кого-нибудь, кроме Алексея Рыбакова? Всю тему я, конечно не подниму, но про оффсеты, подсчёт количества объектов, большие куски данных и некоторые решения с АПИ могу сказать.

Конечно интересно!

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


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


Единственное, что можно сделать — это кешировать количество элементов в некоторых фиксированных выборках.


Оффсеты
Проблема с оффсетами это по сути та же самая проблема.
Для того, чтобы пропустить первые N строк, которые попадают в выборку — нужно смотреть каждую строку в таблице и, если она попадает в выборку, увеличивать счётчик на еденицу, пока мы не наберём N строк. Если мы хотим с помощью оффсета попасть на последнюю страницу выборки — это по затратам равносильно подсчёту всех её элементов.


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


Чтобы дать пользователю возможность перемещаться между страницами выборки и не сжечь при этом сервера, нужно строить интерфейс по принципу — "перейти на следующую страницу", или "перепрыгнуть через 5 страниц" или "перейти на последнюю страницу". Это базу не нагружает, потому, что оффсет для этого можно не использовать, или использовать ограниченно.


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


Большие выборки
Большие выборки лучше не делать, потому что это создаёт в БД длительную транзакцию на чтение, а это делает СУБД больно.


Воркараунд тут — вычитка выборки постранично и последовательно, так же как и в случае с постраничной навигацией на UI.


API
Тут всё точно так же, как в предыдущих пунктах — нельзя отдавать в апи страницы по номеру, если необходимо отдать через апи всю выборку, нужно отдавать сначала первую страницу, потом вторую и так до последней.


Вот как-то так выглядит краткая выжимка из того, что мне известно по теме.

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

Сколько постов и фоток у определённого пользователя это как раз и есть одна из тех заранее заданных выборок, которые можно кешировать :), не всё так плохо


посмотреть что он делал в заданную дату и т.п.

Тут может помочь индекс с датой первым полем :) и, возможно, секционирование таблиц по датам.

На собеседование к вам в компанию на должность front-end разработчика может попасться такой вопрос.
Реализовать функцию, которая возвращает результаты
foo(1)(2)(3) -> 6
foo(1)(2)(3)(4) -> 10
foo(-1)(2)(3)(4)(7) -> 15
foo(1)(2)(3)...(n) вернет результатом сумму 1+2+3...+n
Как вы сами реализуете решение? Сколько времени это займет у вас?

Это не я на собес ходила, но что-то этот вопрос так и запал в память, а здесь такой шанс.
Добрый вечер! Задачу можно решить как-то так:

function foo(value) {
	var acc = value;
	function addNext(next) {
		acc += next;
		return addNext;
	}
	addNext.valueOf = function() {
		return acc;
	}
	return addNext;
}


Теперь вы должны прислать нам вопрос на замену этому.

[irony] но это нерабочее решение: console.log(foo(1)(2)(3)) // function

Да, спасибо за замечание, все верно говорите.

Насколько я помню там речь шла не про вывод в консоль, а про выражения вида:

foo(1)(2)(3) == 6
foo(1)(2)(3) + 4 == 10
foo(1)(2)(3) > 5

и т д

Да это понятно, я уж просто так :] и вот вам задача на замену, хоть и бредовая


for (const num of 0..VI) {
   console.log(num); // 1, 2, 3, 4, 5, 6
}
Спасибо. Только меня не много смутило

Для alert

Хотя я не придумала ни чего лучше. Получилось только не много улучшить.
function foo(value) {
	var acc = value;
	function addNext(next) {
		acc += next;
		return addNext;
	}
	addNext.toString = addNext.valueOf = function() {
		return acc;
	}
	return addNext;
}

Теперь alert возвращает число, но typeof все равно function.
Александр Гутников, alxgutnikov,

Как отслеживаете ошибки яваскрипта на prod?
Мы используем подход, похожий на тот что используется в raven.js от sentry. Если по-простому, то любая возникающая ошибка в итоге попадает в try {} catch() {} на уровнях выше, после чего со своим стектрейсом и разной дополнительной информацией отправляется на сервер.

На сервере ошибки агрегируются по разным признакам: номеру билда, браузеру, сообщению и т д. Так же можно посмотреть когда и как часто эта ошибка вопроизводилась до этого
Вопрос demi_urg:
  1. Как у вас происходит процесс обновления схемы баз данных?
  2. Как накатываете схемы на кластер баз данных?
  3. Как вы решаете проблемы выполнения долгих alter table и лока таблиц при них
  4. Если у вас сценарии деплоя для: добавления колонки в бд, удаления колонки в бд, изменения колонки в бд?

Спасибо
Спасибо за вопрос

Давайте я попытаюсь ответить сразу на все вопросы.

Любой ALTER делается в несколько этапов:
1 подготавливается код (если надо)
2 делается ALTER
3 удаляется код (если надо)

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

Например добавление таблицы или колонки обычно не требует пункта 1, удаление — не требует пункта 3.
В основном все изменения делаются простым альтером в оффпик. Там, где альтер долгий делается через pt-online-schema-change
Расскажите про воркфлоу. Разработчики пишут миграции или же как-то по-другому готовят свои обновления схем, и высылают вам?
Разработчики ставят тикеты на альтер и следят когда они будут выполнены. Как я сказал есть в общем случае 3 этапа. Задача разработчика не допустить их пересечение.
Вопрос Антону Турецкому.
Зачем вам шапка и как она помогает?
Заранее спасибо.
Привет.
Зачем? – Для привлечения внимания.
Как она помогает? – Раз появился такой вопрос, то внимание она привлекает! Значит работает!
Фишеру.

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

Как выруливать?

Надо понять про "руководство не реагирует", обычно за этим стоят проблемы коммуникации, разговор на разных языках, забивания друг на друга, всякиое горделивое типа "если надо обьяснять, то не надо обьяснять" и прочее… надо обьяснять! Продакшн-качество, стабильность — бизнес-метрика, если вдруг что-то не получает должного внимания — приучать. В любом случае нужно по-партизански или открыто сделать команду, которая будет фиксить долг. Лучше открыто, по-партизански можно только очень ненадолго и в большой конторе (минимально зааффектит бизнес).

Ну а если никак — смириться и терпеть или найти место получше, это уж как кто привык.

Вопросы Алексею Рыбаку.

Первый вопрос про ревью и мотивацию. Смотрел в записи ваш доклад о performance review с одного из митапов в Баду, было очень интересно. Насколько я понял, материальные поощрения после review довольно существенные, потому что это хороший инструмент мотивации. Как это сказывается на основной (обязательной) части зарплаты? Пример для наглядности — в одной компании ценят стабильность, и ежемесечная зарплата программиста 180 К (ниже этого он не получит), а ежеквартальные премии могут составлять например 20 К за очень хорошее review — условно говоря на пятёрку по пятибальной шкале, а если сотрудник хорошо работал, но после нормировки оказался ниже середины, то премию он не получит вообще. В другой компании с точно таким же зарплатным фондом обязательная часть зарплаты — это 120 К, но если он постарается, то в конце квартала у него будет премия 200 К (это плюс к обязательной части). Как следует из расчётов, у компании одинаковый зарплатный фонд (оба сотрудника получат по 560 К за три месяца работы, при высшей оценке на ревью). Соответственно в одной компании минус в том, что премия после review слабо мотивирует, а минус второй компании, что хороший, но невыдающийся сотрудник чаще всего будет получать 120 К, что будет его демотивировать так же, как высокая премия мотивирует лучших сотрудников. В каких пределах находится премиальный процент от обязательной части зарплаты, в каких границах находится основная базовая зарплата относительно рыночной зарплаты, и как решаются проблемы демотивации для тех, кто останется недоволен премией?

Второй вопрос частично связан с первым, но больше про HR-стратегию и привлечение новых сотрудников. В Бадушных официальных зарплатных вилках, которые можно встретить на сайтах по поиску работы (и даже на хабре), указываются верхние границы, существенно превышающие среднерыночтные. Но вместе с информацией из доклада про ревью складывается впечатление, что обязательная зарплатная часть существенно ниже нижней границы вилки, а верхняя граница вилки актуальна для очень маленького процента сотрудников и далеко не каждый месяц, и только при условии максимальной оценки на ревью. Часто встречал мнение (как HR-персонала, так и менежеров и разработчиков), что на самом деле для большинства сотрудников вилка по факту меньше, с учётом результатов ревью. Многие относятся с недоверием к официальной вилке. Так вот вопрос — насколько она верна для существующих сотрудников, насколько это честная цифра?

Третий вопрос про тимлидов. Не секрет, что в разных компаниях очень сильно различаются обязанности тимлидов, а так же различается количество уровней IT-шной иерархии управления. Иногда над тим-лидом уже CEO, а иногда ещё три уровня технических управленцев. Иногда тимлиды програмирут 90% времени и по сути больше похожи на ведущих разработчиков, а иногда совсем не программируют, а управляют командой из 15-20 человек. Например, существует мнение, что при команде в 6-8 человек на программирование времени не остаётся. В некоторых компаниях тимлиды отвечают за продуктовую часть, у них свои бизнесовые KPI, а в других ответственность ограничена исключительно качеством кода команды. В некоторых — у тимлида в подчинении кроссфункциональная команда, состоящая как из серверсайд разработчиков, так и клиентсайд разработчиков, тестеровщиков, админов, техписателей и так далее, в то время как в других компаниях у серверсайд тимлиодов в подчинении исключительно серверсайд разработчики. Расскажите, пожалуйста, какой процент времени тимлиды в Баду тратят на непосредтсвенное программирование, как этот процент времени зависит от размера команды, какие у них KPI и входят ли в них бизнесовые и продуктовые показатели, могут ли быть в одной команде и серверсайд и клиентсайд разработчики в подчинении у одномго тимлида, какого размера команды, и какой дальнейший путь развития тимлидов в Баду, кто ими руководит и за что он отвечает?

Отвечать буду частями. (1) влияет ли и как бонусная часть. Да, влияет, обычно практика такая: база в рынке, а с бонусами получится выше ожидаемой — но есть масса ньюансов, конечно. Бонус — десятки процентов. Недовольство = минимальная премия = нет полного соответствия ожиданиям, тут очень важно, чтобы руководитель это подробно разьяснял, и ревью воспитывает и эту культуру тоже. При трудоустройстве можно всегда спросить, какой средний бонус был в этой группе — и вам скажут.

(2) Фактически вы спрашиваете: сколько получают сотрудники. По понятным причинам я не могу это разглашать, но вот утверждение о "существенно низкой базе" — неверное, выше обьяснял, почему, это вообще антипаттерн и я был бы вам крайне признателен, если вы скажете место в докладе, в котором у слушателя по-вашему создается такое впечатление, я обязательно его исправлю.

(3) в разных командах по-разному. Подчинение обычно такое: Тим-лид/менеджер — директор — глава разработки с вариациями. KPI — в зависимости от команды, но главный: сделать что обещал, в срок. Формулы доли программирования и размера нет, поскольку может быть разный профиль, разное число стейкхолдеров и соотвественное разное время на общение/синхронизации. Обычно в командах 3-4 человека еще 50% можно программить, но 7-8 уже почти нереально. Но если человек стремится совмещать — это можно делать и в больших командах, просто в ущерб другим активностям (я бы не рекомендовал, но на вкус и цвет).

Спасибо большое за ответы, Алексей.
если вы скажете место в докладе, в котором у слушателя по-вашему создается такое впечатление

Это не из доклада, это — из общения с различными людьми. Но я понял, что это было ошибочное мнение. В докладе этот момент не был освещён.
Обычно в командах 3-4 человека еще 50% можно программить, но 7-8 уже почти нереально. Но если человек стремится совмещать — это можно делать и в больших командах, просто в ущерб другим активностям (я бы не рекомендовал, но на вкус и цвет).

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

Знаю, что в Badoo используется Zabbix для мониторинга инфраструктуры, возможно ли его применение в современной методологии разработки и развёртывания приложений(микросервисная архитектура, Continuous Delivery , контейнеры)? Нет ли в планах компании интеграции Zabbix и Consul?
Привет!

Спасибо за вопрос и пищу для размышлений – возможно, станет темой для доклада на следующем митапе :)

Применение Zabbix возможно в современном стеке технологий.

Теперь подробнее и по порядку.

  • Мы используем Заббикс не только для инфраструктуры: серверы, диски, сеть, память, проц; но и для приложений: работоспособность сервисов, внутренние метрики [время ответа, cpu usage per instance, свежесть данных в них, наличие бэкапов [для всех или выборочно] сервисов.
  • Сервисы – различные, как опенсорсные, так и внутренние. Например, nginx, php-fpm MySQL, Tarantool. Внутренние, понятное дело, называть не буду, смысла нет.
  • Под каждый сервис – обычно заводится мониторинг с нуля (очень-очень редко берём готовые шаблоны из паблика, да и то – сильно правим их). Во-первых, мы всегда можем и должны ответить на вопрос “что это и зачем”, во-вторых, есть правила, по которым мы всё добавляем более или менее однообразно.
  • “Заббикс ничего не умеет” – у нас очень много кастомных скриптов, которые проверяют всё подряд. Заббикс умеет запускать эти скрипты с разными шаблонными параметрами.
  • Чтобы каждый раз ручками не кликать в интерфейсе – используем API, в основном для заведения хостов, (благо, библиотек полно) и LLD (low level discovery), для заведения айтемов/триггеров.


Как мониторим
Обычно: идём на порт демона и опрашиваем его.
Редко: идём в файловую систему (например, демон пишет дампы каждый час, они важны, надо проверять работоспособность), в случае с контейнерами – тяжелее добраться до файлов (пути не очевидные, либо добраться нужно через docker), но это возможно (и мы так делаем).

Иногда: сходить в базу, населектить значения. Например, очередь в MySQL – SELECT COUNT(*). Или сходить по определённому урлу – nginx status page.

По поводу контейнеров: контейнер для нас (мониторинга) – просто сервис. Точнее, все наши сервисы (или почти все) живут в контейнерах, поэтому нам особой разницы нет, что мы мониторим: сервис, запущенный через systemd, или сервис, который живёт в контейнере. Нам важно то, как мы его мониторим – это обсуждается, как уже говорил, для каждого сервиса отдельно (или дорабатывается в процессе эксплуатации)

Как мы узнаём о том, что и где мониторить?
Написали свою дискаверилку всего-всего, которая умеет добавлять хосты, писать адекватные логи, линковать с нужными шаблонами, класть их в нужные группы и выдавать необходимые права (если используете Zabbix и его внутреннюю дискаверилку хостов – точно натыкались на её непрозрачную работу). Суть работы простая – проверяем «где должно быть», смотрим в заббиксе «где уже есть», недостающие создаём и цепляем к шаблонам, лишние удаляем.
Чаще всего дискаверим (для сервисов) из DNS и PuppetDB (если интересно об этом, тут Антон Турецкий banuchka может прокомментировать откуда Puppet знает про сервисы, да и он вроде уже рассказывал на Хайлоаде).
Отдельно про DNS – повелось давно, чтобы можно было переносить сервисы без изменения каких-либо конфигов: перекинул сервис/контейнер, перекинул dns запись, код пошёл к новому хосту. И мониторинг – обращаемся по DNS имени, не нужно менять ничего в нашей системе. По сути, на один инстанс сервера имеется одна DNS запись.

Далее – два варианта:
  1. цепляем целиком хост (dns алиас) к шаблону
  2. цепляем шаблон с low level discovery к имеющемуся хосту: lld приходит на хост, проверяет, какие сервисы должны быть на хосте и уже мониторит их пачками (таким образом, при переезде сервисов у нас один набор проверок удаляется на одном реальном хосте и появляется на другом, lld же)


Очень редко – бывает, что нужно мониторить работу контейнера, но это укладывается в первый вариант «понять, где нужно проверять работоспособность и прицепить нужный шаблон к нужному хосту».

Схема в первом случае выглядит так:
<шаблон> –> (дискавери работает) –> <хост для сервиса> –> , , …
Схема во втором случае:
<шаблон> –> (дискавери работает) –> <хост, где живут сервисы/контейнеры> –> (low level дискавери работает) –> , , , , …

Выводы
У нас есть своя дискаверилка – прицепить туда Consul не составляет большого труда (нет, сейчас не используем, он у нас в качестве эксперимента и/или используется только для инфраструктурных сервисов)
Контейнеры мониторить можно, разными способами. Но мы мониторим не контейнеры, а сервисы – это важно понимать (ок, если надо контейнеры – мониторим, как описал выше)

Точно знаю, что есть много людей, которые говорят, что «заббикс не предназначен для мониторинга контейнеров!!!11 в моём прометеусе это делается из коробки!!1» (или тулзами, которые умеют взаимодействовать с ним)
В целом – да.
Но если у вас уже есть одна система (как у нас) и она работает давно, и вам не хочется поддерживать несколько систем мониторинга – заббикс можно научить работать с тем, что вам нужно.

Не устану повторять, что Zabbix – это просто платформа, а не готовое решение. Ровно как и Prometheus – вам нужно будет настроить его, прежде чем катить в прод.

P.S. Как-то рассказывал, как мы скрестили заббикс и аппликейшен/бизнес метрики: www.youtube.com/watch?v=QhFpVc_iHKA так что, возможно всё :)
Спасибо за развернутый ответ.
Михаил Scalar, всегда очень больно обижать настоящих добрых клиентов.
Как вы поступаете в этом варианте если антиспам система блокирует добропорядочный аккаунт. Например взломанный, или возможно есть спамеры которые бодаются что их сообщение «выплаты без смс» вообще не спам и друзья хотят их видеть :)
Есть какая то выборочная ручная проверка заблокированных? Или вероятностные оценки системы никогда не ошибаются? Вопрос только в выборе правильной вероятности для блокировки.
Спасибо за вопрос!

Конечно мы стараемся «хороших» пользователей не трогать.
Хотя и не всегда вообще возможно отличить «хорошее» от «плохого».

Но и системы и люди, которые их делают, иногда ошибаются, поэтому у нас есть несколько изолированных систем для «самоконтроля».

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

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

Плюс разные сплит-тесты, ручные проверки и прочий контроль качества.
Ну и помимо блокировки, у нас есть промежуточные «санкции», которые мы используем чтобы убедиться, что перед нами живой человек: можем попросить юзера пройти верификацию по телефону или по фотографии. А для некоторых ботов — это равносильно бану.
И да, вы правы, спамеры часто пишут в поддержку, что они не спамеры и «вы всё врёти», надеясь что это прокатит, и один из аккаунтов случайно разбанят.

Предотвращение взлома аккаунтов — это большая тема, достойная отдельного доклада.
Если вкратце — то мы внимательно следим за логинами пользователя, и если в его логине есть что-то необычное: не то устройство, странная геопозиция, или еще какие либо отклонения от обычного поведения, то мы такому юзеру сразу показываем экран дополнительного подтверждения, по сути второй фактор авторизации, и юзер должен подтвердить, что владеет номером телефона или соц.сетью привязанной ранее.
Вопрос Виталию: выбирать ТимЛида из приличной команды в компании куда поток претендентов не иссякает здорово. Но как это эффективно и предельно ресурсоемко сделать в рядовых компаниях, учитывая, что рынок перегрет и кандидатов, которых можно оперативно вводить в курс дела на одном языке в потоке чуть меньше, чем 0?
2ball, если честно, я не совсем понял вопрос: ваша проблема в том, что нанять не получается людей в команду? Или вопрос в том, как помочь джуниору вырасти в тимлида?
В потоке кандидатов отсутствуют специалисты выше уровня границы Junior / Middle. Исходя из этого время на рост до лида значительно увеличивается. Вопрос, по сути, в том, чтобы сделать это быстрее, чем в обычном темпе.
Как всегда, мы упираемся в «Быстро, качественно, недорого — выбирайте любые два пункта».

Если база «качества» (навыков, необходимых для тимлида) слабая, а нужно «быстро», то, выходит, придётся тратить значительно больше времени на обучение. Иных вариантов, к сожалению, просто нет.

Итого: если выбранный кандидат есть, и нужно помочь ему вырасти, то берём стандартный процесс развития и тратим на него значительно больше времени: больше коучинга, больше проектов, больше присмотра. Не хочу спойлерить мой доклад, подробнее уже в нём отвечу.
Вопрос на билет — Илье.
Будут ли когда нибудь открыты ваши инструменты автоматизации и кастомизации для Zabbix?
За Telegramm оповещения отдельное спасибо.
Привет! К сожалению, билеты уже всё, но на вопрос, конечно, отвечу.
Наши инструменты – не серебряная пуля, не универсальны.
Zabbix – уже позволяет много автоматизировать и кастомизировать в зависимости от окружения и потребностей.
Насколько я могу судить – людей с такими же проблемами и задачами, как у нас – единицы.
Чтобы открывать и выкладывать в открытый доступ – нужно либо много исправлять (времени нет), либо изначально делать с учётом на паблик (но никогда не знаешь, что получится в итоге).
Мы же решаем задачи, а не создаём сервисы.
Как-то так.
Но мы постараемся!

P.S. Оповещения для Telegram делались именно с расчётом на открытость и массовое использование, универсально для всех и каждого. Делается в свободное время и начинал его как pet project на зимних каникулах :)
К сожалению, билеты уже всё, но на вопрос, конечно, отвечу.

А у вас нет желания объявить, кому достались билеты и чем вам понравились их вопросы?

В конце поста есть список победителей со списком вопросов.
Чем понравились – перекрёстное субъективное мнение всех участников ответов: каждый голосовал за вопросы, которые ему понравились, в итоге образовался топ-3, это они :)
Sign up to leave a comment.