В плюсах какое-то совершенно невменяемый слой legacy и новых фич. При этом если что-то явно не описано в стандарте, то оно попадает в долину undefined behaviour.
Лично у меня есть стойкое ощущение, что плюсы не знает никто.
Rust в отличие от C++ гораздо более предсказуем. Меня как-то очень впечатлило, когда я попытался передать в другой поток подключение к PostgreSQL и компилятор мне этого сделать не дал. Я потратил пару часов, чтобы разобраться, что в потрохах подлючения используется не потокобезопасный счетчик ссылок. Но осознание того, что на боевом коде эта проблема проявляла бы себя только под нагрузкой и очень редко, заставляет шевелиться волосы на спине...
В случае сборки контейнера qemu-user-static живёт пока запущен процесс в контейнере, то есть не более одного шага сборки. В нашем случае это не очень большое время (до 10 минут). Мог просто не заметить.
Ну и сами шаги сборки контейнера обычно достаточно простые.
Но на старой версии qemu была проблема со старой же Java на обновлении ca-сертификатов (оно происходит как раз при установке Java в контейнер). Это полечилось использованием qemu от Ubuntu 20.04.
А увеличение времени сборочных машин ничего принципиально не меняет, если их более одной штуки. Ну и машинки с коротким временем жизни стоят заметно дешевле.
Даже в вашем простом случае локальный кэш работает только когда образ собирается на одной и той же машинке.
В нашем случае сборочные машинки живут меньше суток и из-за этого приходится использовать кэш в registry.
Цель у этого проста: получить более быструю сборку, чтобы переиспользовать слои с Runtime и уменьшить объём данных между образами, так как слои с Runtime получаются одинаковыми.
Я не видел вашу статью, когда разбирался в этом вопросе. Сейчас я посмотрел её и выглядит так, что обе статьи дополняют друг друга.
У нас, как минимум, разный подход к решению проблемы с binfmtпри каждой перезагрузке.
Автоматическое кэширование в buildx есть, но в рамках одного хоста. Если образы могут собираться на нескольких машинках, то для общего кэша приходится делать дополнительные телодвижения. Это же касается сборкой через обычный docker build (там то же надо использовать опцию --cache-from, но в другом формате - её передаётся только имя ранее собранного образа).
Я не упомянул основную проблему, которая пока держит нас от того, чтобы полностью отказаться от использования mongos в sidecar-ах в пользу отдельных сервисов: некоторые клиентские библиотеки для работы с MongoDB крайне плохо работают, когда список mongos-ов меняется в процессе работы.
Использовать mongos как sidecar - рабочая конфигурация.
Но у неё есть свои недостатки:
Pod должен иметь доступ к keyfile mongos-а, а эти реквизиты надо как-то предоставить mongos-у и они дают полный доступ к mongod;
mongos далеко не бесплатный: он активно ест CPU на старте и RAM в процессе работы. Причем, что особо печально, количество ресурсов зависит от размера кластера. В нашем случае были прецеденты, когда более 2/3 ресурсов Pod-а выделялось сугубо под mongos-ы;
приложение должно ждать, пока mongos запустится;
время старта mongos-а может драматически увеличиваться, если какие-то ноды mongod недоступны;
если селить mongos в отдельный контейнер, то тяжело выставить ресурсы всех контейнеров, чтобы нормально работал HPA. Особенно если кластеров MongoDB более одного.
Из плюсов такой конфигурации:
более низкое latency при доступе к базе.
У нас сейчас используются оба варианта выкатки mongos-ов: и в пулах, и в sidecar-ах. И мы плавно мигрируем к варианту с пулами.
У меня, кстати, сложилось впечатление, что ни одна СУБД полностью не соответствует SQL стандарту.
Касательно статьи, можно упомянуть более простой случай, где MySQL не соответствует SQL92.
Речь идет про абзац:
13.9 <update statement: positioned>
6) The <value expression>s are effectively evaluated before updat-
ing the object row. If a <value expression> contains a reference
to a column of T, then the reference is to the value of that
column in the object row before any value of the object row is
updated.
Да. Именно так. Микроскопическая утилита запустится с обобщенным
go.mod
.С моей точки зрения, в контексте монорепы Go Workspaces бесполезны, так как по факту мы просто получаем распределённый
go.mod
.У С++ есть ровно два плюса.
В плюсах какое-то совершенно невменяемый слой legacy и новых фич. При этом если что-то явно не описано в стандарте, то оно попадает в долину undefined behaviour.
Лично у меня есть стойкое ощущение, что плюсы не знает никто.
Rust в отличие от C++ гораздо более предсказуем. Меня как-то очень впечатлило, когда я попытался передать в другой поток подключение к PostgreSQL и компилятор мне этого сделать не дал. Я потратил пару часов, чтобы разобраться, что в потрохах подлючения используется не потокобезопасный счетчик ссылок. Но осознание того, что на боевом коде эта проблема проявляла бы себя только под нагрузкой и очень редко, заставляет шевелиться волосы на спине...
Жаль, что на https://launchpad.net/~longsleep/+archive/ubuntu/golang-backports до сих пор 1.17 не появилась...
Не знаю...
В случае сборки контейнера
qemu-user-static
живёт пока запущен процесс в контейнере, то есть не более одного шага сборки. В нашем случае это не очень большое время (до 10 минут). Мог просто не заметить.Ну и сами шаги сборки контейнера обычно достаточно простые.
Но на старой версии
qemu
была проблема со старой же Java на обновлении ca-сертификатов (оно происходит как раз при установке Java в контейнер). Это полечилось использованиемqemu
от Ubuntu 20.04.То же вариант :)
Но тут контейнер
multiarch/qemu-user-static:register
может завершиться уже после окончания завершения загрузки системы.В результате можно поймать гонку между началом сборки и выполнением контейнера. Хотя вероятность выглядит не очень большой.
Создание локального registry - это отдельная тема.
Их очень много разных, например (ссылки отсортированы по алфавиту):
https://about.gitlab.com/install/
https://docs.docker.com/registry/
https://goharbor.io/
https://jfrog.com/artifactory/
https://quay.io/
https://www.sonatype.com/products/repository-oss
А увеличение времени сборочных машин ничего принципиально не меняет, если их более одной штуки. Ну и машинки с коротким временем жизни стоят заметно дешевле.
Даже в вашем простом случае локальный кэш работает только когда образ собирается на одной и той же машинке.
В нашем случае сборочные машинки живут меньше суток и из-за этого приходится использовать кэш в registry.
Цель у этого проста: получить более быструю сборку, чтобы переиспользовать слои с Runtime и уменьшить объём данных между образами, так как слои с Runtime получаются одинаковыми.
Я не видел вашу статью, когда разбирался в этом вопросе. Сейчас я посмотрел её и выглядит так, что обе статьи дополняют друг друга.
У нас, как минимум, разный подход к решению проблемы с
binfmt
при каждой перезагрузке.Автоматическое кэширование в
buildx
есть, но в рамках одного хоста. Если образы могут собираться на нескольких машинках, то для общего кэша приходится делать дополнительные телодвижения. Это же касается сборкой через обычныйdocker build
(там то же надо использовать опцию--cache-from
, но в другом формате - её передаётся только имя ранее собранного образа).Хочу заметить, что пример Уильяма Генри Гейтса III в качестве человека, который много работал и всего добился сам несколько не корректен.
Я не упомянул основную проблему, которая пока держит нас от того, чтобы полностью отказаться от использования mongos в sidecar-ах в пользу отдельных сервисов: некоторые клиентские библиотеки для работы с MongoDB крайне плохо работают, когда список mongos-ов меняется в процессе работы.
Для примера:
сейчас mongos при завершении работы просто закрывает все клиентские соединения. Исправиться это должно только с MongoDB версии 5.0: https://docs.mongodb.com/v5.0/release-notes/5.0/#quiesce-period
некоторые клиенты долго держали соединения до mongos и при добавлении новых Pod-ов нагрузка на них перетекала очень медленно.
Использовать mongos как sidecar - рабочая конфигурация.
Но у неё есть свои недостатки:
Pod должен иметь доступ к keyfile mongos-а, а эти реквизиты надо как-то предоставить mongos-у и они дают полный доступ к mongod;
mongos далеко не бесплатный: он активно ест CPU на старте и RAM в процессе работы. Причем, что особо печально, количество ресурсов зависит от размера кластера. В нашем случае были прецеденты, когда более 2/3 ресурсов Pod-а выделялось сугубо под mongos-ы;
приложение должно ждать, пока mongos запустится;
время старта mongos-а может драматически увеличиваться, если какие-то ноды mongod недоступны;
если селить mongos в отдельный контейнер, то тяжело выставить ресурсы всех контейнеров, чтобы нормально работал HPA. Особенно если кластеров MongoDB более одного.
Из плюсов такой конфигурации:
более низкое latency при доступе к базе.
У нас сейчас используются оба варианта выкатки mongos-ов: и в пулах, и в sidecar-ах. И мы плавно мигрируем к варианту с пулами.
Регистронезависимое сравнение очень шаткое и сильно зависит от локали.
К примеру, в Турции
windows
/WİNDOWS
не то же самое, чтоWINDOWS
/wındows
.В репликации MySQL много недостатков.
На эту тему мне очень нравится статья: https://habrahabr.ru/company/oleg-bunin/blog/313594/
Git LFS решает только проблему хранения blueprint-ов в Git.
Проблема просмотра изменений и слияния остаётся не решенной.
Perforce ужасен: https://bozaro.ru/2016/11/18/p4-broken/
В общем случае — проковырять дырку нельзя.
Могу порекомендовать посмотреть в сторону:
Например: GRE не использует порты.
Извиняюсь, если я был не правильно понят.
Когда я говорил про отсутствие наименования стандарта, речь шла про статью: http://ocelot.ca/blog/blog/2013/09/30/sometimes-mysql-is-more-standards-compliant-than-postgresql/
Статья все равно жёлтая: обсуждение соответствия стандарту без ссылок не то что, на сам стандарт, а даже на его название.
У меня, кстати, сложилось впечатление, что ни одна СУБД полностью не соответствует SQL стандарту.
Касательно статьи, можно упомянуть более простой случай, где MySQL не соответствует SQL92.
Речь идет про абзац:
И иллюстрируется запросом:
Беда в том, этот запрос в MySQL эквивалентен: