毎日、ツイートのユーザー 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
挿入を高速化するためのヒントをいただければ幸いです。