7

私はnginxがPOSTリクエストを受信し、リクエストの本文をMySqlに配置する小さなPHPスクリプトを持っています。問題は、1秒あたり300のPOSTがある場合のMySqlCPU使用率が非常に高いことです。MySqlは、1秒あたり300回をはるかに超える挿入を処理できる高速なものであると期待していました。私はAmazonEC2スモールインスタンスであるAmazonLinuxを使用しています。

top - 18:27:06 up 3 days,  1:43,  2 users,  load average: 4.40, 5.39, 5.76
Tasks: 178 total,   4 running, 174 sleeping,   0 stopped,   0 zombie
Cpu(s): 24.6%us, 13.4%sy,  0.0%ni,  0.0%id,  1.1%wa,  0.0%hi,  4.9%si, 56.0%st
Mem:   1717480k total,  1640912k used,    76568k free,   193364k buffers
Swap:   917500k total,     5928k used,   911572k free,   824136k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
 7677 mysql     20   0  313m 153m 6124 S 39.0  9.2 393:49.11 mysqld
16529 nginx     20   0  157m 151m  820 R 15.2  9.0  28:36.50 nginx
29793 php       20   0 36780 3240 1896 S  2.5  0.2   0:00.34 php-fpm
29441 php       20   0 36780 3204 1892 S  2.2  0.2   0:00.78 php-fpm
29540 php       20   0 36780 3204 1900 S  2.2  0.2   0:00.82 php-fpm
29603 php       20   0 36780 3220 1892 S  2.2  0.2   0:00.61 php-fpm
29578 php       20   0 36780 3200 1900 S  1.9  0.2   0:00.42 php-fpm
29950 php       20   0 36780 3192 1900 S  1.9  0.2   0:00.48 php-fpm
30030 php       20   0 36780 3180 1888 S  1.9  0.2   0:00.08 php-fpm
30025 php       20   0 36780 3200 1888 S  1.6  0.2   0:00.11 php-fpm
29623 php       20   0 36780 3184 1892 S  1.3  0.2   0:00.49 php-fpm
29625 php       20   0 36780 3236 1900 S  1.3  0.2   0:00.46 php-fpm
29686 php       20   0 36780 3364 1900 R  1.3  0.2   0:00.51 php-fpm
29863 php       20   0 36780 3184 1892 S  1.3  0.2   0:00.23 php-fpm
30018 php       20   0 36780 3192 1892 S  1.3  0.2   0:00.19 php-fpm
29607 php       20   0 36780 3224 1900 S  1.0  0.2   0:00.42 php-fpm
29729 php       20   0 36780 3180 1888 R  1.0  0.2   0:00.41 php-fpm

これが私のPHPコードです:

<?php
    $mysqli=new mysqli("localhost", "root", "", "errorreportsraw");
    $project_id=$_REQUEST["project_id"];
    $data=$_REQUEST["data"];
    $date=date("Y-m-d H-i-s");
    $mysqli->query("insert into rawreports(date, data, project_id) values ('$date', '$data', '$project_id')")
?>

mysql_connect、mysql_pconnect、mysqli( "localhost"、...)、mysqli( "p:localhost"、...)を試しました-それでも同じです。これらの挿入を除いて、データベースに対してクエリは実行されていません。

これが私のテーブルです:

CREATE TABLE `rawreports` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `date` datetime NOT NULL,
  `data` mediumtext NOT NULL,
  `project_id` varchar(100) NOT NULL,
  PRIMARY KEY (`id`)
);

後の処理のためにPOSTデータを保存するだけで、インデックスはなく、非常にシンプルです。「データ」フィールドは、ほとんどの場合、約3キロバイトです。innodbとmyisamを試しました-それでも同じです。

これが私のSHOWPROCESSLISTで、複数の挿入以外は何もありません。

