Обновить
4
0
Александр Червинский@Tellamonid

Энтерпрайз-разработчик

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

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

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

Мы делаем так:

  • процессы записи пишут батчами, взятыми из мессаджинга; используются уникальные ключи, и not exists по ним (нам по бизнес-специфике в некоторых случаях одна и та же запись может прийти очень много раз), и еще вдобавок используется хинт ignore_row_on_dupkey_index (у нас оракл) чтобы в редких случаях коллизий не падать, а продолжать;

  • эти же процессы в той же транзакции на каждый батч отписывают в оракловую очередь, что такие-то сущности поменялись (чаще всего тут на несколько порядков меньше записей, чем строк в батче, но это опять же наша специфика);

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

    Все операции делаются со стандартным уровнем изоляции read committed.

Лет 15 назад интернет ещё не был сломан. На любую тему были форумы, у них были подфорумы, и там можно было задавать вопросы, и получать ответы. Потом появился Stack Overflow, и, к счастью, здравствует по сей день. А ещё через какое-то время развились сообщества в мессенджерах. Мало того, что эти мессенджеры не совместимы между собой, и надо иметь несколько установленными, так они ещё и не индексируются. Эффективность поисковиков упала, ответы на многие вопросы сейчас просто не найти. И приходится находить соответствующий чат, например, в Телеграме, и задавать вопрос там. Получается, что людям сейчас сильно сложнее найти ответ, на который кто-то уже отвечал, и приходится заново спрашивать, и заново отвечать.

Автору спасибо за проект, и успехов!

Насчет Детройта/Чикаго не уверен, а Лондонская почти наверняка из-за книжки «Growing Object Oriented Software, Guided by Tests”. Авторы книги – британцы, авторы библиотеки JMock, и они продвигали подход с моками.

Что интересно, конкретно про тесты и моки мне не очень понравилось, что они пишут, мне понравилось другое. А именно что они начинают с ужасного кода, плохо разбитого, и последовательно применяя SRP (single responsibility principle), они приходят к аккуратному коду. Для меня эта книжка была скорее про SRP, чем про тесты.

о да, юнит-тесты, тестирующие имплементацию, а не контракт – это, к сожалению, классика. И они не помогают рефакторить, а только мешают. И бывает очень тяжело объяснить людям, что пользы от таких тестов практически нет, а время на их написание и поддержание уходит.

первая часть, которая до C++ кода, перекликается с ещё одним хорошим докладом: Никита Коваль – На пути к быстрой многопоточной хеш-таблице. Там ребята тоже пришли к варианту с открытой адресацией. Разница в том, что доклад Никиты про реализацию на Джаве.

Интересно, спасибо за ссылку!

Либо у Оракла не совсем B*-деревья, либо у меня было не до конца правильное понимание, как они работают. Надо бы посмотреть, что пишет на эту тему эксперт по оракловым индексам Ричард Фут (Richard Foote)

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

В B*-дереве вообще нет ребалансировки. Есть алгоритм деления блоков, который поддерживает дерево сбалансированным. Что если переполнился листовой блок в середине, делим 50 на 50, а на краю – 100 на 0. И в каких-то случаях это будет приводить к делению бранч-блока (или даже нескольких по цепочке), а это в свою очередь иногда будет приводить к делению корневого блока, и созданию нового. Деление корневого блока – единственный случай, когда высота B*-дерева растет.

Ваша ссылка про B-деревья, а я писал про B*-деревья в Оракле, они устроены несколько по-другому. И я опять же предполагаю, что и в других РСУБД реализация ближе к оракловой, чем к классическому B-дереву. Если кто знает точно, напишите, пожалуйста. В Оракле действительно есть параметр PCTFREE, который говорит, сколько свободного места оставлять в листовых блоках при инсертах, для будущих апдейтов. При PCTFREE=10 листовые блоки будут заполняться на 90%. И можно выставить PCTFREE=0, если мы точно знаем, что апдейтов не будет.

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

