Backend Portal | Программирование
17.2K subscribers
1.5K photos
139 videos
41 files
1.31K links
Присоединяйтесь к нашему каналу и погрузитесь в мир Backend-разработки

Связь: @devmangx

РКН: https://clck.ru/3FobxK
Download Telegram
Каждый разработчик должен понимать: изоляция арендаторов это не проблема базы данных.

Это проблема масштаба последствий.

Я понял это на практике.
Один пропущенный фильтр по арендатору.
И обычный выклад превращается в инцидент безопасности.

Любая система с несколькими арендаторами рано или поздно выбирает один из трёх уровней изоляции.
У каждого свой баланс между безопасностью, ценой и операционной проблемой.

1. Отдельная база данных на арендатора

Самая сильная изоляция. У каждого арендатора своя база. Никаких общих таблиц. Никакого общего состояния.

Плюсы очевидны.
Баг в одном арендаторе не утечёт в данные другого. Проверки проще. Разговоры про соответствие требованиям короче. Если что-то ломается, масштаб последствий небольшой.

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

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

2. Отдельная схема на арендатора

Средний вариант, который многие недооценивают.

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

Границы яснее, чем при изоляции по строкам. Нет взрыва количества баз. Проверки остаются разумными. Большинство случайных утечек просто исчезают.

Но сложность всё равно накапливается.
Миграции нужно прогонять по множеству схем. Отчёты по всем арендаторам сразу становятся неудобными. Автоматизация не опция, а необходимость. Без неё модель разваливается под собственным весом.

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

3. Изоляция по строкам

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

Риск жесткий.
Один пропущенный фильтр и утечка данных. Один рефакторинг и изоляция сломалась. Один спешный хотфикс и можно открыть доступ ко всему. Безопасность зависит от того, что каждый слой всегда всё делает правильно.

Это работает только если поставить мощные “перила”: жёсткое ограничение запросов по арендатору, политики на уровне базы, принудительная проверка на уровне сервисов, и тесты, которые специально пытаются выйти за границы арендатора.

Без этого ты ставишь компанию на дисциплину.

Изоляция арендаторов это не выбор способа хранения. Это решение про доверие.

Запомни: это классический вопрос на собеседованиях.

👉 @BackendPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
6👍2
Датабейз штуки, которые я бы изучал, если бы хотел реально глубоко понять масштабирование:

Сохрани в закладки.

▪️B+ деревья
▪️LSM-деревья
▪️Write-Ahead Logging (WAL)
▪️Двухфазный коммит (2PC)
▪️Трехфазный коммит (3PC)
▪️Реплики для чтения (read replicas)
▪️Репликация leader-follower
▪️Партиционирование (partitioning)
▪️Кэширование запросов (query caching)
▪️Вторичные индексы (secondary indexes)
▪️Векторные индексы (FAISS, HNSW)
▪️Распределенные join’ы (distributed joins)
▪️Материализованные представления (materialized views)
▪️Event Sourcing
▪️Change Data Capture (CDC)

👉 @BackendPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
Не пиши в SQL = NULL или != NULL

Для NULL всегда используй IS NULL / IS NOT NULL

NULL это “нет значения / неизвестно”, и обычные операторы сравнения (=, !=, <, >) с ним не работают, потому что NULL не равен, не больше и не меньше вообще ничего.

= / != сравнивают значения. А NULL это не значение, а отсутствие значения. Поэтому IS / IS NOT проверяют именно наличие или отсутствие значения.

👉 @BackendPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
11
This media is not supported in your browser
VIEW IN TELEGRAM
Топовый лайфхак с GitHub: добавь 0 к URL pull request, и ИИ поможет тебе ревьюнуть и понять изменения, которые хотят влить.

👉 @BackendPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
5😁2
Cursor недавно выкатил Composer, свою agentic-модель для кодинга, и заявил, что агент может быть примерно в 4 раза быстрее. Alex Xu пообщался с командой Cursor, в частности с Lee Robinson, чтобы разобраться, как это устроено внутри и за счет чего получается скорость.

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

Внутри Cursor сначала работает роутер: он выбирает подходящую модель для запроса (в том числе Composer), чтобы дальше она вела задачу.