mysql> show processlist;
+---------+----------------------+-----------+-----------------+---------+------+------------------+------------------------------------------------------------------------------------------------------+
| Id      | User                 | Host      | db              | Command | Time | State            | Info                                                                                                 |
+---------+----------------------+-----------+-----------------+---------+------+------------------+------------------------------------------------------------------------------------------------------+
| 3872248 | root                 | localhost | NULL            | Query   |    0 | NULL             | show processlist                                                                                     |
| 3901991 | root                 | localhost | errorreportsraw | Query   |    0 | update           | insert into rawreports(date, data, project_id) values ('2012-05-05 17-01-37', '{"exceptions":[{"stac |
| 3902003 | root                 | localhost | errorreportsraw | Sleep   |    0 |                  | NULL                                                                                                 |
| 3902052 | root                 | localhost | errorreportsraw | Query   |    0 | update           | insert into rawreports(date, data, project_id) values ('2012-05-05 17-01-37', '{"exceptions":[{"stac |
| 3902053 | root                 | localhost | errorreportsraw | Query   |    0 | update           | insert into rawreports(date, data, project_id) values ('2012-05-05 17-01-37', '{"exceptions":[{"stac |
| 3902054 | root                 | localhost | errorreportsraw | Query   |    0 | update           | insert into rawreports(date, data, project_id) values ('2012-05-05 17-01-37', '{"exceptions":[{"stac |
| 3902055 | root                 | localhost | errorreportsraw | Query   |    0 | update           | insert into rawreports(date, data, project_id) values ('2012-05-05 17-01-37', '{"exceptions":[{"stac |
| 3902056 | root                 | localhost | errorreportsraw | Query   |    0 | update           | insert into rawreports(date, data, project_id) values ('2012-05-05 17-01-37', '{"exceptions":[{"stac |
| 3902057 | root                 | localhost | errorreportsraw | Query   |    0 | update           | insert into rawreports(date, data, project_id) values ('2012-05-05 17-01-37', '{"exceptions":[{"stac |
| 3902058 | root                 | localhost | errorreportsraw | Query   |    0 | update           | insert into rawreports(date, data, project_id) values ('2012-05-05 17-01-37', '{"exceptions":[{"stac |
| 3902059 | root                 | localhost | errorreportsraw | Query   |    0 | update           | insert into rawreports(date, data, project_id) values ('2012-05-05 17-01-37', '{"exceptions":[{"stac |
| 3902060 | root                 | localhost | errorreportsraw | Query   |    0 | update           | insert into rawreports(date, data, project_id) values ('2012-05-05 17-01-37', '{"protocol_version":" |
| 3902061 | root                 | localhost | errorreportsraw | Query   |    0 | update           | insert into rawreports(date, data, project_id) values ('2012-05-05 17-01-37', '{"exceptions":[{"stac |
| 3902062 | root                 | localhost | errorreportsraw | Query   |    0 | update           | insert into rawreports(date, data, project_id) values ('2012-05-05 17-01-37', '{"exceptions":[{"stac |
| 3902063 | root                 | localhost | errorreportsraw | Query   |    0 | update           | insert into rawreports(date, data, project_id) values ('2012-05-05 17-01-37', '{"exceptions":[{"stac |
| 3902064 | root                 | localhost | errorreportsraw | Query   |    0 | update           | insert into rawreports(date, data, project_id) values ('2012-05-05 17-01-37', '{"exceptions":[{"stac |
| 3902065 | root                 | localhost | errorreportsraw | Query   |    0 | update           | insert into rawreports(date, data, project_id) values ('2012-05-05 17-01-37', '{"exceptions":[{"stac |
| 3902066 | root                 | localhost | errorreportsraw | Query   |    0 | update           | insert into rawreports(date, data, project_id) values ('2012-05-05 17-01-37', '{"exceptions":[{"stac |
| 3902067 | root                 | localhost | errorreportsraw | Query   |    0 | update           | insert into rawreports(date, data, project_id) values ('2012-05-05 17-01-37', '{"exceptions":[{"stac |
| 3902068 | root                 | localhost | errorreportsraw | Query   |    0 | update           | insert into rawreports(date, data, project_id) values ('2012-05-05 17-01-37', '{"exceptions":[{"stac |
| 3902069 | root                 | localhost | errorreportsraw | Query   |    0 | update           | insert into rawreports(date, data, project_id) values ('2012-05-05 17-01-37', '{"exceptions":[{"stac |
| 3902070 | root                 | localhost | errorreportsraw | Query   |    0 | update           | insert into rawreports(date, data, project_id) values ('2012-05-05 17-01-37', '{"exceptions":[{"stac |
| 3902071 | root                 | localhost | errorreportsraw | Query   |    0 | update           | insert into rawreports(date, data, project_id) values ('2012-05-05 17-01-37', '{"exceptions":[{"stac |
| 3902072 | root                 | localhost | errorreportsraw | Query   |    0 | update           | insert into rawreports(date, data, project_id) values ('2012-05-05 17-01-37', '{"exceptions":[{"stac |
| 3902073 | root                 | localhost | errorreportsraw | Query   |    0 | update           | insert into rawreports(date, data, project_id) values ('2012-05-05 17-01-37', '{"exceptions":[{"stac |
| 3902074 | root                 | localhost | errorreportsraw | Query   |    0 | update           | insert into rawreports(date, data, project_id) values ('2012-05-05 17-01-37', '{"exceptions":[{"stac |
| 3902075 | root                 | localhost | errorreportsraw | Query   |    0 | update           | insert into rawreports(date, data, project_id) values ('2012-05-05 17-01-37', '{"exceptions":[{"stac |
| 3902076 | root                 | localhost | errorreportsraw | Query   |    0 | update           | insert into rawreports(date, data, project_id) values ('2012-05-05 17-01-37', '{"exceptions":[{"stac |
| 3902077 | root                 | localhost | errorreportsraw | Query   |    0 | update           | insert into rawreports(date, data, project_id) values ('2012-05-05 17-01-37', '{"exceptions":[{"stac |
| 3902078 | root                 | localhost | errorreportsraw | Query   |    0 | update           | insert into rawreports(date, data, project_id) values ('2012-05-05 17-01-37', '{"exceptions":[{"stac |
| 3902079 | root                 | localhost | errorreportsraw | Query   |    0 | update           | insert into rawreports(date, data, project_id) values ('2012-05-05 17-01-37', '{"exceptions":[{"stac |
| 3902080 | root                 | localhost | errorreportsraw | Query   |    0 | update           | insert into rawreports(date, data, project_id) values ('2012-05-05 17-01-37', '{"exceptions":[{"stac |
| 3902081 | root                 | localhost | errorreportsraw | Query   |    0 | update           | insert into rawreports(date, data, project_id) values ('2012-05-05 17-01-37', '{"exceptions":[{"stac |
| 3902082 | root                 | localhost | errorreportsraw | Query   |    0 | update           | insert into rawreports(date, data, project_id) values ('2012-05-05 17-01-37', '{"exceptions":[{"stac |
| 3902083 | root                 | localhost | errorreportsraw | Query   |    0 | update           | insert into rawreports(date, data, project_id) values ('2012-05-05 17-01-37', '{"exceptions":[{"stac |
| 3902084 | root                 | localhost | errorreportsraw | Query   |    0 | update           | insert into rawreports(date, data, project_id) values ('2012-05-05 17-01-37', '{"exceptions":[{"stac |
| 3902085 | root                 | localhost | errorreportsraw | Query   |    0 | update           | insert into rawreports(date, data, project_id) values ('2012-05-05 17-01-37', '{"exceptions":[{"stac |
| 3902086 | root                 | localhost | errorreportsraw | Query   |    0 | update           | insert into rawreports(date, data, project_id) values ('2012-05-05 17-01-37', '{"exceptions":[{"stac |
| 3902087 | unauthenticated user | localhost | NULL            | Connect | NULL | Reading from net | NULL                                                                                                 |
+---------+----------------------+-----------+-----------------+---------+------+------------------+------------------------------------------------------------------------------------------------------+
39 rows in set (0.00 sec)

サーバーにまだプレッシャーがかかっているときに同じ挿入を手動で行った場合のプロファイルは次のとおりです。

set profiling=1;
insert into rawreports(date, data, project_id) values('2012-05-04 00:58:08','[3000-chars-data-here]','5');
show profile ALL for query 1;

Status                          Duration    CPU_user    CPU_system  Context_voluntary    Context_involuntary    Block_ops_in    Block_ops_out   Messages_sent   Messages_received   Page_faults_major   Page_faults_minor   Swaps   Sourc
starting                        0.000231    0.000000    0.000000    0                    0                      0               0               0               0                   0                   0                   0       NULL    NULL    NULL
checking permissions            0.000030    0.000000    0.000000    0                    0                      0               0               0               0                   0                   0                   0       check_access    sql_parse.cc    4745
Opening tables                  0.000057    0.001000    0.000000    0                    0                      0               0               0               0                   0                   0                   0       open_tables     sql_base.cc     4836
System lock                     0.000030    0.000000    0.000000    0                    0                      0               0               0               0                   0                   0                   0       mysql_lock_tables       lock.cc 299
init                            0.000037    0.000000    0.000000    0                    0                      0               0               0               0                   0                   0                   0       mysql_insert    sql_insert.cc   721
update                          0.075716    0.001999    0.011998    166                  2                      0               0               0               0                   0                   0                   0       mysql_insert    sql_insert.cc   806
Waiting for query cache lock    0.000087    0.000000    0.000000    0                    0                      0               0               0               0                   0                   0                   0       lock    sql_cache.cc    552
update                          0.000037    0.000000    0.000000    0                    0                      0               0               0               0                   0                   0                   0       NULL    NULL    NULL
end                             0.000024    0.000000    0.000000    0                    0                      0               0               0               0                   0                   0                   0       mysql_insert    sql_insert.cc   1049
query end                       0.000042    0.000000    0.000000    0                    0                      0               0               0               0                   0                   0                   0       mysql_execute_command   sql_parse.cc    4434
closing tables                  0.000031    0.000000    0.001000    0                    0                      0               0               0               0                   0                   0                   0       mysql_execute_command   sql_parse.cc    4486
freeing items                   0.000126    0.000000    0.000000    0                    1                      0               0               0               0                   0                   0                   0       mysql_parse     sql_parse.cc    5634
logging slow query              0.000030    0.000000    0.000000    0                    0                      0               0               0               0                   0                   0                   0       log_slow_statement      sql_parse.cc    1460
cleaning up                     0.000024    0.000000    0.000000    0                    0                      0               0               0               0                   0                   0                   0       dispatch_command        sql_parse.cc    1416

MySql5.5.20を使用しています。InnoDBとMyISAMの両方を試しました-どちらも同じです。
これが私のiostat出力です:

# iostat -x
Linux 3.2.12-3.2.4.amzn1.i686 05/15/2012      _i686_  (1 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          23.67    0.03   18.39    4.09   52.87    0.95

Device:         rrqm/s   wrqm/s     r/s     w/s   rsec/s   wsec/s avgrq-sz avgqu-sz   await  svctm  %util
xvdap1            0.00     1.74    0.03    0.78     1.50    25.12    32.85     0.01   14.03   5.92   0.48
xvdap3            0.00     0.00    0.01    0.01     0.05     0.08    10.47     0.00    5.72   1.09   0.00
xvdf              0.40    18.59   23.14  117.55   753.12  3465.25    29.98     0.53    3.74   2.38  33.46

最も明白なことは、それらを1つずつではなく、すべて一緒にバッチ挿入してコミットすることです。しかし、すべての挿入は個別のPOSTリクエストであり、個別のPHPスクリプトの実行であるため、これを行うことはできません。それらはすべて同時に実行され、互いに干渉しません。

非常に単純なタスクのようですが、私のCPUは実際に何をしているのでしょうか。mysql、php、linuxの経験はあまりありません。たぶん私は何かが恋しいです。アイデアをありがとう!

4

11 に答える 11

6

「後の」処理とは、おそらく1時間後または1日後を意味しますか?その場合は、1時間に1回程度ローテーションするCSVファイルに情報を書き込みます。その後、「後の」処理を行う必要がある場合は、を使用してファイルをMySQLにロードできます。 LOAD DATA INFILE

http://dev.mysql.com/doc/refman/5.1/en/load-data.html

LOAD DATA INFILEで数百MBの情報を1分以内にロードしました。この方法は、Web応答を高速化するための優れた方法です。

于 2012-05-11T04:33:54.723 に答える
2

プレーンテキストのログファイルまたはNoSQLデータベースを使用する方が良いオプションであることに同意しますが、MySQLを使用する場合、ボトルネックはPHPだと思います。持続的接続とプリペアドステートメントを使用していますか?そうでなければ、それは大きな時間の無駄です。

hsockモジュールnginxを使用してMySQLに直接接続してみてください。

また、EC2スモールインスタンスのI/Oパフォーマンスは良好ではないことに注意してください。1秒あたり300件の投稿をサポートするために必要な種類のI/Oパフォーマンスを得るには、ラージにアップグレードする必要があります。

于 2012-05-10T06:59:44.197 に答える
2

そのPHPコードをループで実行していますか?1つのクエリに一度に複数の行を挿入できます。これにより、CPUの負荷を軽減できる場合があります。あなたがする必要があるのは、次のような値のコンマ区切りのリストを提供することです。

insert into rawreports(date, data, project_id) values (('$date1', '$data1', '$project_id1'),('$date2', '$data2', '$project_id2'), .....)")

また、ループで実行している場合は、new mysqli()反復ごとにを繰り返す必要はありません。

于 2012-05-04T19:02:23.937 に答える
2

インデックスなし、

それは完全に真実ではありません。
そもそもインデックスを削除します。
ログタイプのテーブルでは、意味がありません。

ちなみに、テキストログも使用できます。後の処理用。

詳細情報を取得するには、サーバーに通常の負荷がかかっているときにmysqlコンソールから次のコマンドを実行します。

> SET profiling = 1;
> INSERT an example query
> SHOW PROFILE ALL

また、ばかげてみてください

SHOW PROCESSLIST;

これは疑わしいことに有用なものを明らかにしますが、少なくとも試す価値があります

于 2012-05-05T11:06:28.410 に答える
2

MySQLに直接データを挿入することは使用しないでください。代わりに、2つのcsvファイルを作成します。言っeven_rawreports.csvodd_rawreports.csv。これで、偶数時間(2:00または2:59の間)にすべてのPOSTリクエストをログインし続け、even_rawreports.csv奇数時間にログインしodd_rawreports.csvます。

even_rawreports.csv1時間ごとに実行され、奇数時間と偶数時間で読み取るcronジョブを作成しodd_rawreports.csvます。

cronでは次のクエリを使用して、1つのクエリでCSVファイルから直接mysqlにデータをロードします。

LOAD DATA INFILE 'even_rawreports.csv' INTO TABLE rawreports (col1,col2,...)
    FIELDS TERMINATED BY '|' OPTIONALLY ENCLOSED BY '"';
于 2012-05-11T06:32:37.287 に答える
2

すべての回答から、分析後に問題に対処するために次の選択肢があることがわかります。

1)物理ノードでホストされているすべての仮想サーバー間でHDD iopsが共有されるため、AmazonEC2またはクラウドサーバーの書き込み速度は通常の専用サーバーよりも遅くなります。したがって、DB用に別のマシンを用意することは良い考えであり、AmazonSimpleDBを試してみることができます。試してみる価値があるはずです。

2)MySQLと比較して書き込み操作の速度が非常に速いMongoDBのような最も単純なドキュメントベースのNoSQLデータベースを使用してみることができます。私は自分のローカルマシンでそれをベンチマークし、驚くべき結果を見つけました。したがって、CSVアプローチを実行する代わりに、DBを実際にNoSQL DBに格納し、後で必要に応じて、バッチジョブを使用してリレーショナルクエリのためにデータベースをMySQLにプッシュすることができます。

3)PHPオペコード/アクセラレータを使用していない場合は、それを使用します。

しかし、MySQLは、ディスク容量の書き込み速度のために、持ちこたえて速度を落とし、CPU使用率を上げることさえあると思います...

以下の記事が役立つかどうかを確認してください:http: //kevin.vanzonneveld.net/techblog/article/improve_mysql_insert_performance/

于 2012-05-11T18:56:52.420 に答える
1

INSERT DELAYEDを試しましたか?

さまざまなクライアントから毎秒300件の投稿があると読みましたが、とにかくバンドルを使用して一度に複数の行を挿入できます。

投稿を収集して行を挿入する個別のロジック。したがって、2つのスクリプトが必要です。最初のスクリプトはすべての投稿を収集し、データをファイルに保存します。Secondは、1秒に1回定期的に実行され、すべてのデータをテーブルに挿入します。

ところで:NOW()を使用して、現在の日付を挿入-> rawreports(date、data、project_id)値に挿入(NOW()、

于 2012-05-04T21:47:24.853 に答える
1

MySQLをサポートするために別のデータベース/バイナリファイルを導入することは、最後の手段のようです。あなたがそこに着く前に、私はあなたにこれを考慮して欲しいです:

MEMORY Storage Engine定期的にメインストレージにフラッシュするテーブルを使用してテーブルを作成します。

于 2012-05-16T03:52:25.407 に答える
0

クライアントとサーバー間のバイナリ通信を利用するために、プリペアドステートメントを使用してPDOを試すことができます。

毎回パラメータを変更して実行するだけです。

サーバーへの送信のオーバーヘッドが低いことに加えて、MySQLは毎回クエリを解析する必要がないため、これはCPUの競合に役立つ可能性があります。

これを利用するには、データをバッチ処理(キューイング)する必要があります。

于 2012-05-04T19:14:44.833 に答える
0

iostatに基づくと、5.5を使用している場合、AmazonインスタンスのCPUとディスクI/Oによって制限されていると思います。一時的に高速なインスタンスに移行して、結果を測定できますか?改善の余地はあまりありません。MySQLの75ms更新フェーズは、PHPではなくMySQLがあなたを殺していることを示しています。300も限界だと驚いています。データの整合性要件はわかりませんが、MongoDBが適切に機能する可能性があり、サポートされているPHPライブラリもあります。

于 2012-05-15T13:59:26.447 に答える
0

アーカイブストレージエンジンを使用してみましたか?更新/削除/置換が必要ない場合は、そのオプションを試してください。詳細については、 http://dev.mysql.com/doc/refman/5.0/en/archive-storage-engine.htmlを参照してください。

于 2012-05-16T11:55:20.393 に答える