Codeignitor - при входе в систему / загрузке сеанса MySQL CPU spike и Fatal MySQL Deadlock

Первоначально опубликовано на stackoverflow , и было рекомендовано, что сбой сервера может быть лучшим местом.

У меня есть сайт, использующий:

  • AWS RDS ( MySQL Aurora) - один экземпляр t3.medium
  • 4 x EC2 на балансировщике нагрузки (фиксированные экземпляры не эластичны)
  • Кодовая база CodeIgnitor 3 (3.1.11) (я только что обновил версию 3.1.7 по рекомендации, поскольку были некоторые улучшения сеанса в более новых версиях).

Некоторые характеристики:

EC2:

PHP Version 7.2.32-1+ubuntu18.04.1+deb.sury.org+1
Linux ip-172-32-19-104 5.4.0-1028-aws #29~18.04.1-Ubuntu SMP Tue Oct 6 17:14:23 UTC 2020 x86_64
Apache/2.4.29 (Ubuntu)

RDS:

5.6.mysql_aurora.1.22.2
Instance class: db.t3.medium
vCPU: 2
RAM: 4 GB

При большой нагрузке (500 человек пытаются войти в систему в течение десяти минут), мы наблюдаем прерывистые, но значительные Трудно получить информацию о том, что именно испытывают пользователи, но кое-что указывает на следующее:

  • ЦП RDS MySQL Aurora значительно подскакивает (100%)
  • Резкие скачки количества подключений RDS MySQL Aurora (30–45) - из того, что я читал, максимальное количество подключений RDS составляет {DBInstanceClassMemory / 12582880}, то есть около 340 4 ГБ (1024 4 1024 * 1024) / 12582880
  • Результирующая ошибка Обнаружена тупиковая ситуация при попытке получить блокировку; попробуйте перезапустить транзакцию - полную трассировку ошибок см. ниже.

Я сделал, возможно, неверное предположение, что это поэтому:

  1. увеличить нагрузку >> увеличить использование ЦП RDS
  2. высокий ЦП RDS >> тупиковые ситуации >> Неустранимая ошибка MySQL (я не слишком хорошо разбираюсь в тупиках, чтобы знать, может ли это случиться, но звучит возможно).

Ошибка указывает на libaries \ Session \ drivers \ Session_database_driver.php , в частности:

     /**
     * Write
     *
     * Writes (create / update) session data
     *
     * @param   string  $session_id Session ID
     * @param   string  $session_data   Serialized session data
     * @return  bool
     */
    public function write($session_id, $session_data)

   ...
   ...
   ...
   if ($this->_db->update($this->_config['save_path'], $update_data))
        {
            $this->_fingerprint = md5($session_data);
            return $this->_success;
        }

Итак, мы получаем тупик в базе данных при попытке обновить сеанс CI.

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

Это сеанс и класс базы данных соответствуют кодовой базе CI 3.1.7.

Текущая конфигурация сеанса Code Ignitor выглядит следующим образом:

$config['sess_driver'] = 'database';
$config['sess_cookie_name'] = 'ci_session';
$config['sess_expiration'] = 7200;
$config['sess_save_path'] = 'ci_sessions';
$config['sess_match_ip'] = FALSE;
$config['sess_time_to_update'] = 300;
$config['sess_regenerate_destroy'] = FALSE;

Итак, если мое предположение верно, каков будет лучший план действий:

  1. Перейти на RDS Serverless и позволить RDS масштабироваться для обработки нагрузки ЦП? (Я где-то читал, что Serverless может плохо справляться с блокировками, так как не может sca файл правильно, когда он заблокирован ... мое понимание этого явно ограничено)
  2. Перейти на более крупный, фиксированный (не бессерверный) RDS для обработки нагрузки на ЦП? (не идеально, поскольку 95% времени сайт нет трафика)
  3. Изменить сеансы, чтобы они сохранялись в файлах вместо базы данных - это звучит логично, поскольку тогда мы снимаем всю нагрузку сеанса с MySQL, но я не полностью осознаю какие-либо другие последствия , или если это просто случай изменения $ config ['sessions_driver'] и настройки пути к папке с файлом сеанса
  4. Что-то еще ... (php-fpm?)

В варианте 3) мы используем балансировщик нагрузки, поэтому я беспокоюсь, что сеансы на основе файлов будут означать потерю сеанса пользователя, если они переключат LB на полпути. Хотя это может быть управляемой проблемой, так как пользователь будет оставаться на LB на время своего пребывания, если он не упадет на полпути.

Варианты 1 и 2 кажутся подходами как пластырь, а не решением неэффективной проблемы, но тогда это может быть просто случай нехватки ресурсов.

Я читал в другом месте предложение в похожей публикации об использовании php-fpm для уменьшения количества одновременных потоков apache, но не уверен, актуально ли это здесь, особенно учитывая на php 7.2

Трудно «протестировать», так как это происходит только при большой загрузке пользователей, поэтому некоторые предложения будут действительно признательны, поэтому мне не нужно наносить несколько ударов в темноте.

Спасибо

РЕДАКТИРОВАТЬ:

Копия полной ошибки ниже:

A Database Error Occurred 

Error Number: 1213 

Deadlock found when trying to get lock; try restarting transaction 

UPDATE `ci_sessions` SET `timestamp` = 1604298368 WHERE `id` = 'fqi83a50dfknbvl9h2r98mtgn2f3j2j6' Filename: libraries/Session/drivers/Session_database_driver.php 

Line Number: 260 

A PHP Error was encountered 

Severity: Warning 

Message: Unknown: Cannot call session save handler in a recursive manner 

Filename: Unknown 

Line Number: 0 
Backtrace: 

A PHP Error was encountered 

Severity: Warning 

Message: Unknown: Failed to write session data using user defined save handler. (session.save_path: /var/lib/php/sessions) 

Filename: Unknown 

Line Number: 0 

Backtrace

РЕДАКТИРОВАТЬ: ПОКАЗАТЬ СОЗДАТЬ ТАБЛИЦУ ci_sessions;

'ci_sessions', 'CREATE TABLE `ci_sessions` (
 `id` varchar(128) NOT NULL,
 `ip_address` varchar(45) NOT NULL,
 `timestamp` int(10) unsigned NOT NULL DEFAULT \'0\',
 `data` blob NOT NULL,
  KEY `ci_sessions_timestamp` (`timestamp`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8'
1
задан 3 November 2020 в 04:39
1 ответ

Вам нужен какой-то индекс для id.

Если id уникален, вероятно, это должен быть PRIMARY KEY.

2
ответ дан 3 November 2020 в 23:10

Теги

Похожие вопросы