AWS RDS с Postgres: настроен ли OOM killer? - PullRequest
0 голосов
/ 03 сентября 2018

Мы запускаем нагрузочное тестирование для приложения, которое обращается к базе данных Postgres.

Во время теста мы неожиданно получаем увеличение частоты ошибок. Проанализировав поведение платформы и приложения, мы заметили, что:

  • ЦП Postgres RDS составляет 100%
  • Свободные падения памяти на этом же сервере

А в логах postgres мы видим:

2018-08-21 08:19:48 UTC :: @: [XXXXX]: LOG: серверный процесс (PID XXXX) был прерван по сигналу 9: Killed

После изучения и прочтения документации кажется, что одна из возможностей - запуск linux oomkiller, завершивший процесс.

Но поскольку мы находимся в RDS, мы не можем получить доступ к системным журналам / сообщениям var / log для подтверждения.

Так может кто-нибудь:

  • подтверждает, что oom killer действительно работает на AWS RDS для Postgres
  • дайте нам способ проверить это?
  • дайте нам способ вычислить максимальную память, используемую Postgres, на основе количества соединений?

Я не нашел ответа здесь:

Ответы [ 2 ]

0 голосов
/ 17 мая 2019

TLDR: если вам нужен PostgreSQL на AWS и вам нужна стабильная стабильность, запустите PostgreSQL на EC2 (на данный момент) и выполните некоторые настройки ядра для перегрузки


Я постараюсь быть кратким, но вы не единственный, кто видел это, и это известная (внутренняя для Amazon) проблема с RDS и Aurora PostgreSQL.

OOM Killer на RDS / Aurora

Убийца OOM работает на экземплярах RDS и Aurora, поскольку они поддерживаются виртуальными машинами Linux, а OOM является неотъемлемой частью ядра.

Основная причина

Основная причина заключается в том, что в конфигурации ядра Linux по умолчанию предполагается, что у вас есть виртуальная память (файл или раздел подкачки), но экземпляры EC2 (и виртуальные машины, поддерживающие RDS и Aurora), по умолчанию не имеют виртуальной памяти. Существует один раздел, и файл подкачки не определен. Когда linux думает, что у него есть виртуальная память, он использует стратегию, называемую «overcommitting», что означает, что он позволяет процессам запрашивать и получать больший объем памяти, чем объем оперативной памяти, который фактически имеет система. Два настраиваемых параметра управляют этим поведением:

vm.overcommit_memory - определяет, разрешено ли ядру избыточное выполнение (0 = да = по умолчанию) vm.overcommit_ratio - какой процент подкачки system + может перегрузить ядро. Если у вас есть 8 ГБ оперативной памяти и 8 ГБ подкачки, а ваш vm.overcommit_ratio = 75, ядро ​​предоставит процессам до 12 ГБ или памяти.

Мы настроили экземпляр EC2 (где мы могли бы настроить эти параметры), и следующие настройки полностью предотвратили уничтожение бэкэндов PostgreSQL:

vm.overcommit_memory = 2
vm.overcommit_ratio = 75

vm.overcommit_memory = 2 указывает linux не перегружать (работать в рамках ограничений системной памяти), а vm.overcommit_ratio = 75 говорит linux не разрешать запросы для более чем 75% памяти (только пользовательские процессы могут получать до 75% памяти).

У нас есть открытый случай с AWS, и они взяли на себя обязательство разработать долгосрочное исправление (используя параметры настройки ядра или cgroups и т. Д.), Но у нас пока нет ETA. Если у вас возникла эта проблема, я призываю вас открыть дело с AWS и ссылочным случаем # 5881116231, чтобы они знали, что эта проблема также затрагивает вас.

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

0 голосов
/ 06 сентября 2018

AWS поддерживает страницу с лучшими практиками для своей службы RDS: https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_BestPractices.html

С точки зрения распределения памяти, это рекомендация:

Лучшая практика производительности Amazon RDS - выделять достаточно оперативной памяти, чтобы что ваш рабочий набор почти полностью хранится в памяти. Чтобы сказать, если Ваш рабочий набор почти весь в памяти, проверьте метрику ReadIOPS (используя Amazon CloudWatch), когда экземпляр БД находится под нагрузкой. Значение ReadIOPS должно быть небольшим и стабильным. Если увеличить БД класс экземпляра - классу с большим объемом оперативной памяти - приводит к резкому снижению ReadIOPS, ваш рабочий набор не был почти полностью в памяти. Продолжайте увеличивать масштаб до тех пор, пока ReadIOPS больше не будет резко падать после операция масштабирования или ReadIOPS сокращается до очень небольшого количества. Для получения информации о мониторинге метрик экземпляра БД см. Просмотр метрик экземпляра БД .

Кроме того, это их рекомендация для устранения возможных проблем ОС:

Amazon RDS предоставляет показатели в режиме реального времени для операционной системы (ОС) что ваш экземпляр БД работает. Вы можете просмотреть метрики для вашей БД экземпляр с помощью консоли или использование расширенного мониторинга JSON выход из Amazon CloudWatch Logs в системе мониторинга вашего выбор. Для получения дополнительной информации о расширенном мониторинге см. Расширенный Мониторинг

Там много хороших рекомендаций, включая настройку запросов.

Обратите внимание, что в качестве крайней меры вы можете переключиться на Aurora , который совместим с PostgreSQL:

Аврора имеет распределенное, отказоустойчивое, самовосстанавливающееся хранилище система, которая автоматически масштабируется до 64 ТБ на экземпляр базы данных. Аврора обеспечивает высокую производительность и доступность с малой задержкой до 15 чтение реплик, восстановление на определенный момент времени, непрерывное резервное копирование в Amazon S3, и репликация в трех зонах доступности.

РЕДАКТИРОВАТЬ : если говорить конкретно о вашей проблеме с PostgreSQL, проверьте это Stack Exchange thread - у них было длинное соединение с автоматической фиксацией, установленной в false.

У нас было длинное соединение с автоматической фиксацией, установленной в false:

connection.setAutoCommit(false)

За это время мы много делали маленьких запросов и нескольких запросов с курсором:

statement.setFetchSize(SOME_FETCH_SIZE)

В JDBC вы создаете объект соединения, и из этого соединения вы создавать заявления. Когда вы выполняете отчеты, вы получаете результат установлен.

Теперь каждый из этих объектов должен быть закрыт, но если вы закроете заявление, набор записей закрыт, и если вы закрываете соединение все операторы закрыты и их результирующие наборы.

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

Проблема была теперь с этой длинной транзакцией (~ 24 часа), которая никогда закрыл связь. Заявления никогда не были закрыты. По-видимому, объект оператора содержит ресурсы как на сервере, на котором выполняется код и в базе данных PostgreSQL.

Моя лучшая догадка о том, какие ресурсы оставлены в БД, это вещи связанные с курсором. Операторы, которые использовали курсор, никогда не были закрыт, поэтому набор результатов, который они вернули, также никогда не был закрыт. это означает, что база данных не освободила соответствующие ресурсы курсора в БД, и, поскольку он был за огромным столом, потребовалось много оперативной памяти.

Надеюсь, это поможет!

...