Использование коннектора MySql .NET в асинхронном процессе тяжелой нагрузки C # netcore - PullRequest
0 голосов
/ 23 октября 2019

Использование коннектора MySql .NET в асинхронном процессе с большой нагрузкой

Я переписываю с нуля многопоточный tcp-сервер C # .NET Core (для проекта IoT), который обслуживает несколько узлов> долгоживущий tcp-клиент 5 КБсоединений на узел, переходя на его асинхронную версию (я ожидаю получить не менее 10 тыс. соединений на узел с использованием асинхронных шаблонов без заметной нагрузки на процессор).

Каждое соединение должно считывать / записывать из базы данных MySQLна регулярной основе (как минимум 1 запись каждые 3 минуты в режиме ожидания, гораздо больше, когда есть активность).

До сих пор я использовал функцию пула соединений .NET Connector, и я объявил [ThreadStatic] статический объект соединения, который гарантирует, что каждому потоку назначено отдельное поточно-безопасное соединение.

Я получаю соединение из пула соединителя и помещаю его в экземпляр статического потока, затем освобождаю его, как толькокак я могу.

Используя дополнительный механизм подсчета вращений, я избегаюМожно освободить экземпляр, если мне нужно запустить несколько операторов SQL в вызовах вложенных функций.

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

При наличии 5 тыс. tcp-соединений на одном узле скорость выполнения SQL-запросов в секунду на этом узле составляет около 50 q / s, что несамо по себе это огромное значение, но все соединения в пуле остаются «живыми», что не позволяет менеджеру пула соединителей фактически освобождать незанятые соединения в его фоновом потоке (примерно 1000 соединений на узел).

Теперь реальный вопрос.

Мне неясно, как справиться с этой ситуацией в асинхронной среде. Я также использовал альтернативный MySqlConnector, который претендует на истинную асинхронность, но мои сомнения остаются.

Как мне заменить экземпляр [ThreadStatic], если я переключаюсь на шаблон асинхронного ожидания / ожидания?

Как я могу убедиться, что каждый асинхронный поток контекста использует свой собственный экземпляр Connection в поточно-ориентированном режиме (особенно если учесть, что никакие другие операторы не могут работать над соединением, пока все его курсоры не будут закрыты)?

Как я могу запускать параллельные запросы при необходимости?

Как мне работать с диспетчером пула соединителей?

Я действительно запутался в этом.

Я прочитало AsyncLocal<> классе, но я не мог сделать из этого много. Это правильный путь?

...