Читаю я Рихтера, никого не трогаю. И тут мне открываются новые колдунства в организации межпоточного взаимодействия в c#, о котором я вообще не слышал, а в коде, даже в самом дремучем легаси, никогда не видел. Ключевое слово volatile, Volatile Read и Volatile Write. Дожили.
Пока до конца не осознал что это за звери и нужны ли они мне современном c#, но очень интересно открывать для себя что-то новое.
#Рихтер
#книги
Пока до конца не осознал что это за звери и нужны ли они мне современном c#, но очень интересно открывать для себя что-то новое.
#Рихтер
#книги
Наткнулся на очень интересный инструмент для махинаций с кодом на c# на стадии пост-компиляции: fody.
Инструмент по определенным правилам в скомпилированный код может подсунуть дополнительного функционала, например, во все отмеченные методы влепить логирование. Выглядит очень интересно, хоть пока и кажется близким к бесполезному.
#кодинг
#csharp
Инструмент по определенным правилам в скомпилированный код может подсунуть дополнительного функционала, например, во все отмеченные методы влепить логирование. Выглядит очень интересно, хоть пока и кажется близким к бесполезному.
#кодинг
#csharp
Хабр
Fody и его плагины
С выходом Roslyn разговоры о том, что скоро кода можно писать будет меньше вспыхнули с новой силой. Сегодня я расскажу немного о другом подходе как писать меньше кода и соответственно делать меньше...
Я ранее пару раз упоминал систему сбора метрик Prometheus. Суть ее использования простая: на этапе написания приложения мы используем достаточно простые инструменты и развешиваем метрики вида:
Для обработки данных предусмотрено некоторое количество штатных функций: производная с указанием временного окна, разные варианты суммирования, логарифмы и т.д. Все это добро описывается на достаточно простом языке запросов - PromQL.
Столкнулся на неделе с интересной проблемой: надо было наладить сбор метрик с произвольного числа сервисов (100-200-300), раскиданных по произвольным местам в интернете. Сервисы оживают и умирают в своем ритме.
Обычно Prometheus сам ходит по сервисам и "скреппит" с них метрики. В данном случае такое невозможно. Но на помощь приходит push-gateway: рядом с прометеусом ставится ещё один сервис из экосистемы (в докере), куда все сервисы принудительно отправляют метрики. А прометеус уже сам опрашивает этот сервис.
Отдельно отличное впечатление произвела Graphana - средство для построения графиков и рисования дашбордов.
Указываешь ей: прометеус - там. И при создании графика она сразу на выбор предлагает выбрать одну из его метрик. Больше всего понравился визуальный конструктор запроса на PromQL, с помощью которого формируются данные для графика. Оно и так просто, а с конструктором запросов все низводится до уровня "для дебилов".
Я долгое время хотел сделать сложное преобразование с многокомпонентной метрикой (состоящей из нескольких временных рядов). Несколько раз подступался, но углубляться в недра PromQL и читать доки было лень. В итоге, в графановском конструкторе я нашаманил нужное преобразование за 5 минут.
В целом, экосистема Prometheus производит крайне приятное впечатление, рекомендую всем. Кроме сбора самопальных метрик, можно собирать метрики компонентов инфраструктуры: баз данных, брокеров сообщений. А ещё есть экспортёры системных параметров (CPU, RAM, диск). А в качестве вишенки на торте в экосистеме Prometheus есть система сбора и агрегации логов - loki, знакомство с ней меня ожидает в будущем.
P.S. И Prometheus, и Graphana, и push-gateway ставятся через docker-compose с помощью банальной копипасты из примеров, без включения мозга.
1. Количество и время выполнения запроса1Дальше эти метрики собираются с работающих экземпляров приложения сервером прометеуса и визуализируются. Далее можно строить графики разной степени красивости, цеплять уведомления, срабатывающие по условию и отправляемые, например, в телеграм бота.
2. Число ошибок при выполнении запроса2, и т.д.
Для обработки данных предусмотрено некоторое количество штатных функций: производная с указанием временного окна, разные варианты суммирования, логарифмы и т.д. Все это добро описывается на достаточно простом языке запросов - PromQL.
Столкнулся на неделе с интересной проблемой: надо было наладить сбор метрик с произвольного числа сервисов (100-200-300), раскиданных по произвольным местам в интернете. Сервисы оживают и умирают в своем ритме.
Обычно Prometheus сам ходит по сервисам и "скреппит" с них метрики. В данном случае такое невозможно. Но на помощь приходит push-gateway: рядом с прометеусом ставится ещё один сервис из экосистемы (в докере), куда все сервисы принудительно отправляют метрики. А прометеус уже сам опрашивает этот сервис.
Отдельно отличное впечатление произвела Graphana - средство для построения графиков и рисования дашбордов.
Указываешь ей: прометеус - там. И при создании графика она сразу на выбор предлагает выбрать одну из его метрик. Больше всего понравился визуальный конструктор запроса на PromQL, с помощью которого формируются данные для графика. Оно и так просто, а с конструктором запросов все низводится до уровня "для дебилов".
Я долгое время хотел сделать сложное преобразование с многокомпонентной метрикой (состоящей из нескольких временных рядов). Несколько раз подступался, но углубляться в недра PromQL и читать доки было лень. В итоге, в графановском конструкторе я нашаманил нужное преобразование за 5 минут.
В целом, экосистема Prometheus производит крайне приятное впечатление, рекомендую всем. Кроме сбора самопальных метрик, можно собирать метрики компонентов инфраструктуры: баз данных, брокеров сообщений. А ещё есть экспортёры системных параметров (CPU, RAM, диск). А в качестве вишенки на торте в экосистеме Prometheus есть система сбора и агрегации логов - loki, знакомство с ней меня ожидает в будущем.
P.S. И Prometheus, и Graphana, и push-gateway ставятся через docker-compose с помощью банальной копипасты из примеров, без включения мозга.
prometheus.io
Prometheus - Monitoring system & time series database
An open-source monitoring system with a dimensional data model, flexible query language, efficient time series database and modern alerting approach.
Kafka vs RabbitMQ, часть 1. Описание эксперимента.
Проводил интересный эксперимент: сравнивал между собой брокеры сообщений: Apache Kafka и RabbitMQ под нагрузкой на сообщениях разного размера. В этом посте - описание условий эксперимента, результаты - далее по тегу #kafkavsrabbitmq
Оба брокера брал as-Service, то есть администрирование берет на себя хозяин облака. Под капотом RabbitMQ as Service - 1 инстанс, под капотом Kafka as Service - кластер из 9 .
На 12 серверах раскидал клиентские сервисы: по 70 генераторов данных (Producer) и по 200 потребителей (Consumer). Producer-ы в один поток последовательно генерируют сообщение (массив случайных байт заданного размера), отправляют его в брокер и ждут заданное время до отправки следующего сообщения. Consumer-ы в один поток читают. Режим чтения в Kafka - latest, то есть топики вычитываются не сначала. Сделал центральный сервис конфигурации, куда скидываются POST-запросом настройки сервисов: адреса брокеров и текущие настройки эксперимента - размеры сообщения и задержка после успешной отправки сообщения для регулировки нагрузки. Сервисы раз в некоторое время (от 15 до 30 секунд) ходят за свежей конфигурацией, и, если она поменялась - перенастраиваются.
Данные распределяются по 120 "обменным точкам" - Exchange в RabbitMQ, Topic в Kafka. Доставляются в среднем по 3 раза, везде стоит автоматическое подтверждение получения сообщения Consumer-ом.
Со всех сервисов собирается ряд метрик:
В общем, получил лвлап и кучу экспириенса: зверинец из 550 сервисов я ещё не пас.
#rabbitmq
#kafka
Проводил интересный эксперимент: сравнивал между собой брокеры сообщений: Apache Kafka и RabbitMQ под нагрузкой на сообщениях разного размера. В этом посте - описание условий эксперимента, результаты - далее по тегу #kafkavsrabbitmq
Оба брокера брал as-Service, то есть администрирование берет на себя хозяин облака. Под капотом RabbitMQ as Service - 1 инстанс, под капотом Kafka as Service - кластер из 9 .
На 12 серверах раскидал клиентские сервисы: по 70 генераторов данных (Producer) и по 200 потребителей (Consumer). Producer-ы в один поток последовательно генерируют сообщение (массив случайных байт заданного размера), отправляют его в брокер и ждут заданное время до отправки следующего сообщения. Consumer-ы в один поток читают. Режим чтения в Kafka - latest, то есть топики вычитываются не сначала. Сделал центральный сервис конфигурации, куда скидываются POST-запросом настройки сервисов: адреса брокеров и текущие настройки эксперимента - размеры сообщения и задержка после успешной отправки сообщения для регулировки нагрузки. Сервисы раз в некоторое время (от 15 до 30 секунд) ходят за свежей конфигурацией, и, если она поменялась - перенастраиваются.
Данные распределяются по 120 "обменным точкам" - Exchange в RabbitMQ, Topic в Kafka. Доставляются в среднем по 3 раза, везде стоит автоматическое подтверждение получения сообщения Consumer-ом.
Со всех сервисов собирается ряд метрик:
Бомбил сообщениями следующих размеров:
- Сообщений отправлено
- Сообщений получено
- Байт отправлено
- Байт получено
- Время отправки сообщения
- Число ошибок при отправке
- Число ошибок при получении
Для сбора и визуализации метрик использовалась связка prometheus-push-gateway, Prometheus и Graphana. Сервисам известен адрес push-gateway, они сами туда сбрасывают метрики, prometheus их вычитывает.
- 150 байт
- 5Кб
- 100Кб
В общем, получил лвлап и кучу экспириенса: зверинец из 550 сервисов я ещё не пас.
#rabbitmq
#kafka
Kafka vs RabbitMQ, часть 2. Результаты измерений.
Измерялась сферическая производительность брокера в ваккуме, под конкретную задачу (под NDA).
В качестве измеряемой величины я использовал максимальное количество сообщений в секунду, которое брокер способен разослать сразу, не накапливая их в себе. Ниже приведены получившиеся лимиты для разных размеров сообщения, единица измерения - сообщений/с
Размер сообщения: 150 байт
Kafka - 3000
RabbitMQ - 5000
Размер сообщения: 5 Кб
Kafka - 1100
RabbitMQ - 3600
Размер сообщения: 100 Кб
Kafka - 580
RabbitMq - 1000
#rabbitmq
#kafka
#kafkavsrabbitmq
Измерялась сферическая производительность брокера в ваккуме, под конкретную задачу (под NDA).
В качестве измеряемой величины я использовал максимальное количество сообщений в секунду, которое брокер способен разослать сразу, не накапливая их в себе. Ниже приведены получившиеся лимиты для разных размеров сообщения, единица измерения - сообщений/с
Размер сообщения: 150 байт
Kafka - 3000
RabbitMQ - 5000
Размер сообщения: 5 Кб
Kafka - 1100
RabbitMQ - 3600
Размер сообщения: 100 Кб
Kafka - 580
RabbitMq - 1000
#rabbitmq
#kafka
#kafkavsrabbitmq
Kafka vs RabbitMQ, часть 3. Некоторые впечатления и наблюдения по результатам эксперимента.
1. На практике для себя подтвердил вывод из прочитанного ранее.
2. В отличие от RabbitMQ, для Kafka, даже as-Service всеравно нужен опытный, знающий человек который умеет готовить именно её.
3. При экспоненциальном росте нагрузки Kafka урезает отдачу, а RabbitMQ - прием сообщений.
4. Kafka подключает нового клиента довольно долго. При подключении потребителя в момент, когда Kafka находится в режиме приёма "цунами" сообщений, на клиента по началу вываливается целая куча сообщений, а потом поток урезается до общего уровня.
5. Расстановка метрик вообще, и Prometheus в частности - огонь. Не так много дополнительных приседаний и из нескольких дашбордов понятно происходящее в 550 микросервисах. Prometheus с push-gateway на прием очень экономичны по оперативной памяти (съедали не больше 4-5 Гб), но требовательны к CPU: съедалось на постоянной основе 30+% от 8 ядер сервера.
#rabbitmq
#kafka
#kafkavsrabbitmq
1. На практике для себя подтвердил вывод из прочитанного ранее.
2. В отличие от RabbitMQ, для Kafka, даже as-Service всеравно нужен опытный, знающий человек который умеет готовить именно её.
3. При экспоненциальном росте нагрузки Kafka урезает отдачу, а RabbitMQ - прием сообщений.
4. Kafka подключает нового клиента довольно долго. При подключении потребителя в момент, когда Kafka находится в режиме приёма "цунами" сообщений, на клиента по началу вываливается целая куча сообщений, а потом поток урезается до общего уровня.
5. Расстановка метрик вообще, и Prometheus в частности - огонь. Не так много дополнительных приседаний и из нескольких дашбордов понятно происходящее в 550 микросервисах. Prometheus с push-gateway на прием очень экономичны по оперативной памяти (съедали не больше 4-5 Гб), но требовательны к CPU: съедалось на постоянной основе 30+% от 8 ядер сервера.
#rabbitmq
#kafka
#kafkavsrabbitmq
Telegram
Эшу быдлокодит
Существует целая куча брокеров сообщений и того, что может быть использовано в их качестве. Kafka, RabbitMQ, ActiveMQ, NATS. Продукты от AWS, Microsoft Azure, Yandex Cloud. Notify в PostgreSQL, Queue в Тарантуле, очередь в Redis и ещё куча других решений.…
Сегодня продолжил трогать экосистему Prometheus.
Наконец дошли руки до системы сбора логов - Loki. Вообще, при развертывании "по фен-шую" между сервисами, генерирующими логи и Loki должна использоваться прокладка - Promtail. Promtail осуществляет сбор, анализ, агрегацию и ротацию логов, после чего укладывает их в Loki. Визуализация осуществляется, как и в случае с Prometheus с помощью Graphana.
Но я немного схалтурил и настроил прямую запись из приложения в Loki. Заводится все с ходу, на дефолтных официальных докер образах.
Для централизованной системы анализа логов важно построение поисковых индексов по логам, чтобы из безумного потока отбирать только важное. В ELK стеке индексы конфигурируются из UI при рисовании дашбордов.
В Loki в моей конфигурации об индексировании приходится думать на этапе разработки приложения: надо заложить в сообщения логов метки (например текст {errorType42}), и сообщить отправителю, что их надо индексировать.
А затем, в окне просмотра логов в любой момент можно быстро найти все errorType42 за определенный период времени. И с этой выдачей уже работать другими встроенными инструментами.
#prometheus
Наконец дошли руки до системы сбора логов - Loki. Вообще, при развертывании "по фен-шую" между сервисами, генерирующими логи и Loki должна использоваться прокладка - Promtail. Promtail осуществляет сбор, анализ, агрегацию и ротацию логов, после чего укладывает их в Loki. Визуализация осуществляется, как и в случае с Prometheus с помощью Graphana.
Но я немного схалтурил и настроил прямую запись из приложения в Loki. Заводится все с ходу, на дефолтных официальных докер образах.
Для централизованной системы анализа логов важно построение поисковых индексов по логам, чтобы из безумного потока отбирать только важное. В ELK стеке индексы конфигурируются из UI при рисовании дашбордов.
В Loki в моей конфигурации об индексировании приходится думать на этапе разработки приложения: надо заложить в сообщения логов метки (например текст {errorType42}), и сообщить отправителю, что их надо индексировать.
А затем, в окне просмотра логов в любой момент можно быстро найти все errorType42 за определенный период времени. И с этой выдачей уже работать другими встроенными инструментами.
#prometheus
На неделе познал дзен DDD - domain driven design - подхода к проектированию ПО. Основная суть - разделение мух и котлет - бизнес логики (domain), технического кода по трансформации данных при движении по приложению (application) и взаимодействия с внешним миром (infrastructure).
Раньше во всех моих проектах был сильный перекос: в одном случае 90% проекта приходилось на domain, в другом - infrastructure с примесью application.
Сейчас мне повезло с проектом, где представлены все слои в равной мере и можно поупражняться в правильной архитектуре.
В общем-то самое главное, что даёт "познание дзена DDD" в моем случае - не запоминание догматики правильного построения приложения, а возможность осознанно посмотреть на задачу с новой точки зрения.
Раньше во всех моих проектах был сильный перекос: в одном случае 90% проекта приходилось на domain, в другом - infrastructure с примесью application.
Сейчас мне повезло с проектом, где представлены все слои в равной мере и можно поупражняться в правильной архитектуре.
В общем-то самое главное, что даёт "познание дзена DDD" в моем случае - не запоминание догматики правильного построения приложения, а возможность осознанно посмотреть на задачу с новой точки зрения.
На неделе перешагнул ещё одну важную ступеньку: освоил гитлаб на базовом уровне. Собрал пока экспериментальный стенд вида: мы коммитим в репозиторий, сам собирается докер образ, сохраняется в хранилище образов, после чего вытягивается оттуда и запускается на машине.
Система непрерывной поставки/развертывания с гитлабом выглядит примерно так: есть центральная машина на которой стоит гитлаб. На той же или на соседних машинах установлены Gitlab Runner-ы, выполняющие команды гитлаба.
Вариантов использования Runner-ов масса, я пока остановился на самом простом: выполнение последователльности консольных команд, забитых в скрипте CI/CD.
При коммите Runner, отвечающий за сборку образов, собирает новый образ и сохраняет его в хранилище. Если сборка и сохранение прошли успешно - в дело вступает второй Runner, на машине, где собственно крутится проект. Вытягивает последнюю версию, гасит старый контейнер, запускает новый из нового образа.
Изучать гитлаб можно бесконечно, он неисчерпаем, как электрон, но теперь мне хватает навыков для построения CI/CD на относительно небольшое хозяйство.
#devops
#gitlab
Система непрерывной поставки/развертывания с гитлабом выглядит примерно так: есть центральная машина на которой стоит гитлаб. На той же или на соседних машинах установлены Gitlab Runner-ы, выполняющие команды гитлаба.
Вариантов использования Runner-ов масса, я пока остановился на самом простом: выполнение последователльности консольных команд, забитых в скрипте CI/CD.
При коммите Runner, отвечающий за сборку образов, собирает новый образ и сохраняет его в хранилище. Если сборка и сохранение прошли успешно - в дело вступает второй Runner, на машине, где собственно крутится проект. Вытягивает последнюю версию, гасит старый контейнер, запускает новый из нового образа.
Изучать гитлаб можно бесконечно, он неисчерпаем, как электрон, но теперь мне хватает навыков для построения CI/CD на относительно небольшое хозяйство.
#devops
#gitlab
Sphagnum. Часть 1. Начало.
#sphagnum@eshu_coding
Начинаю новый пет-проект: свой брокер сообщений. Обозвал я его пока Sphagnum, проект планируется в качестве чисто образовательного, под лицензией MIT. Что я хочу получить на выходе:
1. По основному функционалу - клон RabbitMQ, возможно несколько урезанный.
2. Возможность встраивать брокер в другие приложения на .net для организации доступа к проходящим через брокер данным и уменьшению накладных расходов на передачу данных по сети.
3. Очень хочется кафкоподобное горизонтальное масштабирование.
4. Очень хочется возможность сохранения истории прошедших через брокер данных с вычиткой их с произвольного момента.
5. Очень хочется сделать шажочек в сторону работы с динамическими ip некоторых интстансов в системе.
В дальнейшем всё связанное с проектом будет публиковаться под тегами #sphagnum@eshu_coding или #sphagnum. В ближайшее время я буду читать всякое на смежные темы и выкладывать разные теоретические заметки. Код будет ориентировочно зимой.
Пока видится несколько этапов:
1. Отработка основных шаманств по передаче данных, скорее всего поверх сокетов.
2. Реализация хранения данных, думаю надо уметь как NATS - и на диск в самопальные файлики и в базу данных.
3. Админка, видимо в двух вариациях: через rest api и что-то интерактивное, с ui, на базе blazor как вариант.
4. Тесты и оптимизации, оптимизации и тесты. Если удастся догнать RabbitMQ - это будет отличным результатом.
5. Выкатывание проекта в открытый доступ: nuget пакет для установки, несколько образов на docker hub, клиентские библиотеки для основных языков программирования - c#, java, js, python, golang
#проекты
#sphagnum@eshu_coding
Начинаю новый пет-проект: свой брокер сообщений. Обозвал я его пока Sphagnum, проект планируется в качестве чисто образовательного, под лицензией MIT. Что я хочу получить на выходе:
1. По основному функционалу - клон RabbitMQ, возможно несколько урезанный.
2. Возможность встраивать брокер в другие приложения на .net для организации доступа к проходящим через брокер данным и уменьшению накладных расходов на передачу данных по сети.
3. Очень хочется кафкоподобное горизонтальное масштабирование.
4. Очень хочется возможность сохранения истории прошедших через брокер данных с вычиткой их с произвольного момента.
5. Очень хочется сделать шажочек в сторону работы с динамическими ip некоторых интстансов в системе.
В дальнейшем всё связанное с проектом будет публиковаться под тегами #sphagnum@eshu_coding или #sphagnum. В ближайшее время я буду читать всякое на смежные темы и выкладывать разные теоретические заметки. Код будет ориентировочно зимой.
Пока видится несколько этапов:
1. Отработка основных шаманств по передаче данных, скорее всего поверх сокетов.
2. Реализация хранения данных, думаю надо уметь как NATS - и на диск в самопальные файлики и в базу данных.
3. Админка, видимо в двух вариациях: через rest api и что-то интерактивное, с ui, на базе blazor как вариант.
4. Тесты и оптимизации, оптимизации и тесты. Если удастся догнать RabbitMQ - это будет отличным результатом.
5. Выкатывание проекта в открытый доступ: nuget пакет для установки, несколько образов на docker hub, клиентские библиотеки для основных языков программирования - c#, java, js, python, golang
#проекты
Sphagnum. Часть 2. Зачем, а главное нафига?
#sphagnum@eshu_coding
1. Саморазвитие. Читать умные книги это очень познавательно, но намного лучше я усваиваю информацию, когда решаю какую-то задачу, интересную мне. А тут ожидается и изучение существующих архитектурных решений, и выдавливание максимума производительности из c# кода.
2. Для встраиваемого брокера сообщений в экосистеме .Net вполне найдется место. Я вижу как минимум две ниши:
a) Организация сетевого взаимодействия в геймдеве на Unity или в мобильной разработке с использованием MAUI.
b) Онлайн анализ протекающих через брокер данных: например поиск ключевых слов в потоке логов/текстов, которые отправляются на архивирование. Можно конечно ответвить поток данных на отдельного потребителя, осуществляющего анализ. Но в случае цунами из данных, анализ может произойти слишком поздно. А со встроенным брокером - просто скопировать данные (или вообще ссылку на них) внутри процесса. Если бы я запускал #палантир@eshu_coding сейчас, я бы точно не отказался от такого инструмента.
#sphagnum@eshu_coding
1. Саморазвитие. Читать умные книги это очень познавательно, но намного лучше я усваиваю информацию, когда решаю какую-то задачу, интересную мне. А тут ожидается и изучение существующих архитектурных решений, и выдавливание максимума производительности из c# кода.
2. Для встраиваемого брокера сообщений в экосистеме .Net вполне найдется место. Я вижу как минимум две ниши:
a) Организация сетевого взаимодействия в геймдеве на Unity или в мобильной разработке с использованием MAUI.
b) Онлайн анализ протекающих через брокер данных: например поиск ключевых слов в потоке логов/текстов, которые отправляются на архивирование. Можно конечно ответвить поток данных на отдельного потребителя, осуществляющего анализ. Но в случае цунами из данных, анализ может произойти слишком поздно. А со встроенным брокером - просто скопировать данные (или вообще ссылку на них) внутри процесса. Если бы я запускал #палантир@eshu_coding сейчас, я бы точно не отказался от такого инструмента.
Telegram
Эшу быдлокодит
Sphagnum. Часть 1. Начало.
#sphagnum@eshu_coding
Начинаю новый пет-проект: свой брокер сообщений. Обозвал я его пока Sphagnum, проект планируется в качестве чисто образовательного, под лицензией MIT. Что я хочу получить на выходе:
1. По основному функционалу…
#sphagnum@eshu_coding
Начинаю новый пет-проект: свой брокер сообщений. Обозвал я его пока Sphagnum, проект планируется в качестве чисто образовательного, под лицензией MIT. Что я хочу получить на выходе:
1. По основному функционалу…
Послушал открытый урок Otus по некоторым особенностям оптимизации работы кластеров PostgreSQL. В целом, получилось очень познавательно: некоторые из услышанных вещей, упомянутых лишь краем, вызвали реакцию "хм, а так было можно?"
Вот перечень запомнившихся моментов:
1. Оптимизация скорости работы базы данных за счёт разнесения разных таблиц по разным дискам с помощью указания табличных пространств (tablespace). Я про что-то подобное мельком читал во время работы над Палантиром #палантир@eshu_coding, но воспринимал эти махинации исключительно с т.з. размещения большой базы, не влезающей на диск.
2. Оптимизация путем указания стоимости операции одиночного чтения с произвольного места диска. С классических hdd намного быстрее читать последовательно записанные данные. Потому в случае соотношения размера таблицы к размеру индекса 4 к 1 читать с hdd всю таблицу может быть быстрее, чем сканировать индекс и брать нужное из таблицы. А вот на SSD такой разницы нет, и выставив параметр конфигурации random_page_cost=1 мы ощутимо ускорим чтение данных.
3. Махинации с типом репликации. В случае, когда производительность на запись/изменение совсем поджимает, можно пожертвовать надёжностью реплицирования, но выиграть до порядка по быстродействию, переключив репликацию с синхронной на асинхронную. А ещё можно делать реплику, на которую изменения с мастера будут применяться с установленной задержкой, например - час. И в случае катастрофы, например - удаления базы целиком, будет какое-то время оживить систему с меньшими потерями, чем из вчерашнего бэкапа.
4. Узнал про возможность конкуррентного переиндексирования. Предположим, индекс раздулся и начал тупить и есть много места. Можно его удалить и перестроить с нуля. Но "на живую" это приведет к большим проблемам. А оказывается можно запустить фоновое переиндексирование.
5. Узнал, что в постгрес таки есть механизм подсказок планировщику запросов, что ему делать. Для этого нужно расширение pg_hint_plan.
6. Услышал оговорку "обычно балансировку запросов между мастером и репликами у нас делают сами приложения". А так было можно?! Полез читать - оказывается, у стандартного шарпового коннектора Npgsql и балансировщик и координатор выборов нового мастера в случае сбоя есть под капотом.
Курс я конечно покупать не буду, но за 1.5 часа времени информация получена очень полезная.
#postgresql
Вот перечень запомнившихся моментов:
1. Оптимизация скорости работы базы данных за счёт разнесения разных таблиц по разным дискам с помощью указания табличных пространств (tablespace). Я про что-то подобное мельком читал во время работы над Палантиром #палантир@eshu_coding, но воспринимал эти махинации исключительно с т.з. размещения большой базы, не влезающей на диск.
2. Оптимизация путем указания стоимости операции одиночного чтения с произвольного места диска. С классических hdd намного быстрее читать последовательно записанные данные. Потому в случае соотношения размера таблицы к размеру индекса 4 к 1 читать с hdd всю таблицу может быть быстрее, чем сканировать индекс и брать нужное из таблицы. А вот на SSD такой разницы нет, и выставив параметр конфигурации random_page_cost=1 мы ощутимо ускорим чтение данных.
3. Махинации с типом репликации. В случае, когда производительность на запись/изменение совсем поджимает, можно пожертвовать надёжностью реплицирования, но выиграть до порядка по быстродействию, переключив репликацию с синхронной на асинхронную. А ещё можно делать реплику, на которую изменения с мастера будут применяться с установленной задержкой, например - час. И в случае катастрофы, например - удаления базы целиком, будет какое-то время оживить систему с меньшими потерями, чем из вчерашнего бэкапа.
4. Узнал про возможность конкуррентного переиндексирования. Предположим, индекс раздулся и начал тупить и есть много места. Можно его удалить и перестроить с нуля. Но "на живую" это приведет к большим проблемам. А оказывается можно запустить фоновое переиндексирование.
5. Узнал, что в постгрес таки есть механизм подсказок планировщику запросов, что ему делать. Для этого нужно расширение pg_hint_plan.
6. Услышал оговорку "обычно балансировку запросов между мастером и репликами у нас делают сами приложения". А так было можно?! Полез читать - оказывается, у стандартного шарпового коннектора Npgsql и балансировщик и координатор выборов нового мастера в случае сбоя есть под капотом.
Курс я конечно покупать не буду, но за 1.5 часа времени информация получена очень полезная.
#postgresql
Эшу быдлокодит
И в четвертый раз, на те же грабли, в том же месте! Да, я пока ленюсь написать нормальный генератор данных.
Когда я занес ногу в пятый раз, уже на другом проекте на другой работе - я попустился и таки сел писать генератор тестовых данных.
Дочитал Рихтера до типов перечислений (enum) и наткнулся на дополнительное направление их применения, которое я многократно использовал в чужих библиотеках, но ни разу не задавался вопросом, что там под капотом?
Вообще, enum - штука очень удобная, использую их постоянно. Представляет собой конечный набор значений, которые под капотом - лёгкий целочисленный тип, а в коде представлены в человекочитаемой форме.
А тут я осознал, что можно использовать enum как битовые флаги, дополняя битовые операции человекочитаемостью! Достаточно пометить свой enum атрибутом [Flags] и можно развлекаться с байтиками, не отправляя читателя кода в недра клинописи вида 0x5A3 | 0x5A4. Отличный пример приведен мы официальной доке от MS:
Помнил бы я об этих махинациях год назад - поэкономил бы байтиков от души.
#Рихтер
#книги
P.S. Другой вариант записи enum-а из примера:
Вообще, enum - штука очень удобная, использую их постоянно. Представляет собой конечный набор значений, которые под капотом - лёгкий целочисленный тип, а в коде представлены в человекочитаемой форме.
А тут я осознал, что можно использовать enum как битовые флаги, дополняя битовые операции человекочитаемостью! Достаточно пометить свой enum атрибутом [Flags] и можно развлекаться с байтиками, не отправляя читателя кода в недра клинописи вида 0x5A3 | 0x5A4. Отличный пример приведен мы официальной доке от MS:
[Flags]
public enum Days
{
None = 0b_0000_0000,
Mon = 0b_0000_0001,
Tue = 0b_0000_0010,
Wed = 0b_0000_0100,
Thu = 0b_0000_1000,
Fri = 0b_0001_0000,
Sat = 0b_0010_0000,
Sun = 0b_0100_0000,
Weekend = Sat | Sun
}
Помнил бы я об этих махинациях год назад - поэкономил бы байтиков от души.
#Рихтер
#книги
P.S. Другой вариант записи enum-а из примера:
[Flags]
public enum Days
{
None = 0,
Mon = 1,
Tue = 2,
Wed = 4,
Thu = 8,
Fri = 16,
Sat = 32,
Sun = 64,
Weekend = Sat | Sun
}
На прошлых выходных был на конференции по экосистеме .Net, к которой относится мой основной язык - c#: DotNext.
В первый день прослушал 4 доклада, во второй - 5.
Далее будет серия постов по прослушанным докладам, с тегом #dotnext@eshu_coding
#conf
В первый день прослушал 4 доклада, во второй - 5.
Далее будет серия постов по прослушанным докладам, с тегом #dotnext@eshu_coding
#conf
#dotnext, день 1, доклад 1.
Workflow архитектура сервисов в .Net
Узнал, что в природе существует отдельно выделяемая workflow-архитектура - построение приложения вокруг определенных путей, которые проходит в своем жизненном цикле бизнес-сущность.
Самый простой пример - заявление, курсирующие между начальникам, оставляющими визу или завораживающими на доработку.
Раньше подобные вещи я решал через конечные автоматы, описывая логику в переходах между состояниями, решать ту же проблему через описание пути выглядит достаточно интересным ходом.
Также в докладе рассказали о готовых либах, реализующих workflow в c#. По случаю может и пригодится.
P.S. Отдельным бонусом к либам идёт возможность генерации блок схемы наших workflow
#conf
Workflow архитектура сервисов в .Net
Узнал, что в природе существует отдельно выделяемая workflow-архитектура - построение приложения вокруг определенных путей, которые проходит в своем жизненном цикле бизнес-сущность.
Самый простой пример - заявление, курсирующие между начальникам, оставляющими визу или завораживающими на доработку.
Раньше подобные вещи я решал через конечные автоматы, описывая логику в переходах между состояниями, решать ту же проблему через описание пути выглядит достаточно интересным ходом.
Также в докладе рассказали о готовых либах, реализующих workflow в c#. По случаю может и пригодится.
P.S. Отдельным бонусом к либам идёт возможность генерации блок схемы наших workflow
#conf
#dotnext, день 1, доклад 2.
Когда 100% cpu ничего не значит.
Доклад был посвящен некоторым нюансам, понижающим производительность приложений когда в коде все нормально.
Основная полезная информация, которую я вынес - о механизме устройства конвейера виртуальных машин, за мощности которых мы платим хостерам.
Если наш сервис постоянно потребляет мизерное количество ресурсов, хостер, в рамках оптимизации, может засунуть его миллионной виртуалкой на запасной сервер.
И тут к нам приходит лавинообразная нагрузка. Реально выделенных (а не тех, за которые уполчено) выделенных ресурсов нам перестает хватать, автоматика хостера пытается как-то выдать нам оплаченное и теперь востребованное - и тратит на это время, в течение которого наш сервис может захлёбываться на ровном месте.
Другой интересный момент - взятие лишнего десятка ядер CPU, как раз таки на такой случай, не спасает, а наоборот делает хуже. Чем больше запрашиваемые нами ресурсы - тем сложнее приткнуть нашу виртуалку туда, где они есть.
Ещё было занятно про k8s и гармоничные настройки потребления памяти, но кубером я пока не проникся, потому прошло мимо.
#conf
Когда 100% cpu ничего не значит.
Доклад был посвящен некоторым нюансам, понижающим производительность приложений когда в коде все нормально.
Основная полезная информация, которую я вынес - о механизме устройства конвейера виртуальных машин, за мощности которых мы платим хостерам.
Если наш сервис постоянно потребляет мизерное количество ресурсов, хостер, в рамках оптимизации, может засунуть его миллионной виртуалкой на запасной сервер.
И тут к нам приходит лавинообразная нагрузка. Реально выделенных (а не тех, за которые уполчено) выделенных ресурсов нам перестает хватать, автоматика хостера пытается как-то выдать нам оплаченное и теперь востребованное - и тратит на это время, в течение которого наш сервис может захлёбываться на ровном месте.
Другой интересный момент - взятие лишнего десятка ядер CPU, как раз таки на такой случай, не спасает, а наоборот делает хуже. Чем больше запрашиваемые нами ресурсы - тем сложнее приткнуть нашу виртуалку туда, где они есть.
Ещё было занятно про k8s и гармоничные настройки потребления памяти, но кубером я пока не проникся, потому прошло мимо.
#conf
#dotnext, день 1, доклад 3.
Кафка и распродажи в Озоне.
Доклад был посвящен перемалыванию пиковых нагрузок в Озоне. Довольно много касалось Apache Kafka, ну и рассказывали что и как у них устроено. В целом - очень интересно, но прям совсем ничего нового. Хотя, поиграться с такими нагрузками желание появилось.
Из забавного - у них считается нормальным тестить на проде, точнее не тестить, а устраивать учения:)
#conf
Кафка и распродажи в Озоне.
Доклад был посвящен перемалыванию пиковых нагрузок в Озоне. Довольно много касалось Apache Kafka, ну и рассказывали что и как у них устроено. В целом - очень интересно, но прям совсем ничего нового. Хотя, поиграться с такими нагрузками желание появилось.
Из забавного - у них считается нормальным тестить на проде, точнее не тестить, а устраивать учения:)
#conf
#dotnext, день 1, доклад 4.
Dependecy Injection в тестах.
Автор из Яндекса пропагандировал использование стандартных практик написания кода внутри тестов, ну и рассказал об основных тестовых фреймворках в .Net (я и так знал, что использую самый дремучий - MSTest).
Звучит круто и логично, но на моей практике пока ничего хорошего из попыток написать тесты также как обычный код не вышло: поддержка из редактура становилась слишком трудоёмкой.
Пока наиболее оптимальным выглядит путь максимального говнокода с копипастой. И совсем чуть-чуть выноса повторяющихся простынь в отдельные методы.
#conf
Dependecy Injection в тестах.
Автор из Яндекса пропагандировал использование стандартных практик написания кода внутри тестов, ну и рассказал об основных тестовых фреймворках в .Net (я и так знал, что использую самый дремучий - MSTest).
Звучит круто и логично, но на моей практике пока ничего хорошего из попыток написать тесты также как обычный код не вышло: поддержка из редактура становилась слишком трудоёмкой.
Пока наиболее оптимальным выглядит путь максимального говнокода с копипастой. И совсем чуть-чуть выноса повторяющихся простынь в отдельные методы.
#conf
#dotnext, день 2, доклад 1.
Экономия памяти в .Net.
Известно, что приложения на java/c# съедают память столько, сколько им дадут. Но если заморочиться - можно сократить потребление.
В докладе занимались загрузкой файлов со средним размером ~123 Мб. В среднем на загрузку такого файла уходило ~280 Мб памяти.
Путем разных непристойных действий с байтами автор ужал потребление памяти до ~2.7 Мб, т.е. в 100 раз. И даже не особо потерял в читаемости кода.
Во основном использовалось два подхода:
1. Пулинг объектов
2. Выделение памяти на стеке вместо кучи
В c# есть встроенный пул массивов, которые можно использовать как буферные объекты, не создавая новые и не забивая память новосоздаваемыми одноразовыми массивами.
А если таки надо создавать буферные короткоживущие объекты - можно попробовать разместить их на стеке. Использовать структуру. Или вообще аллоцировать кусочек стека и использовать его по своему усмотрению (главное не переусердствовать и не завалить все приложение со Stack Overflow Exception).
Список колдунств, применённых автором, просто чтобы не забыть:
1. stackalloc
2. ArrayPool
3. readonly ref struct
4. ValueStringBuilder (вытащенный внутренний класс из недр рантайма c#, базирующийся на стеке билдер строк).
5. TryFormat
Ещё была важная мысль - использовать бенчмарки в докере, чтобы сравнивать как работает код в целевой ОС, а не на Винде, где идёт разработка.
#csharp
#conf
Экономия памяти в .Net.
Известно, что приложения на java/c# съедают память столько, сколько им дадут. Но если заморочиться - можно сократить потребление.
В докладе занимались загрузкой файлов со средним размером ~123 Мб. В среднем на загрузку такого файла уходило ~280 Мб памяти.
Путем разных непристойных действий с байтами автор ужал потребление памяти до ~2.7 Мб, т.е. в 100 раз. И даже не особо потерял в читаемости кода.
Во основном использовалось два подхода:
1. Пулинг объектов
2. Выделение памяти на стеке вместо кучи
В c# есть встроенный пул массивов, которые можно использовать как буферные объекты, не создавая новые и не забивая память новосоздаваемыми одноразовыми массивами.
А если таки надо создавать буферные короткоживущие объекты - можно попробовать разместить их на стеке. Использовать структуру. Или вообще аллоцировать кусочек стека и использовать его по своему усмотрению (главное не переусердствовать и не завалить все приложение со Stack Overflow Exception).
Список колдунств, применённых автором, просто чтобы не забыть:
1. stackalloc
2. ArrayPool
3. readonly ref struct
4. ValueStringBuilder (вытащенный внутренний класс из недр рантайма c#, базирующийся на стеке билдер строк).
5. TryFormat
Ещё была важная мысль - использовать бенчмарки в докере, чтобы сравнивать как работает код в целевой ОС, а не на Винде, где идёт разработка.
#csharp
#conf