Mysqlテーブルに約78億レコードを保存する必要があります。テーブルは読み取りと書き込みの両方を集中的に行います。挿入率の1時間あたり少なくとも0億2000万レコードを維持する必要があります。テーブルの検索には10秒以上かかることはありません。ユーザーがさまざまな列のプロパティに基づいて検索できるUIがあります。
主に検索されるクエリは次のようになります。
select * from mytable where prop1='sip:+100008521149' and prop2='asdsa' order by event_timestamp desc limit 10;
select * from mytable where prop1='sip:+100008521149' order by event_timestamp desc limit 10;
select * from mytable where prop2='asdsa' order by event_timestamp desc limit 10;
現在、テーブルには2つのインデックスがあります。
1- idx_1(prop1,event_timestamp)
2- idx_2(prop2,event_timestamp)
InnoDBの設定は次のとおりです。
innodb_buffer_pool_size = 70G
innodb_log_file_size = 4G
innodb_io_capacity=2000
innodb_io_capacity_max=6000
innodb_lru_scan_depth=2000
innodb_flush_log_at_trx_commit=2
innodb_log_buffer_size=16M
innodb_thread_concurrency = 0
innodb_read_io_threads = 64
innodb_write_io_threads = 64
innodb_autoinc_lock_mode = 2
bulk_insert_buffer_size=33554432
query_cache_type=1
query_cache_size=64M
innodb_flush_neighbors=0
expire_logs_days=10
max-connections=500
long_query_time = 5
read_buffer_size=16M
sort_buffer_size=16M
read_rnd_buffer_size=16M
innodb_doublewrite = 0
innodb_flush_method=O_DIRECT
Machine's RAM size is 99 GB.
一度起動したシステムは高速でしたが、記録が2億2000万に達すると、パフォーマンスが大幅に低下します。 LOAD INFILEを使用していますが、挿入速度が非常に遅く、インデックス付きパラメーターの検索中の検索はかなり高速でした。バッファプールが十分ではないようです。
質問はほとんどありません。
この構成でこの種のデータをサポートすることは可能ですか?.
70億レコードの理想的で実用的なバッファプールサイズはどれくらいですか。
PADTE:1
Q-テーブルはRAMよりもはるかに大きいですよね? buffer_poolを十分に大きくすることはできません。ramよりも小さくする必要があります。そうしないと、パフォーマンスが低下します。
A- RAMサイズは100GB、バッファプールは70Gです。はい。データサイズがRAMより大きすぎます。
Q- SHOW CREATETABLEを提供してください。調査する必要のある問題がいくつかあります。 (データ型、フィールドサイズなど)
A-すべてのフィールドは文字列型です。すべてにvarchar(127)を使用しました。 PKは自動生成されたidbigint(20)です。
Q- LOAD DATA INFILEにはいくつのレコードがありますか?テーブルに直接ロードしますか? LOADはどのくらいの頻度ですか?
A-1ファイルあたり100000レコード。複数のスレッドがCSVファイルからDBにデータを読み込んでいます。最初の移行では、6億5000万レコードまで継続的にロードする必要があります。その後、頻度は15分あたり約に減少します。
Q-マスター+スレーブ:すべての書き込みはスレーブでも実行されることに注意してください。読み取りが多い場合は、複数のスレーブが読み取りを分散し、それによってある程度のスケーリングが行われます。
A- 現在、MASTER/SLAVEアプローチでテストしています。
MYISAMを使用し、インデックスを使用せずにMASTERを作成しました。挿入にはMASTERが使用されます。 INNODBと2つのインデックスを持つスレーブ。検索が実行されます。どちらも異なるマシンであり、RAMまたはCPUを共有していません。アプリケーションは3番目のマシンにあります。
Q-スピニングドライブはありますか?またはSSD? A-確認方法は?
Q-あなたの行はかなり大きいようです。 TEXTまたはBLOBはありますか?その場合、SELECT *はパフォーマンスに重大な負担をかける可能性があります。
A-はい、行には50列ありますが、データは約15〜20列です。すべてのフィールドが任意の量の英数字データを保持できるため、データ型のサイズを縮小することはできません。すべてTEXTSnoBLOBSです。
MYSQL DBをElasticsearchに置き換えることで、この要件を達成しました。それは速い挿入率とひどい速い検索にぴったりに見えます。さらに、Luceneのフルテキスト機能により、Luceneは完璧なツールになります。 ESの最良の部分は、ハードウェア要件が非常に低いことです。垂直方向ではなく水平方向にスケーリングします。
クエリキャッシュをオフにします。INSERT
が発生するたびに、QC内のすべてのエントリを削除する必要があります。これは1秒間に5555回です。
_query_cache_type = 0
query_cache_size = 0
_
最初のクエリにはINDEX(prop1, prop2, event_timestamp)
が必要です。 (prop1とprop2は交換できます。)
その追加されたインデックスを使用すると、3つのクエリのそれぞれがインデックス内の10行以下にアクセスし、データへのランダム(?)フェッチを10回以下実行します。最悪の場合、それは約11ディスクヒットにすぎません。そして、@ Berndの「遅延評価」はそれをさらに良くすることはありません。
テーブルはRAMよりはるかに大きいですよね? buffer_poolを十分に大きくすることはできません-それはramより小さくなければなりません、さもなければパフォーマンスsuffers。
_SHOW CREATE TABLE
_を提供してください。調査する必要のある問題がいくつかあります。 (データ型、フィールドサイズなど)
_LOAD DATA INFILE
_にはいくつのレコードがありますか?テーブルに直接LOAD
しますか? LOAD
はどのくらいの頻度ですか?
マスター+スレーブ:すべての書き込みはスレーブでも実行されることに注意してください。読み取りが多い場合、複数のスレーブがreadsを分散し、それによってある程度のスケーリングが得られます。
回転するドライブはありますか?またはSSD?
あなたの列はかなり大きいようです。 TEXTs
またはBLOBs
はありますか?もしそうなら、_SELECT *
_は深刻なパフォーマンスの負担になる可能性があります。
これは答えではありませんが、コメントでフォーマットすることはできません
これを試して、もっと速いかどうか確認してください。したがって、MySQLは穴の行をIDのみで並べ替えてはなりません(主キー)
SELECT r.*
FROM (
SELECT id
FROM mytable
WHERE
prop1='sip:+100008521149'
AND
prop2='asdsa'
ORDER BY event_timestamp DESC
LIMIT 10
) AS r
LEFT JOIN mytable m ON m.id =r.id
ORDER BY r.event_timestamp DESC;