2012-04-25 31 views
20

データベースに非常に速く(理想的には30分未満ですが速い方が良い)大量のデータ(50億行以上)をロードする必要があり、最近postgresqlを調べるよう提案されました(失敗しましたmysqlとhbase/cassandraを見ていました)。私の設定では、多くのデータを生成するクラスタ(現在は8台のサーバ)があり、クラスタ内の各マシンでデータベースをローカルで素早くローカルに実行し、最後に(またはデータを生成して)一緒に合併した。データはどの順序でもないので、特定のサーバーが(最終的にはそこにある限り)オンには関係ありません。自動シャーリングpostgresql?

私の質問は、PostgreSQLの自動シャーディングについて学ぶ良いチュートリアルや場所があるかどうかです(私はsykpeが自動シャーディングをしているがチュートリアルはしていないような企業の結果を見つけました。私がしようとしていることは可能ですか?データが順不同であるため、自動増分ID番号を使用するつもりでしたが、データがマージされた場合にコンフリクトが発生しますか(これはもう大きな問題ではありません)。

更新:私が尋ねていた自動インクリメントの矛盾の問題は、以下のようなFrankの考えでは解消されました。質問は基本的に今、私はどのように自動シャーディングについて学ぶことができ、複数のサーバーへのデータの分散アップロードをサポートしますか?ここで

+1

私は5分未満でpostgresデータベースに1000万行をロードしました。これは、単一のシャードにデータをロードするとき、これが非常に重要なリソースであることを自信を持って伝えます:http:// www .postgresql.org/docs/8.1/static/populate.htmlこれも有望そうです:http://pgbulkload.projects.postgresql.org/ –

+9

'自動インクリメントID番号を使用しようとしていました。データはマージされますか? '10だけインクリメントし、異なるオフセットから開始します。サーバー1はID 1,11,21,31を使用します。サーバー2はID 2,12,22,32を使用します –

+0

@FrankFarmerリンクと素晴らしいアイデアを再ありがとう:ありがとう。私は複雑さのいくつかを取り除くと思う、私は質問がオートシャーディングと分散アップロードにのみ関連していると思います。 – Lostsoul

答えて

2

に役立つかもしれないいくつかされています

  • DB各サーバー上には、そのサーバーのユニークな特性を備えた小型のメタデータテーブルを持っている必要があります。それはどのサーバであるかなど。サーバーは順次番号を付けることができます。そのテーブルの内容とは別に、各サーバのスキーマを可能な限り似ているようにすることが賢明でしょう。

  • 数十億の行では、bigint ids(またはUUIDなど)が必要になります。 bigintsを使用すると、各サーバーに十分な範囲を割り当てて、その順序を使用してそれを使用することができます。例えば。サーバー1が1.1000000000000000、サーバー2が1000000000000001から2000000000000000になります。

  • データが単純なデータポイント(正確に10個の計測器から毎秒の温度を読み取るようなもの)であれば、列が(time timestamp, values double precision[])のテーブルではなく、より正確な(time timestamp, instrument_id int, value double precision)です。これは、効率化のための明示的な非正規化です。 (。Iこのスキームと私自身の経験についてblogged

1

私は手元にチュートリアルを持っているが、ここでは可能な解決策の概要ですありません申し訳ありません:

  • ロードあなたの1 8最適な負荷速度のためにサーバ
  • のそれぞれのPGインスタンスへのデータは、挿入を使用していないが、データがロードされるとCOPY方法
  • 、一つに8つのデータベースを組み合わせて使用​​しないでください。すでに述べた代わりに、

一度にすべてのデータベースを照会するための単一の文(またはあなたのクエリを満たすために右のいずれか)を起動するために plProxyを使用して、キーが問題になる可能性があります。重複しないシーケンスやUUID、または文字列接頭辞付きのシーケンス番号を使用してください。解決するのは難しくありません。

サーバーの1つでCOPYテストを開始し、30分の目標にどれだけ近づいているかを確認する必要があります。あなたのデータが重要ではなく、最近のPostgreSQLバージョンを持っているなら、より速く(衝突安全ではない)unlogged tablesを試してみてください。楽しいプロジェクト、幸運のように聞こえる。

+0

ありがとう、私はplProxyを見ていきます。本当に興味深いです。私はそれを試してみると、テーブルに記録されていません。 – Lostsoul

14

最初に、生成されたデータをクラスタからリレーショナルデータベースに直接挿入する必要がありますか?とにかく最後にそれをマージしても構わないので、どうしてデータベースに挿入するのはどうですか?あなたの立場では、クラスタノードにフラットファイル(おそらくgzip'd CSVデータ)を書き込ませてもらいます。私は一括インポートし、pg_bulkloadのようなツールを使用してそのデータをマージします。

リレーショナルデータベースに直接挿入する必要がある場合:これは、PgPool-IIと(特に)PgBouncerの一部です。 PgBouncerを異なるノード間で負荷分散するように設定すると、かなりソートされているはずです。

PostgreSQLは、データ耐久性が保証されたトランザクションデータベースです。それは、あなたが単純な方法でそれを使用すると、たくさんの小さな書き込みを行うのが遅くなることも意味します。データの耐久性、スピード、およびハードウェアのコストの間でどのようなトレードオフを実行するかを考慮する必要があります。

極端な場合、それぞれINSERTは成功裏にディスクに同期コミットされた独自のトランザクションである可能性があります。これにより、ディスクサブシステムで実行できるfsync()の数に制限される1秒あたりのトランザクション数が制限されます(バッテリバックアップRAIDコントローラなし)。特別な操作を行わず、INSERTBEGINCOMMITにラップしない場合は、これがデフォルトです。

もう1つの極端な場合は、「すべてこのデータを失うと本当に気にしない」と言って、挿入物にunlogged tablesを使用します。これは基本的に、OSのクラッシュ、データベースのクラッシュ、電力損失などの問題が発生した後に、データが安全であると判断した場合、データを破棄する権限をデータベースに与えます。

中盤は、 。これは、一度に数千レコードのCOPY負荷を行うことができます代わりにINSERTのバッチ処理のasynchronous commitgroup commitscommit_delaycommit_siblings)のいくつかの組み合わせなどの明示的なBEGINENDに包まれたグループにバッチ処理の挿入を伴います。これらのすべてが、データの耐久性をスピードから排除します。

ファースト・バルク・インサートの場合は、プライマリ・キー以外のインデックスを持たないテーブルにも挿入することを検討する必要があります。多分それはないかもしれません。一括挿入が完了したら、インデックスを作成します。これはずっと速い地獄でしょう。

+0

うわー..素晴らしい答えをありがとう。あなたの権利私は全くデータベースを必要としませんが、私はそれを使って他のワーカーノードとエンドデータを共有しようとしています。だから私の最初のプロセスはたくさんのデータを生成しますが、2番目のプロセスはクラスターを使って以前のデータセットに対してデータを分析します(別の日に同じように生成されます)。私は中間地盤かもっと極端な未記録テーブルが必要かどうかはわかりません。なぜなら、データベースが死んでもデータを使用すれば死んだときを知り、処理をやり直すことができるからです。遅くなったら私のデッドラインを逃すだろう。 – Lostsoul

+0

私の場合、データをファイルとして保存してアップロードすれば意味があると思いますか?私はデータベース内で解析して最終的に分析していましたが、私が処理している間にプログラムを送信するスレッドを作成するかもしれませんが、ローカルで書いて一括アップロードするほうが速ければそれに、テーブルにはインデックスがありません(私の列は文字列としてロードするint型のものですが、もう1つはLong型のID列です)。 )。他のすべての決定事項は速度のためのものです。 – Lostsoul

+0

シャードされたデータベースにデータを挿入する方法は、シャードされた形式でクエリを実行できる場合にのみ便利です。そのためのツール(PL/Proxyなど参照)がありますが、単一のDBインスタンスよりも複雑で使いにくいツールです。 OTOH、それらはずっと速くすることができます。断片を照会するのではなく、データを分析する前にマージしたい場合は、フラットファイルとして書き込み、最終的なDBに挿入するだけです。 –

-1

クラスタをまたいだ自動シャーディングをサポートするmySQLを使用できます。

+2

私はあなた自身がMySQLとは別の有料製品であるMySQL Clusterを考えていると思います。 – Peeja

1

PostgreSQL自動シャーディングにはcitusを使用してください。またthis linkが役に立ちます。

関連する問題