web-dev-qa-db-ja.com

再起動後、Apache 2のリクエスト処理が非常に遅くなる

受信したHTTPSリクエストをApacheがインストールされたサーバーに送信し、データをMySQLデータベースに保存するNodeJSを使用するGPSデバイスソケット処理サーバーがあります。 NodeJSまたはApacheがインストールされたサーバーを再起動すると、Apacheがインストールされたサーバーのリクエスト処理率が非常に遅くなります。これまでのところ、MySQLのパフォーマンスとその動作を確認しています。 1秒あたり5〜15のリクエストのみがNodeJSサーバーからトリガーされます。通常の状況では、正常に機能しますが、再起動後、サーバーは非常に悪くなります。数時間後、自動的に問題が解決します。この問題を解決する方法とそれを監視するために共有するために必要な詳細をガイドしてください?

サーバーの詳細:

Ubuntu server with 8GB RAM and 4 Cores processor.

MySQL設定:

key_buffer_size         = 16M
max_allowed_packet      = 16M
thread_stack            = 192K
thread_cache_size       = 8

query_cache_limit       = 1M
query_cache_size        = 16M
max_binlog_size   = 100M

innodb_log_file_size=512M
innodb_buffer_pool_size=6G
innodb_buffer_pool_instances=6
innodb_flush_log_at_trx_commit=2
innodb_flush_method=O_DIRECT_NO_FSYNC
innodb_log_files_in_group=5
innodb_open_files=1000
sync_binlog=0

max_connections=512
table_open_cache=1000
table_open_cache_instances=16
back_log=1000

query_cache_limit=2M
query_cache_size=0
query_cache_type=0

sort_buffer_size=32M
read_rnd_buffer_size=32M

トップコマンド:トッププロセスリスト、6.8GBを使用するMySQL

しばらくすると、MySQLが自動的に再起動し、サーバーが再び遅くなります。

Apache Buddy

[ -- ] Parent PID: 19547.
[ OK ] Memory usage of parent PID is less than 50MB: 7268 Kilobytes.
[ -- ] Apache has been running 0d 23h 19m 11s.
[ !! ] *** LOW UPTIME ***.
[ @@ ] The following recommendations may be misleading - Apache has been restarted within the last 24 hours.
[ -- ] Your server has 7976 MB of PHYSICAL memory.
[ -- ] Your ServerLimit setting is 512.
[ -- ] Your MaxRequestWorkers setting is 512.
[ OK ] Current Apache Process Count is 45, including the parent PID.
[ -- ] Number of vhosts detected: 5.
[ -- ]             |________ of which 3 are HTTP (specifically, port 80).
[ -- ]             |________ of which 2 are HTTPS (specifically, port 443).
[ OK ] Current Apache vHost Count is less than maxrequestworkers.
[ >> ] MaxRequestsPerChild directive not found.
[ -- ] This server is NOT running Plesk.
[ -- ] This server is NOT running cPanel.
[ -- ] This server is NOT running Virtualmin.
[ -- ] Your PHP Memory Limit (Per-Process) is 128M.
[ -- ] MySQL Detected => Using 7038.63 MB of memory.

[ OK ] No large log files were found in /var/log/Apache2.
[ OK ] MaxClients has not been hit recently.
[ >> ] Apache only logs maxclients/maxrequestworkers hits once in a lifetime, if no restart has happened this event may have been rotated away.
[ >> ] As a backup check, please compare number of running Apache processes (minus 1 for parent) against maxclients/maxrequestworkers.
[ OK ] No PHP Fatal Errors were found.

[ -- ] Apache2 is currently using 1308.65 MB of memory.
[ -- ] The smallest Apache process is using 9.73 MB of memory
[ -- ] The average Apache process is using 9.82 MB of memory
[ -- ] The largest Apache process is using 10.19 MB of memory
[ !! ] Going by the average Apache process, Apache can potentially use 5027.85 MB RAM:
        Without considering services: 63.04 % of total installed RAM
        Considering extra services: 536.38 % of remaining RAM
[ !! ] Going by the largest Apache process, Apache can potentially use 5217.28 MB RAM:
        Without considering services: 65.42 % of total installed RAM
        Considering extra services: 556.59 % of remaining RAM


