Как обрабатывать слишком много параллельных соединений даже после использования пула соединений?
сценарий
скажем, у вас есть сайт или приложение, которое имеет массу трафика. И даже с пулом подключений к базе данных производительность принимает реальный удар (сайт/приложение может даже сбой), потому что слишком много параллельных подключений.
вопрос
какие-то варианты решения этой проблемы?
мои мысли
Я думал кто-то с этой проблемой можно создать несколько баз данных (возможно, на разных машинах, хотя я не уверен, что это необходимо), каждая с той же информацией и обновлена одновременно, что предоставит несколько исходных соединений для одной базы данных. Но если база данных большая, это не кажется очень жизнеспособным решением.
7 ответов
стебель не является достаточно конкретным, чтобы дать твердое предложение, но полный список того, что можно было бы сделать, выглядит следующим образом:
- кластер базы данных: подходит для ситуаций, когда вы не хотите, чтобы изменить уровень приложения и базы данных все, что вы касаетесь. Существует ограничение на то, сколько вы можете получить из кластера базы данных. Если объем вашего запроса продолжает расти, это решение также в конечном итоге потерпит неудачу. Но хорошая новость в том, что у тебя есть все функциональность вы уже в обычный один экземпляр MySQL.
- Sharding: поскольку ваш вопрос помечен MySQL, и он не поддерживает sharding сам по себе, если вы хотите использовать это решение, вам нужно реализовать его в своем слое приложения. В этом решении вы будете разбрасывать свои данные по нескольким базам данных (предпочтительно в нескольких экземплярах MySQL на отдельном оборудовании) логически. Это будет ваша ответственность, чтобы найти соответствующую базу данных холдинг назначенный данных. Это одно из самых эффективных решений, но оно не всегда осуществимо. Его самый большой недостаток заключается в том, что данные, разбросанные между двумя или более базами данных, не могут быть включены в транзакцию.
- репликация: в зависимости от вашего сценария, вы могли бы включить репликацию базы данных и копии ваших данных на них. Таким образом, вы можете подключиться к ним вместо главной базы данных и уменьшить нагрузку на нее. Определение репликации по умолчанию сценарий master/slave, в котором поток данных является одним из способов, от ведущего к ведомому. Таким образом, изменения, которые вы можете сделать на рабе, будут применены к мази, они не повлияют на хозяина. Но существует также конфигурация репликации master/master, в которой поток данных находится в обоих направлениях. Тем не менее, вы не можете предположить атомарную целостность для одновременных изменений данных между обоими мастерами. В конце концов, это решение наиболее эффективно, если вы планируете использовать его в режиме master / slave и использовать slaves только для чтения доступ.
- кэширование: возможно, это решение не следует включать здесь, но так как ваш стебель не отвергает его, вот он идет. Один из способов уменьшить нагрузку на базу данных-кэшировать ее данные после извлечения. Это решение может быть полезным, особенно если извлечение данных является дорогостоящим. Есть много серверов кэша там, как memcached или redis. Таким образом, вы можете пропустить так много подключений к базе данных, но только для извлечения данные.
- другие механизмы хранения: вы всегда можете переключиться на более мощные двигатели, если текущий не предоставить вам то, что вам нужно. Конечно, это возможно, только если ваши потребности позволяют. В настоящее время существуют движки NoSQL, гораздо более эффективные, чем СУБД, которые поддерживают sharding изначально, и вы можете масштабировать их линейно с минимальными усилиями. Существуют также решения на основе Lucene с мощными возможностями полнотекстового поиска, предоставляющими вам тот же автоматический осколок. На самом деле единственная причина, по которой вы должны использовать традиционную СУБД, - это атомарное поведение транзакций. Но если транзакции не являются обязательными, существуют гораздо лучшие решения, чем СУБД.
Если вы еще этого не сделали, вы можете попробовать запустить приложение на сервере приложений-чтобы получить промежуточное ПО позади вашего приложения. Большинство серверов приложений будут делать свой собственный пул соединений (потому что получение соединения из веб-приложения в пул соединений с базой данных по-прежнему очень дорого). Кроме того, вы должны иметь возможность настроить сервер приложений для использования общих подключений , что, как следует из названия, позволит подключениям быть общими везде вероятный.
короче говоря, используйте appserver. Если вы уже есть, возможно, укажите, какой из них вы используете, и мы можем посмотреть на оптимизацию конфигурации сервера оттуда.
репликация -- Master плюс любое количество рабов. Это дает вам "неограниченное" масштабирование чтения.
отключить -- соединение не должно держать соединение открытым дольше, чем это необходимо.
Unix, а не Windows -- нужно ли уточнять?
InnoDB в -- используйте InnoDB, а не MyISAM.
SlowLog -- Set long_query_time
до 1 и следите за верхней парой запросов; оптимизируйте их. Видеть pt-query-digest
для справки в суммировании slowlog.
Это типичная проблема масштабирования приложений, и было разработано множество решений - например, Google Big Table и Amazon Elastic. Если перемещение в облако и использование параметров автоматического масштабирования, которые они все предоставляют, не является опцией, вам нужно создать свою собственную настройку. Взгляните на документы для Postgres и в MySQL, и вы обнаружите, что идеи довольно похожи, включая концепции из
sharding: распределите клиентские данные по нескольким базам данных и направьте запросы клиентов в нужные экземпляры базы данных.
балансировка нагрузки: разверните приложение на нескольких серверах и используйте промежуточное ПО для маршрутизации запросов на основе нагрузки на сервер. Для этого потребуется какой-то инструмент DB synchronizarion, такой как SymmetricDS для синхронизации баз данных.
Это не означает полномасштабный обзор всех вариантов, но может помочь вам начать работу.
есть много вещей, которые вы должны исследовать эту проблему.
- Сколько одновременных соединений. Вы всегда можете увеличить ОЗУ и увеличить количество максимальных подключений. MySQL может поддерживать миллионы соединений.
- убедитесь, что ваше приложение закрывает соединения. Даже с пулом приложение должно возвращать соединения в пул.
-запуск базы данных на отдельном сервере.
- убедитесь, что оптимизированы запросы. Один длинный выполнение запроса может замедлить работу системы.
-наконец, используйте MySQL cluster, если другие подходы терпят неудачу. С высоким трафиком сайта вы можете рассмотреть это, чтобы избежать одной точки отказа.
в нашем случае мы также столкнулись с той же проблемой, когда параллельное соединение mysql достигло 100.
наконец, мы нашли отличный npm express-myconnection модуль (https://www.npmjs.com/package/express-myconnection). Это автоматически освобождает соединения, когда сделано. Он поддерживает один и бассейн стратегии связи.
Он работает нормально.
я столкнулся с аналогичными проблемами, хотя приложение предположительно закрывало его соединения, я мог видеть, как они складываются в SQL как спящие соединения. После проверки проблемы я добавляю следующую строку подключения в webconfig со следующим, чтобы проверить:
Connection Lifetime=600
Это должно было убить любые спящие соединения после 10 минут - но это не так...
при дальнейшем обзоре у меня были ожидающие обновления windows на моем веб-сервере и SQL server. И волшебным образом проблема исчезла!
Я хотел бы, чтобы у меня был более конкретный ответ для вас, но где-то между добавлением этого "времени жизни соединения" и обновлением моих веб-серверов и SQL с патчами полностью устранил проблему для меня. Я чиста уже 3 недели, никаких проблем.