Forwarded from Человек и машина
#машины_разное
Во время своего выступления Дор Лаор, СЕО Scylla анонсировал новый проект Cerci, который в корне меняет структуру консенсуса ScyllaDB.
Взамен Paxos в ядро этого немалоизвестного конкурента Cassandra и DynamoDB будет использоваться Raft, что по словам Дора сделано в угоду консистентности и позволяет быстрее синхронизировать новые узлы в кластере.
Интересно попробовать собрать POSIX FS over Scylla... когда-нибудь.
Во время своего выступления Дор Лаор, СЕО Scylla анонсировал новый проект Cerci, который в корне меняет структуру консенсуса ScyllaDB.
Взамен Paxos в ядро этого немалоизвестного конкурента Cassandra и DynamoDB будет использоваться Raft, что по словам Дора сделано в угоду консистентности и позволяет быстрее синхронизировать новые узлы в кластере.
Интересно попробовать собрать POSIX FS over Scylla... когда-нибудь.
ScyllaDB
Making ScyllaDB a Monstrous Database: Introducing Project Circe - ScyllaDB
Project Circe is a year-long initiative to make ScyllaDB even more of a monstrous database, improving performance, scalability and elasticity.
Forwarded from Человек и машина
#машины_разное
Неплохо так бомбануло вчера, да? Честное слово, еще одна авария из-за регулярок (я все еще помню историю с Cloudflare), и я всерьез задумаюсь о выходе из профессии.
Обещанное про TCP и его возможности. Я уверен, вы догадались, что речь пойдет не о рукопожатиях (вы их и без меня знаете, а если не знаете, то срочно идите знать), но про TCP backlog, window, qdisc и прочие прелести, о которых я узнал вот буквально в этом году.
Век живи.
Узнал я про них не абы откуда, а из второго издания Systems Performance Брендана Грегга (которого вы знаете как парня, любящего покричать на диски). Производительность сети вообще несправедливо игнорируемая тема: новое поколение инженеров предпочитает закидывать проблему ресурсами, старое поколение винит во всем сетевиков, либо знает, что сеть можно тюнить на уровне сетевой подсистемы Linux Kernel (эти ребята штучный товар и сидят конечно же в FAANG’ах).
У TCP есть backlog - очередь из сегментов на обработку, каждому порту назначается своя очередь, если эта очередь забивается (tcp congestion), то пакеты начинают теряться. Для управления перегрузкой используются так называемые “алгоритмы избежания сетевой перегрузки” (их много). Сама подсистема использует всякие трюки в виде congestion windows и slow start.
Но управление очередью это еще полбеды. Каждое соединение требует рукопожатия, что на больших объемах негативно влияет на пропускную способность сети. Если сетка у нас уморительно стабильна и каждое соединение успешно “рукопожимается”, то накрутить оборотов можно с помощью TCP initial/receive window. Эти два подхода позволяют добавить небольшой асинхронности сетевой передаче, отправляя и принимая часть сегментов прежде, чем ответить ACK’ом. В довесок к этому есть еще SACK и TCP timestamps - результат схожий, принцип работы несколько другой.
Что еще есть прикольного в этой вашей сетке? TCP/Generic Segment Offloading. Ядро генерирует super packet размером до 64 Кб, который затем нарезается на сегменты непосредственно перед отправкой на сетевой устройство (GSO). Современные сетевые карты могут делать это сами (TSO), так что ядро даже этим не заморачивается.
Ну и напоследок - queueing discipline или qdisc. Qdisc работает на L2-L3 и является планировщиком отправки пакетов/кадров. По умолчанию используется FIFO, но возможностей там гораздо больше, даже есть Token bucket.
В книге Грегга, кстати, есть старый кусок сетевой конфигурации, которая раньше использовалась в Netflix.
Неплохо так бомбануло вчера, да? Честное слово, еще одна авария из-за регулярок (я все еще помню историю с Cloudflare), и я всерьез задумаюсь о выходе из профессии.
Обещанное про TCP и его возможности. Я уверен, вы догадались, что речь пойдет не о рукопожатиях (вы их и без меня знаете, а если не знаете, то срочно идите знать), но про TCP backlog, window, qdisc и прочие прелести, о которых я узнал вот буквально в этом году.
Век живи.
Узнал я про них не абы откуда, а из второго издания Systems Performance Брендана Грегга (которого вы знаете как парня, любящего покричать на диски). Производительность сети вообще несправедливо игнорируемая тема: новое поколение инженеров предпочитает закидывать проблему ресурсами, старое поколение винит во всем сетевиков, либо знает, что сеть можно тюнить на уровне сетевой подсистемы Linux Kernel (эти ребята штучный товар и сидят конечно же в FAANG’ах).
У TCP есть backlog - очередь из сегментов на обработку, каждому порту назначается своя очередь, если эта очередь забивается (tcp congestion), то пакеты начинают теряться. Для управления перегрузкой используются так называемые “алгоритмы избежания сетевой перегрузки” (их много). Сама подсистема использует всякие трюки в виде congestion windows и slow start.
Но управление очередью это еще полбеды. Каждое соединение требует рукопожатия, что на больших объемах негативно влияет на пропускную способность сети. Если сетка у нас уморительно стабильна и каждое соединение успешно “рукопожимается”, то накрутить оборотов можно с помощью TCP initial/receive window. Эти два подхода позволяют добавить небольшой асинхронности сетевой передаче, отправляя и принимая часть сегментов прежде, чем ответить ACK’ом. В довесок к этому есть еще SACK и TCP timestamps - результат схожий, принцип работы несколько другой.
Что еще есть прикольного в этой вашей сетке? TCP/Generic Segment Offloading. Ядро генерирует super packet размером до 64 Кб, который затем нарезается на сегменты непосредственно перед отправкой на сетевой устройство (GSO). Современные сетевые карты могут делать это сами (TSO), так что ядро даже этим не заморачивается.
Ну и напоследок - queueing discipline или qdisc. Qdisc работает на L2-L3 и является планировщиком отправки пакетов/кадров. По умолчанию используется FIFO, но возможностей там гораздо больше, даже есть Token bucket.
В книге Грегга, кстати, есть старый кусок сетевой конфигурации, которая раньше использовалась в Netflix.
Forwarded from Человек и машина
#машины_разное
Разные птички шепчут мне, что дела надо доводить до конца, не смотря на отсутствие дофаминового всплеска.
Оно и правильно - раз обещал рассказать про внешнюю консистентность, будь добр сдержать обещание!
Ваше пятничное чтиво - каким образом в СУБД обеспечивается консистентность, как она достигается на одной машине, на нескольких, почему не работает, и какие исследования в области распределенных транзакций ведутся.
Understanding External Consistency
Ставим лайки, делимся материалом, подписываемся, жалуемся в комментариях “а почему не на русском?!”!
Разные птички шепчут мне, что дела надо доводить до конца, не смотря на отсутствие дофаминового всплеска.
Оно и правильно - раз обещал рассказать про внешнюю консистентность, будь добр сдержать обещание!
Ваше пятничное чтиво - каким образом в СУБД обеспечивается консистентность, как она достигается на одной машине, на нескольких, почему не работает, и какие исследования в области распределенных транзакций ведутся.
Understanding External Consistency
Ставим лайки, делимся материалом, подписываемся, жалуемся в комментариях “а почему не на русском?!”!
Forwarded from Человек и машина
#машины_разное #люди
Брендан Грегг таки не разочаровал и теперь будет работать в Intel.
Учитывая его вовлеченность в производительность систем от железа до программ, можно ждать новый виток нововведений от Intel. Брендан обещает тесную работу с AWS, так что ждем интересных новостей.
Это отличное решение для Intel в первую очередь. Надеюсь, экспертиза Грегга поможет контору занять конкурирущющие позиции с многочисленными ARM производителями.
Брендан Грегг таки не разочаровал и теперь будет работать в Intel.
Учитывая его вовлеченность в производительность систем от железа до программ, можно ждать новый виток нововведений от Intel. Брендан обещает тесную работу с AWS, так что ждем интересных новостей.
Это отличное решение для Intel в первую очередь. Надеюсь, экспертиза Грегга поможет контору занять конкурирущющие позиции с многочисленными ARM производителями.
Forwarded from Человек и машина
#машины_разное
Многие кандидаты валятся на интервью, когда не могут продемонстрировать полное понимание работы предлагаемых инструментов. Проще говоря, если предлагаешь Kafka в роли брокера сообщений, то будь добр понимать внутреннее устройство со всеми его приколами.
Такая придирчивость не только к кандидатам, но и коллегам во время архитектурных разборов. Хуже системы, поведение и принцип работы которой никому не понятен, в эксплуатации не найти.
Отсюда же недоверие к managed хранилищам. К примеру, архитектура той же DynamoDB еле описана в документации и одноименной научной работе. Все что мы, по сути, знаем, что это Leader-Follower СУБД с шардированием по ключу партиции. Каким именно образом работает шардирование, и сколько мы имеем шардов на старте, и как именно распределяются capacity units по шардам, мы не знаем.
С open-source СУБД все гораздо проще, открыл код, да посмотрели ничего не понял. Для тех, кто не хочет смотреть в код и ничего не понимать, есть отличная литература по кишкам. Одно время я запоем читал Database Internals, а теперь с таким же удовольствием читаю про внутренности Postgres 14-ой версии.
Потому что с autovacuum шутки плохи!
Многие кандидаты валятся на интервью, когда не могут продемонстрировать полное понимание работы предлагаемых инструментов. Проще говоря, если предлагаешь Kafka в роли брокера сообщений, то будь добр понимать внутреннее устройство со всеми его приколами.
Такая придирчивость не только к кандидатам, но и коллегам во время архитектурных разборов. Хуже системы, поведение и принцип работы которой никому не понятен, в эксплуатации не найти.
Отсюда же недоверие к managed хранилищам. К примеру, архитектура той же DynamoDB еле описана в документации и одноименной научной работе. Все что мы, по сути, знаем, что это Leader-Follower СУБД с шардированием по ключу партиции. Каким именно образом работает шардирование, и сколько мы имеем шардов на старте, и как именно распределяются capacity units по шардам, мы не знаем.
С open-source СУБД все гораздо проще, открыл код, да посмотрел
Потому что с autovacuum шутки плохи!
Postgrespro
PostgreSQL 14 Internals
Postgres Professional is a PostgreSQL company delivering Postgres Pro DBMS and all kinds of PostgreSQL professional services worldwide
Forwarded from Человек и машина
#машины_разное
Обещанный пост про блокировки!
Если совсем просто, то механизм блокировок (lock) реализуется с помощью обычной хеш-таблицы/словаря/чего-бы-то-ни-было. Ключом к этому словарю обычно является сам объект блокировки, а значение - некий идентификатор/токен замочка.
Объектом блокировки в данном контексте может быть что угодно. Довольно древний, по современным меркам, storage engine MySQL под названием MyISAM блокирует целые таблицы, а более новый InnoDB - строки. Продвинутый механизм блокировок в PostgreSQL, который задействует snapshot isolation - блокировка назначается на строку, но в определенный момент времени! Записи, в том числе обновления и удаления данных, в таблицах Postgres, работают в режиме append only, заправляя это все крепеньким vacuum’ом, ну или как там это называется, знатоки пусть меня поправят.
Локальная система блокировок существует в памяти СУБД.
1. Подключился к СУБД
2. Запрашиваешь “замочек” на строку Х в таблице У (acquire lock)
3. Получаешь некий токен “замочка” - механизм тебя “запоминает”
4. Производишь запись, “освобождаешь” замок (release lock)
Другие транзакции, точно так же приходят за замком и смиренно ждут, пока ты его освободишь. При этом блокировки могут быть на чтение и на запись, простые и двуфазные (тут уже идите читать кабанчика от Клепманна). В целом работа с механизмами блокировок в пределах одноузловой система простая и понятная.
Но если вы работаете в смузихлебном стартапе, то скорее всего вы живете в условиях распределенных систем, а значит у вас распределенные хранилища, а возможно и распределенные системы блокировок!
И если вам сейчас показалось, что я несу откровенную чушь - то зря. В SRE книге Гугла в 4-ой главе рассказывается про распределенную систему блокировок Chubby. Другим примером распределенного замочка может быть ситуация, когда вы хотите заблокировать некую сущность в пределах нескольких независимых систем. Распределенный замок может быть реализован и в рамках самой системы, например Redlock в Redis. Мы к этому еще вернемся, но тут важно уточнить, что Redlock это фича для потребителя, а не внутренний механизм для работы с запросами.
Как любая распределенная система создает неприятный головняк, так и распределенные блокировки тоже. Представьте себе следующее: процесс взял замок, начал обрабатывать транзакцию, а потом умер. Мы можем решить это с помощью срока жизни (TTL) замка, но что если процесс не умер, но задержался на срок дольше TTL?
Решается это еще интереснее, и вот тут я хочу поделиться наинтереснейшей статьей от автора того самого Кабанчика. Там вам и про блокировки, и почему Redlock говно. Не потому что Redlock, а потому что в распределенных системах все говно, если хорошенько докопаться.
Обещанный пост про блокировки!
Если совсем просто, то механизм блокировок (lock) реализуется с помощью обычной хеш-таблицы/словаря/чего-бы-то-ни-было. Ключом к этому словарю обычно является сам объект блокировки, а значение - некий идентификатор/токен замочка.
Объектом блокировки в данном контексте может быть что угодно. Довольно древний, по современным меркам, storage engine MySQL под названием MyISAM блокирует целые таблицы, а более новый InnoDB - строки. Продвинутый механизм блокировок в PostgreSQL, который задействует snapshot isolation - блокировка назначается на строку, но в определенный момент времени! Записи, в том числе обновления и удаления данных, в таблицах Postgres, работают в режиме append only, заправляя это все крепеньким vacuum’ом, ну или как там это называется, знатоки пусть меня поправят.
Локальная система блокировок существует в памяти СУБД.
1. Подключился к СУБД
2. Запрашиваешь “замочек” на строку Х в таблице У (acquire lock)
3. Получаешь некий токен “замочка” - механизм тебя “запоминает”
4. Производишь запись, “освобождаешь” замок (release lock)
Другие транзакции, точно так же приходят за замком и смиренно ждут, пока ты его освободишь. При этом блокировки могут быть на чтение и на запись, простые и двуфазные (тут уже идите читать кабанчика от Клепманна). В целом работа с механизмами блокировок в пределах одноузловой система простая и понятная.
Но если вы работаете в смузихлебном стартапе, то скорее всего вы живете в условиях распределенных систем, а значит у вас распределенные хранилища, а возможно и распределенные системы блокировок!
И если вам сейчас показалось, что я несу откровенную чушь - то зря. В SRE книге Гугла в 4-ой главе рассказывается про распределенную систему блокировок Chubby. Другим примером распределенного замочка может быть ситуация, когда вы хотите заблокировать некую сущность в пределах нескольких независимых систем. Распределенный замок может быть реализован и в рамках самой системы, например Redlock в Redis. Мы к этому еще вернемся, но тут важно уточнить, что Redlock это фича для потребителя, а не внутренний механизм для работы с запросами.
Как любая распределенная система создает неприятный головняк, так и распределенные блокировки тоже. Представьте себе следующее: процесс взял замок, начал обрабатывать транзакцию, а потом умер. Мы можем решить это с помощью срока жизни (TTL) замка, но что если процесс не умер, но задержался на срок дольше TTL?
Решается это еще интереснее, и вот тут я хочу поделиться наинтереснейшей статьей от автора того самого Кабанчика. Там вам и про блокировки, и почему Redlock говно. Не потому что Redlock, а потому что в распределенных системах все говно, если хорошенько докопаться.
Docs
Distributed Locks with Redis
A distributed lock pattern with Redis
Forwarded from Человек и машина
#машины_разное
Насчет смены стратегий, архитектуры и направления, читай "начали за serverless, закончили за монолит", есть важный нюанс под названием "контекст". Можно было бы пройтись по Amazon Prime, но эту историю только ленивый не мусолил. Давайте из моего опыта.
🟢Ситуация 1: CRUD хранилище
Спроектировали систему-хранилище. Модель данных простая до безобразия:
Поле
Целесообразность: эффективно хранить данные, максимальная гибкость клиенту. Сервис, предполагается, будет иметь строгую структуру данных и выполнять функции CRUD.
🟡Ситуация 2: CRUD хранилище с внешними интеграциями.
Проходит некоторое время, и появляется потребность помимо записи в базу делать вызовы туда-сюда, дополнять поле
Целесообразность: иметь отдельный “интеграционный” слой, не выходить за рамки текущего сервиса.
🟠Ситуация 3: CRUD хранилище с внешними интеграциями, динамическими полями и строгой типизацией десериализованных данных.
Как вы догадались, давая клиентам самим десериализовать данные, ловим поток вопросов в поддержку о том, как правильно их десериализовывать. Принимается решение сделать еще один слой абстракции, который десериализацию делает со строгими типами и выдает клиенту. Вдобавок к нашей модели добавляются новые поля, которые рассчитываются динамически через RPC. Делаем новый слой абстракции.
Целесообразность: иметь отдельный уровень абстракции, который берет на себя сложность десерализации и расчета динамических полей.
🔴Ситуация 4: А какого хрена мы ходим через 3 сервиса, чтобы вернуть одну сущность?! Почему у нас 80 мс на проксирование запросов?! Давайте переделывать в угоду эффективности.
Между Ситуацией 1 и Ситуацией 4 прошло без малого 6 лет. Если бы вы, как и я, устроились в контору недавно, вы бы, как и я, решили, что систему проектировали и проектировали наркоманы и смузихлебы.
Тут надо сделать ремарку и вновь упомянуть моего приятеля Серегу П., словами которого я руководствуюсь: "Мне очень экономит время задавание вопроса самому себе, когда я вижу какую-то дичь: "При каких условиях я сделал бы вот эту ебалу?"
Ситуации с 1 по 3 я описал, опираясь на дизайн документы, предшествовавшие каждому слою. В каждом, повторюсь, каждом дизайне все было логично, потому что контекст был именно такой. Предполагали ли инженеры-архитекторы тогда, во что вырастет система сегодня? Сомневаюсь. Представляют ли они сейчас? Вполне себе да. Для опыта не существует алгоритма компрессии.
Насчет смены стратегий, архитектуры и направления, читай "начали за serverless, закончили за монолит", есть важный нюанс под названием "контекст". Можно было бы пройтись по Amazon Prime, но эту историю только ленивый не мусолил. Давайте из моего опыта.
🟢Ситуация 1: CRUD хранилище
Спроектировали систему-хранилище. Модель данных простая до безобразия:
{
UserId: UUID,
ItemId: UUID,
SchemaName: str,
Payload: binary
}
Поле
Payload
представляет собой закодированный в Apache Avro набор данных, схема которого описана в отдельном реестре. Пользователь может декодировать на стороне сервера - тогда сервер вернет JSON, или на стороне клиента - тогда сервер вернет base64 строку, а там уже пусть клиент сам схему разбирает.Целесообразность: эффективно хранить данные, максимальная гибкость клиенту. Сервис, предполагается, будет иметь строгую структуру данных и выполнять функции CRUD.
🟡Ситуация 2: CRUD хранилище с внешними интеграциями.
Проходит некоторое время, и появляется потребность помимо записи в базу делать вызовы туда-сюда, дополнять поле
Payload
новыми данными и класть в базу. Чем городить костыли на текущем сервисе, принимается решение сделать Отдельный Слой Абстракции™, который будет эти вызовы делать.Целесообразность: иметь отдельный “интеграционный” слой, не выходить за рамки текущего сервиса.
🟠Ситуация 3: CRUD хранилище с внешними интеграциями, динамическими полями и строгой типизацией десериализованных данных.
Как вы догадались, давая клиентам самим десериализовать данные, ловим поток вопросов в поддержку о том, как правильно их десериализовывать. Принимается решение сделать еще один слой абстракции, который десериализацию делает со строгими типами и выдает клиенту. Вдобавок к нашей модели добавляются новые поля, которые рассчитываются динамически через RPC. Делаем новый слой абстракции.
Целесообразность: иметь отдельный уровень абстракции, который берет на себя сложность десерализации и расчета динамических полей.
🔴Ситуация 4: А какого хрена мы ходим через 3 сервиса, чтобы вернуть одну сущность?! Почему у нас 80 мс на проксирование запросов?! Давайте переделывать в угоду эффективности.
Между Ситуацией 1 и Ситуацией 4 прошло без малого 6 лет. Если бы вы, как и я, устроились в контору недавно, вы бы, как и я, решили, что систему проектировали и проектировали наркоманы и смузихлебы.
Тут надо сделать ремарку и вновь упомянуть моего приятеля Серегу П., словами которого я руководствуюсь: "Мне очень экономит время задавание вопроса самому себе, когда я вижу какую-то дичь: "При каких условиях я сделал бы вот эту ебалу?"
Ситуации с 1 по 3 я описал, опираясь на дизайн документы, предшествовавшие каждому слою. В каждом, повторюсь, каждом дизайне все было логично, потому что контекст был именно такой. Предполагали ли инженеры-архитекторы тогда, во что вырастет система сегодня? Сомневаюсь. Представляют ли они сейчас? Вполне себе да. Для опыта не существует алгоритма компрессии.
Forwarded from Человек и машина
#анонсы #машины_разное
Согласованный кеш на базе Redis Cluster, Highload Serbia.
https://youtu.be/Sqxsm2oQDsw
Приятного просмотра!
Согласованный кеш на базе Redis Cluster, Highload Serbia.
https://youtu.be/Sqxsm2oQDsw
Приятного просмотра!
Forwarded from Человек и машина
#машины_разное
Null Pointer Exception одна из самых ублюдских проблем, с которой мне приходится сталкиваться с тех пор, как я перешел в бекенд. Особенно противно работать с вложенными структурами, когда приходится делать такие проверки:
Пропустить такие вещи, особенно обрабатывая сериализованные структуры, любезно сгенерированные gRPC или Thrift, раз плюнуть.
Хорошо, что теперь помимо зорких глаз ревьюера, у меня еще есть NilAway!
Null Pointer Exception одна из самых ублюдских проблем, с которой мне приходится сталкиваться с тех пор, как я перешел в бекенд. Особенно противно работать с вложенными структурами, когда приходится делать такие проверки:
s := someStruct{}
if s.Nested != nil || s.Nested.MoreNested != nil || s.Nested.MoreNested.EvenMoreNested != nil {
// ...
}
Пропустить такие вещи, особенно обрабатывая сериализованные структуры, любезно сгенерированные gRPC или Thrift, раз плюнуть.
Хорошо, что теперь помимо зорких глаз ревьюера, у меня еще есть NilAway!
GitHub
GitHub - uber-go/nilaway: Static analysis tool to detect potential nil panics in Go code
Static analysis tool to detect potential nil panics in Go code - uber-go/nilaway