--------------------------------------------------------------------------------
### GENERAL FINDINGS & RECOMMENDATIONS ###
--------------------------------------------------------------------------------
Apache2buddy.pl report for server:
Settings considered for this report:
[ !! ] *** LOW UPTIME ***.
[ @@ ] The following recommendations may be misleading - Apache has been restarted within the last 24 hours.

    Your server's physical RAM:                                   7976 MB
    Remaining Memory after other services considered:             937 MB
    Apache's MaxRequestWorkers directive:                         512      <--------- Current Setting    
    Apache MPM Model:                                             prefork
    Largest Apache process (by memory):                           10 MB
[ !! ]  Your MaxRequestWorkers setting is too high.
    Your recommended MaxRequestWorkers setting (based on available memory) is between 81 and 91. <------- Acceptable Range (10% of MAX)
    Max potential memory usage:                                   5217 MB
    Percentage of TOTAL RAM allocated to Apache:                  65.42  %
    Percentage of REMAINING RAM allocated to Apache:              556.59  %
--------------------------------------------------------------------------------
A log file entry has been made in: /var/log/Apache2buddy.log for future reference.

Last 5 entries:

2019/12/19 07:37:28 Uptime: "0d 02h 26m 52s" Model: "Prefork" Memory: "7976 MB" MaxRequestWorkers: "512" Recommended: "352" Smallest: "9.81 MB" Avg: "10.28 MB" Largest: "12.35 MB" Highest Pct Remaining RAM: "145.16%" (79.28% TOTAL RAM)
2019/12/20 07:06:41 Uptime: "0d 23h 19m 11s" Model: "Prefork" Memory: "7976 MB" MaxRequestWorkers: "512" Recommended: "91" Smallest: "9.73 MB" Avg: "9.82 MB" Largest: "10.19 MB" Highest Pct Remaining RAM: "556.59%" (65.42% TOTAL RAM)

ロケーションテーブル:

