Как стать автором
Обновить
62
0
Виктор Пряжников @bikutoru

Пользователь

Отправить сообщение

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

Валидация отклонит такие данные. Валидация отклоняет валидные логи? Ой.

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


Сначала сервис/приложение пишет логи, в текст которых добавляются структурированные данные. Здесь задача положить так, чтобы это потом можно было вытащить.
Возможная проблема тут — это сформировать какую-то некорректную строку с какими-то лишними данными или без необходимых. Google protobuf тут позволяет проверить, а все ли данные есть. Если чего-то нет, то это не повод не писать логи совсем, а повод дать знать, что есть проблема в запаковке данных (бросить какую-то ошибку, записать специальное сообщение в лог или как-то иначе сигнализировать о проблеме).


В статье про это сказано так:


Наша реализация годами оттачивалась, чтобы канонические строки генерировались для каждого запроса даже при возникновении внутренних сбоев и неожиданном поведении.… Этот инструмент настолько важен для нас, что любые проблемы с ним должны максимально быстро устраняться (иначе реагирование на инциденты будет похоже на полёт вслепую).

В конце эти логи собираются со всех машин и загружаются в какое-то центральное хранилище (в статье сказано про Presto, Redshift и Kafka). И вот тут уже структурированные данные должны извлекаться из текста строк. Данные извлекаются, проверяются той же схемой Google protobuf и пишутся в хранилище распакованными. Если данные тут некорректны, то не получится их распаковать (а значит и записать) и об этой проблеме тоже нужно сигнализировать (т.к. проблема может быть не только в запаковке, но и при передаче "в центральную систему для поиска и анализа", например).


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

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

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

Главная вещь, к которой я призываю — не использовать на автомате время с секундной точностью (потому что "её хватит всем"). Вместо этого стоит задумываться о том, не будет ли пользы от большей точности и если будет, то инструменты для работы с ней уже есть и их можно использовать. Если вам достаточно порядка, то в этом нет ничего плохого, не нужно использовать максимальную точность времени.

А есть реальные задачи, где время с такой точностью нужно?

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


Другой пример — замер времени доставки сообщений чата между базами данных отправителя и получателя. Это физически разные базы и хочется понимать, сколько времени происходит между отправкой сообщений (записью её в базу отправителя) и доставкой (базу получателя). При секундной точности разницу между 0.05 и 0.95 секунды будет не видна, а при повышении точности времени в базе — вполне.

В своём первом комментарии вы говорите про две вещи:


  1. сортировки по времени не нужны, а нужны по ID
  2. непонятно, зачем нужна такая точность времени.

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


Более того, мессенджер как-то свои сообщения локально хранит и их айдишники наверняка на время тоже завязаны.

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

Сортировка по уникальному идентификатору — это очень хорошо и если можно её использовать, то лучше сделать это. К сожалению она не всегда подходит. Вот несколько примеров, где эта сортировка не поможет:


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

В обоих случаях можно обойтись без дат если ввести дополнительный идентификатор, отражающий порядок сортировки (счетчик публикации для первого примера, счётчик сообщений для второго), но при его использовании есть свои проблемы: как минимум нужно гарантировать его уникальность, а использовать автоинкремент уже не получится. Я не уверен, что это будет проще, чем использовать время публикации/обновления.

Я хотел проиллюстрировать, как работают миграции с временем высокой точности. Изначально план был сделать несколько примеров для разных фреймворков, но в процессе я решил что достаточно будет и одного примера. В результате в статью попал тот, что был сделан первым (с Yii у меня лично самый большой практический опыт среди популярных фреймворков, поэтому начал именно с него).


Насколько мне известно, в кодовой базе Badoo нет Yii (но есть немного Laravel и Symfony Components).

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

Интересно. Кажется, что с помощью такой обёртки можно править баги при работе с временем, если обновить версию PHP нельзя или попался новый еще неисправленный баг.

Да, все эти записи будут проигнорированы при выборке. Если же заменить условие created < X на created <= X, то сюда попадёт и та запись, что уже была показана на предыдущей странице.


Эту проблему тоже можно решить — добавить к сортировке и фильтру по created второе поле, уникальное для каждой записи (тот же автоинкрементный id, например), но придётся усложнять условия выборки. Запрос на выборку страницы тогда будет выглядеть как-то так:


SELECT id, created
FROM CommentsTable
WHERE ((created > :last_shown_created) OR (created = :last_shown_created AND id > :last_shown_id))
ORDER BY created ASC, id ASC
LIMIT 10

Тут в условии (created = :last_shown_created AND id >:last_shown_id) отвечает за корректную обработку случая, когда есть несколько записей в то же время, что и у граничной записи, а (created > :last_shown_created) за обработку случая, когда их нет.


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


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


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

Не совсем понял пример.


В моём примере подразумевалось, что если мы делаем пагинацию без оффсетов (при использовании которых есть свои проблемы), а на базе условий вида WHERE created < "2019-10-08 12:13:14" ORDER BY created DESC LIMIT 10 (где 2019-10-08 12:13:14 — это время последнего объекта предыдущей страницы, а 10 — количество записей на страницу), то мы не покажем другие объекты с тем же значением created если они есть, но не попали на предыдущую страницу из-за лимита записей на эту самую страницу.

Способ, позволяющий выкатить новый функционал не на всех пользователей, а только на их часть

Да, имелось в виду именно это

Процесс, после завершения которого пользователям становится доступна последняя версия вашего приложения или сайта

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

Информация

В рейтинге
Не участвует
Откуда
Москва, Москва и Московская обл., Россия
Зарегистрирован
Активность