Дальше запускается цикл: вытягиваем самый релевантный код (retrieval контекста), через инструменты открываем и редактируем файлы, гоняем команды в песочнице. Как только тесты зеленые, задача закрыта.

Чтобы этот цикл не тормозил, Cursor опирается на три техники:

1. Mixture-of-Experts (MoE): разреженная MoE-архитектура, где на каждый токен активируется только часть весов модели.

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

3. Уплотнение контекста (context compaction): старые шаги суммаризируются, а в промпте остается только активный рабочий набор, чтобы контекст по мере итераций не раздувался и оставался максимально релевантным и коротким.

Фулл статья

👉 @BackendPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
Бесплатный инструмент для визуализации плана SQL : https://explain.datadoghq.com/

В настоящее время для PostgreSQL, MySQL, MSSQL и MongoDB

👉 @BackendPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3🔥2
GitHub хранит миллионы репозиториев примерно так же, как они лежат у нас локально: буквально как git-репозитории. Ничего особо сверхъестественного

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

Когда мы пушим код, запись не принимается, пока строгая “большинство” реплик не сможет применить изменение и получить тот же результат, то есть минимум 2 из 3.

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

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

Spokes отказывает в write-операциях, если не может закоммитить их хотя бы в двух местах. Это гарантирует, что если твой push прошёл, код уже в безопасности.

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

Примерно так GitHub хранит репозитории и, что важнее, выбирает простой дизайн с упором на консистентность, а не на “лишь бы запись прошла” при просадках по доступности/надёжности.

Надеюсь, тебе тоже было интересно.

👉 @BackendPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12
Как работает NAT

👉 @BackendPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
4👍1
Твои Postgres-серваки сейчас плавятся? Поздравляю. И да, тебе нужен PG Dog.

Его основатель Lev один из самых сильных ребят в теме масштабирования и шардинга БД. Он делал это для Instacart, и его софт может сделать это и для тебя.

Если реплики начинают отставать, а IOPS упёрся в потолок, значит, пора.

https://pgdog.dev/

👉 @BackendPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
3👍2
Не пиши в SQL = NULL или != NULL

Для NULL всегда используй IS NULL / IS NOT NULL

NULL это “нет значения / неизвестно”, и обычные операторы сравнения (=, !=, <, >) с ним не работают, потому что NULL не равен, не больше и не меньше вообще ничего.

= / != сравнивают значения. А NULL это не значение, а отсутствие значения. Поэтому IS / IS NOT проверяют именно наличие или отсутствие значения.

👉 @BackendPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
7
В этом туториале объясняется, что такое JWT, как они работают, какие бывают техники подписи и какие есть best practices по безопасности.

👉 @BackendPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
4
Dockerfile доктор уже тут: переписывает файлы Dockerfile для уменьшения размера и повышения безопасности

👉 @BackendPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
11🔥2
Строки в PostgreSQL неизменяемые и хранятся в heap. У каждой строки есть скрытый идентификатор CTID, который указывает на ее физическое местоположение на диске.

CTID это идентификатор-кортеж из двух частей: номер страницы и индекс (позиция) внутри этой страницы. Посмотреть его можно простым запросом:

SELECT ctid, * FROM your_table;


Вывод будет выглядеть примерно так: (0,1), (0,2), (1,1), где первое число это страница, а второе это позиция.

Что в CTID интересного: когда ты создаешь индекс по первичному ключу, индекс не хранит всю строку целиком. Он хранит значение ключа и CTID, который указывает на реальное место строки в heap.

Из-за этого выборки быстрые. Индекс дает CTID, и PostgreSQL прыгает напрямую в нужную физическую точку в heap, чтобы достать строку.

Но есть нюанс: CTID меняется при обновлении строки. PostgreSQL использует MVCC (Multi-Version Concurrency Control), поэтому update создает новую версию строки в другом физическом месте. Старый CTID становится невалидным, а у строки появляется новый.

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

Интересные архитектурные решения. PostgreSQL сэкономил одно лишнее разыменование, сохраняя CTID, но теперь индекс нужно переписывать даже если меняются неиндексируемые колонки.

Вот почему я обожаю копаться во внутренностях СУБД :) Там сплошь интересные решения и компромиссы.

👉 @BackendPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🔥41
Postgres 18 теперь поддерживает OAUTH 2.0 для аутентификации пользователей.

👉 @BackendPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11