А потом провести тот же эксперимент с UUID-полем (в Оракле это будет raw(16)), и мы увидим, что после перестроения индекс уменьшится примерно на четверть, или на треть. Потому что на этот раз записи будут лежать плотно. Но это не естественное состояние для индекса по UUID, и при последующих вставках он вернется к своему нормальному состоянию, когда блоки не до конца заполнены.

нет-нет, @Nurkedвсё правильно пишет, что наиболее плотно ложатся в индекс, например, данные из последовательности (сиквенса). По крайней мере в Оракле, но, думаю, и в других СУБД тоже. Все дело в алгоритме деления блока. Если заполняется листовой блок в серединке, то он делится пополам (деление 50 на 50), а если это крайний блок, то просто добавится новый (хоть это деление часто называют 90 на 10, оно на самом деле 100 на 0). И таким образом, если мы будем писать разбросанные по индексу данные, то блоки будут не полностью заполнены. А если пишем из последовательности, то полностью.

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

У вас немного странное представление о TDD. Там не тесты пишутся до кода. И не может быть ситуации «почти все готово - половину тестов написал, осталось только вторая половина, ну и по мелочи - код, рефакторинг…», потому что пишется один самый простой тест кейс, а потом сразу код, который делает, чтобы код проходил, потом – чуть более сложный тест кейс, и код, чтобы уже два теста проходили, и так далее.

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

В настоящих реляционках у Nested loops обычно сложность O(N). Допустим мы соединяем таблицу orders и таблицу customers, и передаем список order_id. Пусть у нас достаточно большие таблицы, но не гигантские. Тогда нам на каждый order_id надо затратить три логических чтения блоков индекса (его высота), и одно логическое чтение блока таблицы. Потом столько же для customer_id, который мы взяли в таблице orders. Итого 8 логических чтений. А если нам на вход дали 100 order_id, то у нас будет 800 логических чтений. Строго линейная зависимость.

У вас на картинке Джава и Котлин подписаны наоборот: Джава же более древняя, а Котлин — молодёжь.

У меня уже давно установлен PCalc Lite. Рекламы там нет, возможностей калькулятора мне хватает.

Мы используем Logger, который рекомендовал Том Кайт. Единственное что, мы секционировали таблицу по дням, и чистим с помощью дропа партиций, а не с помощью удаления строк. То есть мы сделали изменения относительно оригинала, но они минимальные.

Из плюсов:

  • эта штука поддерживает переключение, например, с уровня info на уровень debug на лету;

  • при использовании log_error в эксепшен-блоке, в лог автоматом вставится стек трейс, то есть нам достаточно только словами описать, что у нас не получилось сделать, а остальное за нас сделает логгер;

  • если мы в начале процедуры положили входные параметры в специальную коллекцию, то в случае log_error мы их тоже увидим.

Но главный плюс, конечно, в том, что мы не стали тратить время на написание собственного логгера на pl/sql.

У меня стоит Mikrotik LHG LTE kit, летом выдаёт до 90 мегабит/с на скачивание, и около 30 на отдачу, зимой похуже (бывает 20–30 мегабит/с на скачивание) причем я не очень понимаю, с чем это связано.
Но главное, я там вообще ничего не настраивал. Его надо просто воткнуть в вайфай-роутер, и всё работает. Я только время от времени смотрю показатели вроде SINR в Микротиковском веб юае, и то ради интереса.

По ссылке про Серену Вильямс написано, что она как-то утром не успела выпить эспрессо, и проиграла сет. Потом между сетами выпила-таки эспрессо, и выиграла матч. Это как-то совсем не то же самое, что «Серена Уильямс всегда пьет эспрессо, прежде чем вернуться на корт»

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

Пользуюсь Newsify. Несколько раз пробовал перейти на InoReader, как на популярный, но мне там неудобно отмечать статьи как прочитанные.

Информация

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