Архитектура сосредоточена на распределенной авторизационной службе, вдохновленной Zanzibar, состоящей из трех уровней: безстатусные узлы оценки Check Engine, глобально распределенная графовая база данных Snapshot Database и событийно-ориентированный Watch Pipeline для недействительности кэша. Этот дизайн разделяет запросы на авторизацию, требующие много чтений, и обновления разрешений, требующие много записей, позволяя независимо масштабировать мощность оценки и обеспечивая надежные гарантии согласованности для изменений отношений. Система использует шаблон zookie от Google для ограничения устаревания без ущерба для преимуществ производительности кэширования на краю.
Узлы Check Engine, развернутые в крайних точках, оценивают запросы на авторизацию с помощью локальных кэшей в памяти и компактных битовых карт разрешений. Эти узлы загружают конфигурации пространств имен из реплицированного кластера etcd и разрешают кортежи отношений из гео-распределенной инстанции CockroachDB или Spanner, которая обеспечивает внешнюю согласованность через TrueTime или гибридные логические часы. Каждый узел поддерживает Bloom фильтры, чтобы предотвратить пропуск кэша, когда отношения определенно не существуют.
Чтобы решить проблему "нового врага", когда недавние отмены могут быть невидимыми для крайних кэшей, система реализует токены zookie — непрозрачные временные метки, кодирующие согласованность моментального состояния, которые заставляют кэширование операции получать пропуски в пределах настраиваемого окна неопределенности. Клиенты получают эти токены с первичных проверок и должны воспроизводить их при доступе к ресурсам высокой ценности, обеспечивая немедленную видимость недавно отмененных разрешений без необходимости в глобальной недействительности кэша. Этот механизм балансирует необходимость низкой задержки с требованием безопасности немедленной видимости отмены.
Недействительность кэша использует Watch Pipeline на основе Apache Kafka, который распространяет изменения кортежей на все крайние узлы Check Engine с использованием согласованного хеширования, обеспечивая, чтобы штормы отмены вызывали разбросанные обновления кэша, а не синхронизированные запрашивания к базе данных. Пайплайн использует метод экспоненциального замедления с дрожью, чтобы предотвратить массовые запросы, когда широко распространенные объекты испытывают изменения разрешений. Эта архитектура гарантирует, что система поддерживает задержку менее 10 мс для попаданий в кэш, обеспечивая при этом причинную согласованность для обновлений разрешений через географически распределенные узлы.
Глобальная платформа для совместной работы с документами, обслуживающая 50 миллионов корпоративных пользователей, испытала катастрофические всплески задержки в часы пик при оценке сложных иерархий совместного использования. Каждому доступу к документу требовалось проходить по вложенным группам и унаследованным разрешениям, хранящимся в монолитном кластере PostgreSQL, что вызывало время запросов более 500 мс и частые таймауты во время массовых обновлений разрешений, когда сотрудники меняли отделы или проекты. Инженерной команде требовалось решение, способное обеспечить задержку менее 10 мс при строгих гарантиях безопасности во время каскадных отмен в рамках вложенных структур папок.
Первый подход оценивал возможность поддержания централизованного кластера PostgreSQL с агрессивным кэшированием путей разрешений через Redis с материализованными представлениями. Плюсы включали сильные гарантии ACID, обеспечивающие немедленную видимость отмен, и простую семантику транзакций для сложных многотабличных обновлений. Минусы заключались в серьезных узких местах записи при массовых изменениях разрешений, неизбежных рисках массовых запросов при обновлении популярных документов и принципиальной невозможности масштабирования пропускной способности чтения географически без сложных реплик чтения, которые вводили неприемлемую задержку репликации для критически важных решений безопасности.
Второй подход предложил полностью денормализированный развертывание Apache Cassandra с приложенческой решением разрешений и истечением срока действия кэша на основе TTL. Плюсы охватывали отличную пропускную способность записи для изменений отношений и внутреннюю многостороннюю доступность без единственных точек отказа. Минусы продемонстрировали неприемлемые соображения по окончательной согласованности, когда отмененные разрешения оставались видимыми в течение нескольких минут из-за задержек протокола шептания, и отсутствие атомарных каскадных удалений создавало уязвимости, когда пользователи сохраняли доступ к ресурсам после исключения из родительских групп, нарушая принцип наименьших привилегий.
Команда в конечном итоге выбрала архитектуру в стиле Zanzibar, использующую CockroachDB для хранения кортежей отношений, Envoy сайдкары в качестве точек принуждения политики и горизонтально масштабируемые узлы Check Engine с кэшами Наименьшей недавно использованной памяти, которые обрабатываются с помощью Bloom фильтров. Этот выбор уравновесил необходимость в надежной согласованности записи разрешений через сериализуемую изоляцию по умолчанию с требованиями производительности на краю через локальные кэши оценки и потоки недействительности, управляемые Apache Kafka. В результате задержка авторизации p99 снизилась с 500 мс до 4 мс, поддерживая 15 миллионов проверок в секунду по всему миру и обеспечивая, чтобы отмены разрешений распространялись на все крайние узлы в течение 150 миллисекунд при поддержании 99.99% доступности.
Как вы предотвращаете, чтобы проверки авторизации не возвращали устаревшие решения "разрешить" сразу после отмены разрешения, не жертвуя преимуществами производительности распределенного кэширования?
Кандидаты часто упускают шаблон zookie или вектор версий, вместо этого предлагая глобальную недействительность кэша или чтения из базы данных для каждой проверки. Решение требует от авторизационной службы возвращать токен согласованности с каждым решением, который кодирует временную метку момента состояния данных, использованных. Для чувствительных операций или после недавних событий отмены клиент должен предоставить этот токен, заставляя Check Engine проверять против центрального хранилища, если его локальный кэш предшествует временной метке токена. Это обеспечивает причинную согласованность без необходимости в глобальной недействительности кэша или жертвования производительностью чтения для большинства запросов.
Как бы вы архитектурно спроектировали механизм недействительности кэша, чтобы избежать массовых эффектов стадного поведения, когда у широко используемого объекта изменяются его разрешения, потенциально вызывая миллионы одновременных обновлений кэша?
Ключевая техника включает согласованное хеширование ключей кэша в сочетании с методами экспоненциального замедления с дрожью и коалесценции запросов на краевых узлах. Когда Watch Pipeline передает изменение кортежа, крайние узлы не аннулируют незамедлительно, а вместо этого планируют недействительность, используя хеш идентификатора объекта, чтобы распределить обновления по временной шкале. Кроме того, каждый Check Engine поддерживает группу выполнения для текущих проверок, обеспечивая, что одновременные запросы для одного и того же объекта делят один результат запроса к бэкенду, что предотвращает перегрузку базы данных во время обновления популярных объектов.
Почему использование простого ориентированного обхода графа недостаточно для моделирования политик ReBAC и как вы обрабатываете ограничения пересечения и исключения в распределенной среде оценки?
Простой обход графа не может захватить операции со множествами, необходимые для сложных политик, таких как "разрешить только в том случае, если пользователь находится в группе A И НЕ в группе B". Решение реализует систему переработки, в которой конфигурации пространств имен компилируются в деревья решений, оцениваемые через обратные индексные запросы, хранение как положительных, так и отрицательных кортежей отношений явно. Для ограничений пересечения система запрашивает оба набора и вычисляет пересечение на уровне Check Engine, в то время как исключения используют короткое замедление оценки с ранним завершением. Этот подход обеспечивает эффективное оценивание сложной логики с помощью булевых операций без необходимости в многократных раундах запроса к базе данных.