Pull to refresh
62
0
Виктор Пряжников @bikutoru

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

Send message

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

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

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


Сначала сервис/приложение пишет логи, в текст которых добавляются структурированные данные. Здесь задача положить так, чтобы это потом можно было вытащить.
Возможная проблема тут — это сформировать какую-то некорректную строку с какими-то лишними данными или без необходимых. 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 если они есть, но не попали на предыдущую страницу из-за лимита записей на эту самую страницу.

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

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

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

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

Information

Rating
Does not participate
Location
Москва, Москва и Московская обл., Россия
Registered
Activity