А вы замечали, сколько исходников есть на github? И на 50-90 процентов приложения написаны используя эти библиотеки. В том числе stdlib. То есть если вы не видите исходный код самого приложения, то вполне вероятно, что у вас есть исходники большинства используемых библиотек.
Выходит, что нужно начинать читать весь гитхаб на предмет TODO и README
Он может в том числе выполнять сборку образов. И он решает вопрос воспроизводимости сборок несколько иначе. Werf кэширует промежуточные слои в реджистри. Разные сборки на разных раннерах используют общие слои. Таким образом решаются 2 задачи - ускорение сборки и повторяемость. Бонусом идёт кейс, что если исходные источники устанавливаемых пакетов более недоступны, то пока у вас есть промежуточный слой в реджистри, где вы их когда-то успешно установили, то вас это не заботит. Не важно, делали ли вы prune или нет, если слой был когда-то собран, то более он пересобираться не будет.
Так же werf сам следит за своими образами в реджистри, на основании истории git, удаляя "лишние" слои только тогда, когда нет веток/тэгов в git, ссылающихся на них
На самом деле зашифрованы только данные, которые лежат на диске. Или в любом другом бэкенде. Если вы получите доступ только к файлам, или дампу БД, тогда да - данные не расшифровать.
Но если вы попали на сервер, где запущен работающий Vault, то тут простор для фантазии. Ключ шифрования находится в памяти, можно дампнуть память процесса. Можно потрейсить процесс или подключиться дебаггером. Можно подгрузить eBPF правила, которые будут сливать часть инфы. Можно воткнуть MITM-прокси (сертифкаты лежат на ноде в виде файлов) и получить токены пользователей, которые делают запросы, а так же посмотреть данные, которые им отправляет Vault.
Спасибо за новый интересный инструмент для мониторинга БД. Здорово, что появляются новые решения.
Часто нужно пушить метрики, а не скрейпить. Если пользоваться prometheus exporter с частично схожим функционалом, то для push метрик нужно было дополнительные упражнения делать.
На данный момент мне кажется вам не хватает каких-то готовых дашбордов по этим метрикам, для графаны например. Метрик много, и смотреть в каждую метрику кожаным мешкам уже тяжело.
Если взять тот же prometheus exporter, к нему уже есть готовые дашборды, хотя бы на сайте графаны, и можно посмотреть в целом на состояние БД, более в человеко..читаемом виде, не заглядывая в каждую метрику отдельно.
Percona Monitoring and Management (PMM) использует под капотом postgresql exporter для метрик, и имеет в комплекте помимо дашбордов ещё и аналитику (алертинг по метрикам), можно просто включить и смотреть по мере необходимости в уже готовые дашборды. Ну и дополнительно статистику по запросам (pg_state_statemets) они хранят в clickhouse
Okmeter предоставляет помимо метрик в чистом виде и дашборды, и алертинг, и рекомендации по запросам (например, добавить индекс), но это, как и РММ, целый комбайн, только он не только базы мониторить может. Но вот агент у него очень лаконичный - один бинарь и даже без конфигурации.
Если выбирать между prometheus exporter и pgpro-otel прямо сейчас, я бы наверное пока использовал postgresql prometheus exporter. Просто потому что я знаю что искать в тех сотнях метрик, которые он экспортирует. У вас же метрики по большей части те же самые, но с другим неймингом. И нет инструментов для их анализа, их нужно делать самим.
Утверждение про "сыроват" - это относительно очень, смотря с чем сравнивать.
А вот для создания нод вполне можно обойтись без terraform и ansible/puppet. Ноды могут создаваться и управляться через machine controller manager прямо из кубернетес. Как в облаках, так в общем то и дя bare metal серверов актуально
Преимущества становятся видны, когда вам нужно разворачивать десятки, а может быть сотни баз, и при этом ваши приложения работают в кубернетес.
Тогда ямл-девелопер описывает манифесты приложений проекта, основываясь на примитивах кубернетес. Deployment, Statefulsets. А когда нужна база - описывает базу прям там же, используя те же примитивы кубернетес. Например, пишет CR (Custom Resource) нужной базы.
Таким образом нет двух мест, где нужно описать проект: для приложений - манифесты кубернетес, а для баз данных - terraform для виртуалок и ansible для конфигурации. Копировать и удалять проекты целиком становится проще. Создал новое окружение - базы там появились вместе с приложениями. Удалил окружение - базы исчезли вместе с окружением. Вернул окружение - базы вернулись обратно, и даже переналились из последнего бэкапа сами.
Для локальной разработки тоже не нужно делать отдельные схемы. Если сейчас у вас база на виртуалке, а локально разработчик запускает ее в докере - это две разных конфигурации. А так он может запускать все в kind/minikube или в dev-кластере, и все будет одинаково.
При этом никто вам не запрещает запускать контейнеры (поды) с базами на выделенных виртуалках или вообще на выделенных железных нодах. Или для дев-сред на виртуалках, а для прод - на железных нодах. Ведь нет никакой разницы для процесса, где он запущен, в контейнере или нет. У вас только меняется средство доставки конфигурации и бинарей. В случае с виртуалками это какой нибудь terraform + ansible/puppet. А в случае с контейнерами - бинари лежат в образе, а конфигурации - в configmap/secrets в etcd kubernetes. Если у вас уже есть kubernetes, то зачем вам еще terraform+ansible/puppet?
Если есть необходимость в базе 96 кор и 2Тб RAM то это прямым образом указывает на то, что архитектура сервиса плохо заточена под масштабирование. Если у вас возрастает нагрузка, вы покупаете другой сервер, куда вставляете 2 процессора по 96 кор и переливаете базу?
А кубернетес же не про это. Он предполагает, что вы можете скейлить ворклоад почти бесконечно, просто создавая больше подов приложения. А так как с базами это плохо работает, то используется другие подходы. Примеры: для каждого сервиса своя небольшая база, использование баз, поддерживающих шардирование, запись через брокеры сообщений, использование нескольких слоев кэширования.
Да, тут теряется консистентность, которую гарантирует БД. Например, если один клиент что-то записал и другой тут же прочитал - данные будут уже обновленные. А использование очередей и кэшей приводит к задержкам доставки актуальных данных. Ну или вы не сможете сделать select.. join из таблиц разных сервисов, потому что одна таблица - это clickhouse из 40 нод, а вторая это opensearch из 10 нод.
Но зато при этом каждый шард базы получается не очень большой, и если ещё имеет реплику - можно обращаться с базами почти как со stateless. То есть включать, выключать, перемещать на другие ноды или другие хранилища. В конце концов раздуть каждый инстас до 96 кор и 2Тб RAM в моменте.
А чтобы не менеджить много маленьких баз с большим количеством шардов или реплик вручную, в кубернетес можно использовать операторы, которые сделают бОльшую часть работы за вас. Не все операторы идеальны, но они хотя бы предсказуемы, так как работают по конкретным алгоритмам. В отличие от части инженеров )
Где гарантия того, что используемые функции сертифицированного СКЗИ вызываются правильно и вызовы не подменяются
О чем именно тут речь? Убедиться, что мое приложение действительно вызывает функции сертифицированного СКЗИ вместо функций, например, openssl? Или убедиться в том, что такие вызовы нельзя перехватить и даже подменить, например, используя eBPF или gdb?
Оформлять соответствующую лицензию нужно перед тем, как приступать к созданию нового СКЗИ
Тут какая-то тонкая и непонятная мне грань, не могли бы пояснить?
Например, я разработчик утилиты, которая шифрует файл используя библиотеку openssl. В какой момент у меня наступает обязанность получить лицензию - когда я открыл текстовый редактор, или перед тем, как я первый раз назвал получившийся результат "СКЗИ"? И наступает ли вообще обязанность получения лицензии, если сертификация СКЗИ не планируется?
Спасибо большое за статью! Открыл для себя такие отличные утилиты, как pv-migrate/pv-rename.
Добавил бы еще, что так как pv-migrate выполняет rsync, то для уменьшения времени простоя, для больших pvc можно выполнить несколько итераций. Сначала "прогнать" pv-migrate несколько раз с ключами --ignore-mounted --source-mount-read-only=false --dest-delete-extraneous-files при рабочем исходном поде (первый проход может занять много времени, если данных сотни гигабайт). Потом сделать бэкап манифеста пода и удалить под. Прогнать pv-migrate еще раз, "начисто". После чего переименовать pvc и восстановить бэкап манифеста пода, он подключит новую pv.
Почему --source-mount-read-only=false ? Если опции монтирования исходного пода и пода-мигратора различаются (pv-migrate создает под, в который подключает 2 вольюма, и между ними копирует данные), то мультимаунт вольюма для некоторых CSI провайдеров не срабатывает и под мигратора не запускается.
Честно говоря никогда не сталкивался с проблемой по смене ОС при смене версии PG. Но обычно я менял ubuntu 20 на ubuntu 22, или CentOS 6 на CentOS 7. А FreeBSD x64 на Debian arm менять не доводилось.
Можете как-то подсветить, в чем может быть проблема при смене версии ОС, чтобы на эти грабли случайно не наступить?
А не засекали по времени, сколько занимает pg_upgrade без analyze? По опыту обычно не долго, несколько секунд.
План мог бы быть:
Делаем физическую реплику 13->13
Мастера переводим в readonly и делаем чекпоинт.
На новом инстансе делаем pg_upgrade 13->16 и promote
На pgbouncer/odyssey переключаем трафик в 16-й постгрес
Делаем analyze/reindex в фоновом режиме на новом мастере
Чтение мы не потеряем (будем читать с 13 постгреса который в ридонли), простой операций записи будет только на пунктах 3-4. Пункт 3 это по факту создание хардлинков и занимает несколько секунд. Пункт 4 это отправка -HUP в pgbouncer. А еще можно заморочиться с PAUSE в pgbouncer, и для приложений, работающих с БД, это будет выглядеть как "медленный ответ БД" вместо "упавшие запросы на запись в бд"
Какие минусы видите в таком подходе? Меня смущает деградация производительности после pg_upgrade без analyze, но честно говоря логическая репликация меня смущает ещё больше, так как сильно зависит от структуры таблиц. Не реплицируемые секвенции - это только одна из проблем.
Разработчики кубернетес придумали хранить конфигурации в объектах ConfigMaps, а секретные/не публичные значения в объектах Secrets, для доступа к которым можно настроить отдельные rbaс
Это выглядит не безопасным, ведь секреты могут утекать, если неправильно настроены rbac, или у вас выполняются, а потом утекают, дампы etcd
Поэтому нужно использовать Vault, там можно гранулярнее задавать доступы к секретам и вести аудит доступа
А чтобы было удобно, используем оператор Vault Secrets Operator, который поместит секретные значения в кубернетес объекты Secrets
После чего в аудите Vault не будет никакой информации о доступе приложений к секретам (потому что они получают доступ к секретам через Secrets Kubernetes), а сами секреты продолжат утекать аналогично п. 2
Итого: мы не хотели хранить секреты в secrets kubernetes, и вместо этого использовали 2 других инструмента, чтобы ... в итоге хранить секреты в secrets kubernetes
Более того, все ещё можно сходить в государственную клинику и сделать зубы или протезы (пусть не такие крутые) бесплатно, точнее по ОМС.
Да, там очередь на месяцы. Но это работает. Сам не делал, но знакомые меняли коронки, и ставили протезы. То есть бюджет может быть и 2.7 млн, и 0.27 млн. И 0 млн. Качество материалов безусловно страдает, и зубы будут действительно "железные", и растянется это на год. Насчёт опытности врачей - очень спорно, там такой поток, что опыта врачам не занимать. Там поврос не в опыте, а в ограниченности материалами и оборудованием. Вряд ли там вам сделают МРТ 3 раза чтобы рассмотреть конкретный канал, а будут делать "на глазок".
Но в любом случае, можно сделать "бесплатно" почти все. И кто-то, у кого нет миллионов на зубы, и сотен тысяч тоже, так и делает. У кого есть миллионы - платит сам. А с миллионов платит налог, и на эти деньги зубы делают другим.
С учётом того, что в 1998 году регистрировались уже восьмизнаки, то "использовать" шестизнак с 2003 года было нельзя, скорее можно было переиспользовать чей-то чужой.
А возможность такая появлялась как раз из-за чисток базы (исключаем вариант "угнанных" аккаунтов)
В похожей ситуации использовали такой подход: m3u динамический, плейлисты отдаются высокопроизводительным бэкендом. Там высокий rps, но нет io, и сами плейлисты мелкие, поэтому bandwidth не занят у серверов.
При генерации плейлиста учитывалась нагрузка на серверы, отдающие непосредственно видеочанки. Серверы выводились из балансировки при недоступности, или когда полоса была на пределе. А ещё автоматом подкидывалась раздача через cdn, когда полоса всех серверов группы была близка к пределу
А вы замечали, сколько исходников есть на github? И на 50-90 процентов приложения написаны используя эти библиотеки. В том числе stdlib. То есть если вы не видите исходный код самого приложения, то вполне вероятно, что у вас есть исходники большинства используемых библиотек.
Выходит, что нужно начинать читать весь гитхаб на предмет TODO и README
Есть такой инструмент werf (werf.io)
Он может в том числе выполнять сборку образов. И он решает вопрос воспроизводимости сборок несколько иначе. Werf кэширует промежуточные слои в реджистри. Разные сборки на разных раннерах используют общие слои. Таким образом решаются 2 задачи - ускорение сборки и повторяемость. Бонусом идёт кейс, что если исходные источники устанавливаемых пакетов более недоступны, то пока у вас есть промежуточный слой в реджистри, где вы их когда-то успешно установили, то вас это не заботит. Не важно, делали ли вы prune или нет, если слой был когда-то собран, то более он пересобираться не будет.
Так же werf сам следит за своими образами в реджистри, на основании истории git, удаляя "лишние" слои только тогда, когда нет веток/тэгов в git, ссылающихся на них
Это частое заблуждение на тему Vault.
На самом деле зашифрованы только данные, которые лежат на диске. Или в любом другом бэкенде. Если вы получите доступ только к файлам, или дампу БД, тогда да - данные не расшифровать.
Но если вы попали на сервер, где запущен работающий Vault, то тут простор для фантазии. Ключ шифрования находится в памяти, можно дампнуть память процесса. Можно потрейсить процесс или подключиться дебаггером. Можно подгрузить eBPF правила, которые будут сливать часть инфы. Можно воткнуть MITM-прокси (сертифкаты лежат на ноде в виде файлов) и получить токены пользователей, которые делают запросы, а так же посмотреть данные, которые им отправляет Vault.
Добрый день.
Спасибо за новый интересный инструмент для мониторинга БД. Здорово, что появляются новые решения.
Часто нужно пушить метрики, а не скрейпить. Если пользоваться prometheus exporter с частично схожим функционалом, то для push метрик нужно было дополнительные упражнения делать.
На данный момент мне кажется вам не хватает каких-то готовых дашбордов по этим метрикам, для графаны например. Метрик много, и смотреть в каждую метрику кожаным мешкам уже тяжело.
Если взять тот же prometheus exporter, к нему уже есть готовые дашборды, хотя бы на сайте графаны, и можно посмотреть в целом на состояние БД, более в человеко..читаемом виде, не заглядывая в каждую метрику отдельно.
Percona Monitoring and Management (PMM) использует под капотом postgresql exporter для метрик, и имеет в комплекте помимо дашбордов ещё и аналитику (алертинг по метрикам), можно просто включить и смотреть по мере необходимости в уже готовые дашборды. Ну и дополнительно статистику по запросам (pg_state_statemets) они хранят в clickhouse
Okmeter предоставляет помимо метрик в чистом виде и дашборды, и алертинг, и рекомендации по запросам (например, добавить индекс), но это, как и РММ, целый комбайн, только он не только базы мониторить может. Но вот агент у него очень лаконичный - один бинарь и даже без конфигурации.
Если выбирать между prometheus exporter и pgpro-otel прямо сейчас, я бы наверное пока использовал postgresql prometheus exporter. Просто потому что я знаю что искать в тех сотнях метрик, которые он экспортирует. У вас же метрики по большей части те же самые, но с другим неймингом. И нет инструментов для их анализа, их нужно делать самим.
Утверждение про "сыроват" - это относительно очень, смотря с чем сравнивать.
А вот для создания нод вполне можно обойтись без terraform и ansible/puppet. Ноды могут создаваться и управляться через machine controller manager прямо из кубернетес. Как в облаках, так в общем то и дя bare metal серверов актуально
https://github.com/gardener/machine-controller-manager
https://deckhouse.ru/products/kubernetes-platform/documentation/v1/kubernetes.html
Преимущества становятся видны, когда вам нужно разворачивать десятки, а может быть сотни баз, и при этом ваши приложения работают в кубернетес.
Тогда ямл-девелопер описывает манифесты приложений проекта, основываясь на примитивах кубернетес. Deployment, Statefulsets. А когда нужна база - описывает базу прям там же, используя те же примитивы кубернетес. Например, пишет CR (Custom Resource) нужной базы.
Таким образом нет двух мест, где нужно описать проект: для приложений - манифесты кубернетес, а для баз данных - terraform для виртуалок и ansible для конфигурации. Копировать и удалять проекты целиком становится проще. Создал новое окружение - базы там появились вместе с приложениями. Удалил окружение - базы исчезли вместе с окружением. Вернул окружение - базы вернулись обратно, и даже переналились из последнего бэкапа сами.
Для локальной разработки тоже не нужно делать отдельные схемы. Если сейчас у вас база на виртуалке, а локально разработчик запускает ее в докере - это две разных конфигурации. А так он может запускать все в kind/minikube или в dev-кластере, и все будет одинаково.
При этом никто вам не запрещает запускать контейнеры (поды) с базами на выделенных виртуалках или вообще на выделенных железных нодах. Или для дев-сред на виртуалках, а для прод - на железных нодах. Ведь нет никакой разницы для процесса, где он запущен, в контейнере или нет. У вас только меняется средство доставки конфигурации и бинарей. В случае с виртуалками это какой нибудь terraform + ansible/puppet. А в случае с контейнерами - бинари лежат в образе, а конфигурации - в configmap/secrets в etcd kubernetes. Если у вас уже есть kubernetes, то зачем вам еще terraform+ansible/puppet?
Если есть необходимость в базе 96 кор и 2Тб RAM то это прямым образом указывает на то, что архитектура сервиса плохо заточена под масштабирование. Если у вас возрастает нагрузка, вы покупаете другой сервер, куда вставляете 2 процессора по 96 кор и переливаете базу?
А кубернетес же не про это. Он предполагает, что вы можете скейлить ворклоад почти бесконечно, просто создавая больше подов приложения. А так как с базами это плохо работает, то используется другие подходы. Примеры: для каждого сервиса своя небольшая база, использование баз, поддерживающих шардирование, запись через брокеры сообщений, использование нескольких слоев кэширования.
Да, тут теряется консистентность, которую гарантирует БД. Например, если один клиент что-то записал и другой тут же прочитал - данные будут уже обновленные. А использование очередей и кэшей приводит к задержкам доставки актуальных данных. Ну или вы не сможете сделать select.. join из таблиц разных сервисов, потому что одна таблица - это clickhouse из 40 нод, а вторая это opensearch из 10 нод.
Но зато при этом каждый шард базы получается не очень большой, и если ещё имеет реплику - можно обращаться с базами почти как со stateless. То есть включать, выключать, перемещать на другие ноды или другие хранилища. В конце концов раздуть каждый инстас до 96 кор и 2Тб RAM в моменте.
А чтобы не менеджить много маленьких баз с большим количеством шардов или реплик вручную, в кубернетес можно использовать операторы, которые сделают бОльшую часть работы за вас. Не все операторы идеальны, но они хотя бы предсказуемы, так как работают по конкретным алгоритмам. В отличие от части инженеров )
Ну почему же? Может они даже одинаковые, но на "просто клауд" нет сертификата. А на "secure cloud" есть.
О чем именно тут речь? Убедиться, что мое приложение действительно вызывает функции сертифицированного СКЗИ вместо функций, например, openssl? Или убедиться в том, что такие вызовы нельзя перехватить и даже подменить, например, используя eBPF или gdb?
Тут какая-то тонкая и непонятная мне грань, не могли бы пояснить?
Например, я разработчик утилиты, которая шифрует файл используя библиотеку openssl. В какой момент у меня наступает обязанность получить лицензию - когда я открыл текстовый редактор, или перед тем, как я первый раз назвал получившийся результат "СКЗИ"? И наступает ли вообще обязанность получения лицензии, если сертификация СКЗИ не планируется?
Спасибо большое за статью!
Открыл для себя такие отличные утилиты, как pv-migrate/pv-rename.
Добавил бы еще, что так как pv-migrate выполняет rsync, то для уменьшения времени простоя, для больших pvc можно выполнить несколько итераций.
Сначала "прогнать" pv-migrate несколько раз с ключами --ignore-mounted --source-mount-read-only=false --dest-delete-extraneous-files при рабочем исходном поде (первый проход может занять много времени, если данных сотни гигабайт). Потом сделать бэкап манифеста пода и удалить под. Прогнать pv-migrate еще раз, "начисто". После чего переименовать pvc и восстановить бэкап манифеста пода, он подключит новую pv.
Почему --source-mount-read-only=false ? Если опции монтирования исходного пода и пода-мигратора различаются (pv-migrate создает под, в который подключает 2 вольюма, и между ними копирует данные), то мультимаунт вольюма для некоторых CSI провайдеров не срабатывает и под мигратора не запускается.
Mounting arguments: -t ext4 -o _netdev,ro /dev/drbd1010 /var/lib/kubelet/pods/7894f1d9-cb3b-4caa-b5dd-94ed94363458/volumes/kubernetes.io~csi/pvc-8e6c39d5-30fd-4a01-9867-64d152abe597//dev/drbd1010 already mounted on /var/lib/kubelet/pods/ee7487b4-dc5c-4d40-b89d-df2396e8bff8/volumes/kubernetes.io~csi/pvc-8e6c39d5-30fd-4a01-9867-64d152abe597/mount.
Честно говоря никогда не сталкивался с проблемой по смене ОС при смене версии PG. Но обычно я менял ubuntu 20 на ubuntu 22, или CentOS 6 на CentOS 7. А FreeBSD x64 на Debian arm менять не доводилось.
Можете как-то подсветить, в чем может быть проблема при смене версии ОС, чтобы на эти грабли случайно не наступить?
Спасибо за интересную статью.
А не засекали по времени, сколько занимает pg_upgrade без analyze? По опыту обычно не долго, несколько секунд.
План мог бы быть:
Делаем физическую реплику 13->13
Мастера переводим в readonly и делаем чекпоинт.
На новом инстансе делаем pg_upgrade 13->16 и promote
На pgbouncer/odyssey переключаем трафик в 16-й постгрес
Делаем analyze/reindex в фоновом режиме на новом мастере
Чтение мы не потеряем (будем читать с 13 постгреса который в ридонли), простой операций записи будет только на пунктах 3-4. Пункт 3 это по факту создание хардлинков и занимает несколько секунд. Пункт 4 это отправка -HUP в pgbouncer. А еще можно заморочиться с PAUSE в pgbouncer, и для приложений, работающих с БД, это будет выглядеть как "медленный ответ БД" вместо "упавшие запросы на запись в бд"
Какие минусы видите в таком подходе? Меня смущает деградация производительности после pg_upgrade без analyze, но честно говоря логическая репликация меня смущает ещё больше, так как сильно зависит от структуры таблиц. Не реплицируемые секвенции - это только одна из проблем.
Как я это прочитал:
Разработчики кубернетес придумали хранить конфигурации в объектах ConfigMaps, а секретные/не публичные значения в объектах Secrets, для доступа к которым можно настроить отдельные rbaс
Это выглядит не безопасным, ведь секреты могут утекать, если неправильно настроены rbac, или у вас выполняются, а потом утекают, дампы etcd
Поэтому нужно использовать Vault, там можно гранулярнее задавать доступы к секретам и вести аудит доступа
А чтобы было удобно, используем оператор Vault Secrets Operator, который поместит секретные значения в кубернетес объекты Secrets
После чего в аудите Vault не будет никакой информации о доступе приложений к секретам (потому что они получают доступ к секретам через Secrets Kubernetes), а сами секреты продолжат утекать аналогично п. 2
Итого: мы не хотели хранить секреты в secrets kubernetes, и вместо этого использовали 2 других инструмента, чтобы ... в итоге хранить секреты в secrets kubernetes
Все время вспоминаю мультфильм Золотые ворота
Не смогли время с NTP синхронизировать?
Немного странно в 2024г подключаться к Vault по http )
А если говорить про https - кастомные сертифкаты поддерживаются? А валидируются? Как передать CA для src и для dst?
Чем не устроила, например, https://github.com/jonasvinther/medusa для миграции данных, через api?
Или встроенный функционал по миграции бэкендов https://developer.hashicorp.com/vault/docs/commands/operator/migrate ?
Этой утилитой? https://github.com/jonasvinther/medusa
А расскажите, как переносите Transit?
Более того, все ещё можно сходить в государственную клинику и сделать зубы или протезы (пусть не такие крутые) бесплатно, точнее по ОМС.
Да, там очередь на месяцы. Но это работает. Сам не делал, но знакомые меняли коронки, и ставили протезы. То есть бюджет может быть и 2.7 млн, и 0.27 млн. И 0 млн. Качество материалов безусловно страдает, и зубы будут действительно "железные", и растянется это на год. Насчёт опытности врачей - очень спорно, там такой поток, что опыта врачам не занимать. Там поврос не в опыте, а в ограниченности материалами и оборудованием. Вряд ли там вам сделают МРТ 3 раза чтобы рассмотреть конкретный канал, а будут делать "на глазок".
Но в любом случае, можно сделать "бесплатно" почти все. И кто-то, у кого нет миллионов на зубы, и сотен тысяч тоже, так и делает. У кого есть миллионы - платит сам. А с миллионов платит налог, и на эти деньги зубы делают другим.
Душить безусловно никого не хотел )
Действительно, вы не написали, что зарегистрировали шестизнак в 2003 году, только то, что использовать стали шестизнак с 2003 года.
В 2001 году использовал в ICQ четырехзнак, 1111. В ICQ Corp, селф-хостед сервер
С учётом того, что в 1998 году регистрировались уже восьмизнаки, то "использовать" шестизнак с 2003 года было нельзя, скорее можно было переиспользовать чей-то чужой.
А возможность такая появлялась как раз из-за чисток базы (исключаем вариант "угнанных" аккаунтов)
В похожей ситуации использовали такой подход: m3u динамический, плейлисты отдаются высокопроизводительным бэкендом. Там высокий rps, но нет io, и сами плейлисты мелкие, поэтому bandwidth не занят у серверов.
При генерации плейлиста учитывалась нагрузка на серверы, отдающие непосредственно видеочанки. Серверы выводились из балансировки при недоступности, или когда полоса была на пределе. А ещё автоматом подкидывалась раздача через cdn, когда полоса всех серверов группы была близка к пределу