web-dev-qa-db-ja.com

Mysql:テーブル内の70億レコード

Mysqlテーブルに約78億レコードを保存する必要があります。テーブルは読み取りと書き込みの両方を集中的に行います。挿入率の1時間あたり少なくとも0億2000万レコードを維持する必要があります。テーブルの検索には10秒以上かかることはありません。ユーザーがさまざまな列のプロパティに基づいて検索できるUIがあります。

主に検索されるクエリは次のようになります。

  1. select * from mytable where prop1='sip:+100008521149' and prop2='asdsa' order by event_timestamp desc limit 10;

  2. select * from mytable where prop1='sip:+100008521149' order by event_timestamp desc limit 10;

  3. 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を使用していますが、挿入速度が非常に遅く、インデックス付きパラメーターの検索中の検索はかなり高速でした。バッファプールが十分ではないようです。

質問はほとんどありません。

  1. この構成でこの種のデータをサポートすることは可能ですか?.

  2. 70億レコードの理想的で実用的なバッファプールサイズはどれくらいですか。

  3. DATA + INDEXのサイズは150GBに近づいており、レコード数はわずか2億2,000万です。ラムのTBが必要なようです。
  4. マスター/スレーブ構成で、それぞれのサーバーで読み取りと書き込みのcongifを支配的にすることを考えています。
  5. このソリューションを設計する他のより良い方法はありますか?
  6. インデックスを増やすとUI検索が向上しますが、インデックスを1つ増やすと、挿入速度が何倍も低下します。

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です。

16
Mudit bhaintwal

MYSQL DBをElasticsearchに置き換えることで、この要件を達成しました。それは速い挿入率とひどい速い検索にぴったりに見えます。さらに、Luceneのフルテキスト機能により、Luceneは完璧なツールになります。 ESの最良の部分は、ハードウェア要件が非常に低いことです。垂直方向ではなく水平方向にスケーリングします。

3
Mudit bhaintwal

クエリキャッシュをオフにします。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 *_は深刻なパフォーマンスの負担になる可能性があります。

4
Rick James

これは答えではありませんが、コメントでフォーマットすることはできません

これを試して、もっと速いかどうか確認してください。したがって、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;
2
Bernd Buffen