CREATE TABLE `locations` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `device_id` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT 'Device Associated with Location',
  `driver_id` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT 'Driver associated with the Device',
  `packet_type` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '1=Login\\n2=Heartbeat\\n3=Ping\\n4=Alarm',
  `latlng` point DEFAULT NULL COMMENT 'Longitude, Latitude',
  `lng` decimal(10,7) NOT NULL DEFAULT '0.0000000' COMMENT 'Longitude',
  `lat` decimal(10,7) NOT NULL DEFAULT '0.0000000' COMMENT 'Latitude',
  `device_time` datetime DEFAULT NULL,
  `server_time` datetime DEFAULT NULL,
  `imei` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `satellite` tinyint(3) unsigned NOT NULL DEFAULT '0',
  `speed` tinyint(3) unsigned NOT NULL DEFAULT '0',
  `acc` tinyint(3) unsigned NOT NULL DEFAULT '0',
  `heading` smallint(5) unsigned NOT NULL DEFAULT '0',
  `gsm_mcc` varchar(10) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'Mobile Country Code',
  `gsm_mnc` varchar(10) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'Mobile Network Code',
  `gsm_lac` varchar(10) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'Location Area Code',
  `gsm_cid` varchar(10) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'Cell Tower ID',
  `gsm_signal` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT 'GSM Signal Percentage',
  `battery_level` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT 'Battery Level Percentage',
  `alarm_code` varchar(5) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'Alarm Code sent by GPS Device',
  `raw_data` varchar(300) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `raw_json` varchar(3000) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `status` tinyint(3) unsigned NOT NULL DEFAULT '1' COMMENT '0=Not Active\\n1=Active\\n2=Deleted',
  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  PRIMARY KEY (`id`),
  KEY `locations_device_id_index` (`device_id`),
  KEY `locations_status_index` (`status`),
  KEY `locations_created_at_index` (`created_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci

旅行表

CREATE TABLE `trips` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `device_id` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT 'Device Associated with Trip',
  `last_location_id` bigint(20) NOT NULL DEFAULT '0' COMMENT 'Last Location associated with the Trip Date',
  `trip_date` date NOT NULL,
  `items` longtext COLLATE utf8mb4_unicode_ci COMMENT 'Trips with points',
  `points` longtext COLLATE utf8mb4_unicode_ci COMMENT 'Received points',
  `is_place` tinyint(1) unsigned NOT NULL DEFAULT '1' COMMENT 'When enabled, Need to get places',
  `is_fetch` tinyint(1) unsigned NOT NULL DEFAULT '1' COMMENT 'When enabled, Need to fetch points from locations table',
  `status` tinyint(3) unsigned NOT NULL DEFAULT '1' COMMENT '0=Not Active\\n1=Active\\n2=Deleted',
  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  KEY `trips_device_id_index` (`device_id`),
  KEY `trips_trip_date_index` (`trip_date`),
  KEY `trips_is_place_index` (`is_place`),
  KEY `trips_is_fetch_index` (`is_fetch`),
  KEY `trips_status_index` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci

スキーマの批評

Lat/lng:ジオフェンスの実装を計画しているため、地理空間検索にポイントが必要であるため、このフィールドを維持しました。実装していません。必要ない場合は削除します。

BIGINT:デバイスは増加します。しかし、現在のところわずか400台のデバイスです。現在、小さなintを使用できることを願っています。

raw両方のフィールドが削除されます

updated_at使用したことはありません

created_at選択時に使用する現在の日付の旅行を生成します

status複合インデックスについて知らないので、実装しようとします。

トップコマンドTop command screenshot

2
jAddict

メモリの問題

_innodb_buffer_pool_size=5G_まで下げます。

システムがメモリ不足でクラッシュしているか、またはOOMキラーを使用して混乱していると思います。

MySQLの88%-しかし、Apacheはどのくらいですか? OS?他のもの? 100%に到達させないでください。 MySQLのパフォーマンスでは、スワッピングはひどいです。

ApacheのMaxRequestWorkersを下げます。

スキーマの批評

このテーブルには大量のトラフィックがあるため、ディスクフットプリントを縮小すると役立ちます。

緯度/経度:POINT(25バイト)と数値のペア(各6バイト)の両方が必要ですか?数値にそれほど多くの精度が必要ですか?参照 http://mysql.rjweb.org/doc.php/latlng#representation_choices

IMEI-15桁ですか?もちろん、utf8mb4は必要ありません。 varchar(20)の15桁は17バイトになります。 DECIMAL(15)では、7になります。

GSM:mcc、mnc、lac、cidを別のテーブルに正規化し、JOINingに3バイトの_MEDIUMINT UNSIGNED_を使用できます。

BIGINT-それぞれ8バイト。デバイスとドライバーはいくつあると思いますか?

raw *-おそらくこれらを使用しませんか?テーブル内の多くのスペースを節約するために、(たとえば)不便なファイルに移動することができます。 (私はあなたがファイルを「決して」見ないだろうと想定しています。)

raw *-テーブルに保持することを選択した場合、それらを圧縮してVARBINARYを使用すると、スペースが約3分の1に縮小されます(クライアントで圧縮/解凍を実行します)。

created_at、updated_at-使用されない定型文のように聞こえます。 (各5バイト)。

ステータス-カーディナリティの低い列のインデックスを単独で作成しても、ほとんど役に立ちません。それを必要とする可能性のあるクエリはありますか?もしそうなら、おそらくcomposite(multi-column)インデックスが役立つでしょう。

これらの変更により、このテーブルが半分に縮小されると思います。

Buffer_poolキャッシング

挿入された各行は、各インデックスに挿入する必要があります。

  • PK-データの最後(1つのホットスポット)
  • device_id-デバイスごとに1つのホットスポット。デバイスはいくつですか?
  • ステータス-2?ホットスポット
  • 作成場所-事実上すべての行がこのインデックスの「終わり」に移動します。 (1)

結論:insertingの場合、実際に使用されるバッファープールはほとんどありません。 16KB(ブロックのサイズ)倍(D + 4)ここで、Dはデバイスの数です。合計:数メガバイト?

大きなSELECTはありますか?これらは、テーブルをスイープして、ブロックを行き来させます。テーブルをスキャンすると、I/Oが大量に発生する可能性があります。したがって、テーブルスキャンは避けてください。

1
Rick James

innodb_buffer_pool_size = 8GBサーバーの6Gはタイトです。 5G以下に下げます。

Apacheの512でのMaxRequestWorkersは、RAMの束を必要とし、同時接続が多すぎるMySQLを圧倒する恐れがあります。それとMySQLのmax_connections、たとえば100に下げます。

0
Rick James

1秒あたりのレート= RPS

My.cnf [mysqld]セクションで検討すべき提案

read_rnd_buffer_size=256K  # from 32M to conserve RAM and reduce handler_read_rnd_next RPS
sort_buffer_size=4M  # from 32M to conserve RAM footprint
thread_cache_size=100  # from 8 to reduce threads_created

これらの構成変更により、CPUが大幅に削減されます。パフォーマンスを向上させるためのダウンロード可能な無料のユーティリティスクリプトのネットワークプロファイルを表示します。

0
Wilson Hauck