1

毎日、ツイートのユーザー ID から、そのユーザーが作成したツイートのツイート ID のリストへのマッピングを構築しています。使用しているストレージ エンジンは Percona xtraDB "5.1.63-rel13.4 Percona Server (GPL), 13.4, Revision 443" です。

1 秒あたりの行挿入数に関して、最大スループットには満足していません。xtraDB でツイートを処理する最大スループットは、1 秒あたり約 6000 ~ 8000 ツイートです。(たとえば、データをゼロから再構築する必要がある場合、ほぼ 1 日待つ必要があります)

ほとんどの場合、Twitter データの全量 (1 秒あたり約 4000 ~ 5000 ツイート) を使用して、これをリアルタイムで十分に行うことができます。

アプリケーションのボトルネックを MySQL InnoDB 挿入に絞り込みました。このアプリケーションでは、ディスクからフィードを読み取り、jackson で解析します (これは 1 秒あたり約 30,000 ツイートで発生します)。次に、アプリケーションはツイートのバッチで処理を進めます。これらのツイートを生成する一連の作成者について、それらを 8 つのグループに分割します (ユーザー ID モジュロ 8 による単純な分割)。グループごとにテーブルが割り当てられ、そのテーブルにデータを書き込むために 1 つのスレッドが割り当てられます。毎日、約 2,600 万人のユニーク ユーザーがこれらのツイートを生成しているため、各テーブルには約 400 万行あります。ユーザーのグループについては、読み取りと更新に 1 つのトランザクションのみを使用します。グループ サイズは実行時に調整可能です。8 ~ 64000 のさまざまなサイズを試しましたが、256 が適切なバッチ サイズであると判断しました。

私たちのテーブルのスキーマは

CREATE TABLE `2012_07_12_g0` (  `userid` bigint(20) NOT NULL,  `tweetId` longblob,  PRIMARY KEY (`userid`)) ENGINE=InnoDB DEFAULT CHARSET=utf8

tweetId は、Google snappy で圧縮されたツイート ID の長整数の圧縮リストです。

各スレッドが使用する

Select userid,tweetId from <tablename> where userid IN (....)

ユーザーIDを解決してデータをリードバックし、スレッドが使用します

INSERT INTO <tablename> (userid,tweetId) VALUES (...) ON DUPLICATE KEY UPDATE tweetId=VALUES(tweetId)

行を新しい tweetid で更新します。

さまざまな XtraDB パラメータを設定してみました

innodb_log_buffer_size = 4M
innodb_flush_log_at_trx_commit = 2
innodb_max_dirty_pages_pct = 80
innodb_flush_method = O_DIRECT
innodb_doublewrite = 0
innodb_use_purge_thread = 1
innodb_thread_concurrency = 32
innodb_write_io_threads = 8
innodb_read_io_threads = 8 
#innodb_io_capacity = 20000 
#innodb_adaptive_flushing = 1
#innodb_flush_neighbor_pages= 0"

毎日のテーブル サイズは、すべてのテーブルで約 8G であり、InnoDB には 24GB が使用されます。

私たちは以下を使用しています:

  • 6 ディスク (crucial m4 SSD、512 GB、000F ファームウェア) ソフトウェア RAID5。
  • MySQL innodb データ、SSD パーティション上のテーブル スペース
  • noatime,nodiratime,commit=60 での ext4 マウント
  • セントス6.2
  • 太陽 JDK 1.6.30

挿入を高速化するためのヒントをいただければ幸いです。

4

2 に答える 2

0

InnoDB には 24GB が与えられます

これは innodb_buffer_pool_size ということですか? メモリの量や使用している CPU については言及していません。その場合は、おそらくより大きな innodb_log_buffer_size を使用する必要があります。innodb_log_file_size の設定は何ですか? おそらく 96Mb の領域にあるはずです。

innodb_write_io_threads = 8

ext3 には複数のライターとの同時実行の問題があるという ISTR - しかし、ext4 については知りません

innodb_flush_method を変更してみましたか?

どの I/O スケジューラを使用していますか (スマート ディスク コントローラがない場合、通常は期限が最も早く、CFQ の場合もあります)。

ext4 バリアをオフにすると、スループットが向上します。これは少しリスクが高くなります。JBD2 でチェックサムが有効になっていることを確認してください。同様に、 innodb_flush_log_at_trx_commit=0 を設定すると、大幅に増加しますが、リスクが高くなります。

データをリレーショナル形式で維持することは明らかに気にならないので、noSQL データベースの使用を検討することもできます。

于 2012-07-13T09:46:29.510 に答える
0

私の最初の提案は次のとおりです。

  1. メモリ付きの RAID カードがないため、システム キャッシュの書き込みを可能にするためにinnodb_flush_method = O_DIRECT行をコメント アウトすることをお勧めします。
  2. 二重書き込みバッファを無効にしたので、 innodb_flush_log_at_trx_commitを 0 に設定することもできます。これは 2 よりも高速です。
  3. 少なくとも 1 秒の書き込みをカバーするようにinnodb_log_buffer_sizeを設定します (30K ツイートの場合、約 12Mb)。
  4. バイナリログを使用する場合 - sync_binlog = 0であることを確認してください

ハードウェア側では、書き込み速度を向上させるために、少なくとも 256Mb の RAM とバッテリー ユニット (BBU) を備えた RAID カードを試すことを強くお勧めします。SSD をサポートする RAID カードが市場に出回っています。

お役に立てれば。それがどうなるか教えてください。

于 2012-07-13T07:12:06.123 に答える