web-dev-qa-db-ja.com

A Cassandraデータモデルの設計におけるベストプラクティスは何ですか?

そして、避けるべき落とし穴は何ですか?取引の中断はありますか?たとえば、Cassandra=データをエクスポート/インポートするのは非常に難しいと聞いています。

ところで、Cassandraの良いチュートリアルを見つけるのは非常に難しいです。私が持っている唯一のチュートリアルは http://arin.me/code/wtf-is-a-supercolumn-cassandra-data-model はまだきれいです基本的な。

ありがとう。

63
Jerry

私にとって、主なことは、OrderedPartitionerとRandomPartitionerのどちらを使用するかを決定することです。

RandomPartitionerを使用する場合、範囲スキャンはできません。つまり、古いデータのクリーニングを含め、アクティビティの正確なキーを知っている必要があります。

したがって、大量のチャーンがある場合、どのキーを挿入したかを正確に知る魔法の方法がない限り、ランダムパーティショナーを使用すると、簡単に「失う」ことができ、ディスクスペースリークが発生し、最終的にはすべてのストレージを消費します。

一方、注文されたパーティショナーに「AとBの間の列ファミリXにはどのキーがありますか」と尋ねることができます-そして、それはあなたに教えます。その後、それらをクリーンアップできます。

ただし、欠点もあります。 As Cassandraは自動ロードバランシングを行いません。順序付けられたパーティショナーを使用する場合、すべてのデータはたぶん1つまたは2つのノードで終わり、他のノードではないことになります。リソースを無駄にします。

これには簡単な答えはありませんが、キーの先頭に短いハッシュ値(他のデータソースから簡単に列挙できるもの)を置くことによって「両方の世界のベスト」を得ることができる場合を除いてユーザーIDの16ビット16進ハッシュの例-4桁の16進数字が得られ、その後に実際に使用したいキーが続きます。

次に、最近削除されたユーザーのリストがある場合、それらのIDと範囲スキャンをハッシュして、それらに関連するものをすべてクリーンアップできます。

次のトリッキーなビットはセカンダリインデックスです-Cassandraにはありません-XをYで検索する必要がある場合は、両方のキーの下にデータを挿入するか、ポインターが必要です。同様に、これらのポインターは、それらが指すものが存在しない場合にクリーンアップする必要があるかもしれませんが、これに基づいてものを照会する簡単な方法はないため、アプリはただ覚えておく必要があります。

また、アプリケーションのバグにより、忘れていた孤立したキーが残る場合があり、dbのすべてのキーを定期的にスキャンするガベージコレクターを作成しない限り、簡単にそれらを検出する方法はありません(これには時間がかかります-ただし、不要になったものを確認するために、チャンクで行うことができます。

これは実際の使用法に基づいたものではなく、研究中に私が見つけたものです。プロダクションではCassandraを使用しません。

編集:Cassandra=トランクにセカンダリインデックスがあります。

41
MarkR

これはコメントとして追加するには長すぎたため、問題のリストの返信から誤解を解消するには:

  1. 任意のクライアントが任意のノードに接続できます。最初に選択したノード(またはロードバランサー経由で接続したノード)がダウンした場合は、別のノードに接続します。さらに、クライアントが書き込み自体を指示できる「ファットクライアント」APIが利用可能です。例は http://wiki.Apache.org/cassandra/ClientExamples にあります

  2. サーバーが無期限にハングアップするのではなく応答しない場合のタイムアウトは、過負荷のRDBMSシステムを扱ったほとんどの人が望んでいた機能です。 Cassandra RPCタイムアウトは設定可能です。必要に応じて、数日に設定し、代わりに無期限にハングアップに対処できます。:)

  3. 多重削除や切り捨てのサポートはまだないことは事実ですが、これら両方のパッチがレビューされています。

  4. クラスターノード間で負荷のバランスを維持することには明らかにトレードオフがあります。物事を維持しようとするバランスが完全になればなるほど、より多くのデータ移動が行われますが、これは無料ではありません。デフォルトでは、Cassandraクラスター内の新しいノードは、トークンリング内の最適な位置に移動して、不均一性を最小限に抑えます。実際には、これはうまく機能することが示されており、クラスターつまり、倍増が最適であるというのはそれほど真実ではありません。これは http://wiki.Apache.org/cassandra/Operations で詳しく説明されています。

17
jbellis

取引の中断はありますか?必ずしもブレーカーに対処する必要はありませんが、知っておくべきこと

  1. クライアントは最も近いノードに接続します。このアドレスは事前に知っておく必要があり、他のすべてのCassandraプロキシされたノードとのすべての通信。自分自身をホストするよりも多くのデータをプロキシするb。ノードがダウンした場合、クライアントは無力で、読み取りも書き込みもクラスター内のどこにも書き込みができません。

  2. Cassandraは、「書き込みは決して失敗しない」と主張していますが、少なくとも話す時点では失敗します。ターゲットデータノードが遅くなると、リクエストはタイムアウトし、書き込みは失敗します。ノードが応答しなくなる理由:ガベージコレクターの起動、圧縮プロセスなど、すべての場合、すべての書き込み/読み取り要求は失敗します。従来のデータベースでは、これらの要求は比例して遅くなりますが、Cassandra失敗するだけです。

  3. マルチGETはありますが、マルチデリートはなく、ColumnFamilyも切り捨てられません。

  4. 新しい空のデータノードがクラスターに入ると、キーリング上の1つの隣接ノードからのデータの一部のみが転送されます。これは、不均一なデータ分散と不均一な負荷につながります。ノードの数を常に2倍にすることで修正できます。また、トークンを手動で追跡し、賢明に選択する必要があります。

7
Igor Katkov

別のチュートリアルはこちらです: http://blog.evanweaver.com/articles/2009/07/06/up-and-running-with-cassandra/

7
Alice

Cassandra 1.2が最近リリースされたので、これは更新に値すると思います。

私はソーシャルゲームで過去18か月間、本番環境でCassandraを使用しています。

私の強みは、Cassandraを使用する必要があるということです。そのため、どのデータモデルをどのように使用するかを十分に理解するには、どのデータモデルを使用するかを確認するか、別のDBソリューションがより役立つかどうかを特定する必要があります。

OrderedPartitionerは、アプリケーションがキー範囲クエリに依存している場合にのみ役立ちますが、Cassandraの最も強力な機能の1つである自動シャーディングと負荷分散をあきらめます。行キー範囲クエリの代わりに、同じ行内の列名の範囲を使用して、必要な同じ機能を実装しようとします。 TL; DR 読み取り/書き込みは、これを使用してノード間で分散されません。

RandomPartioner(md5ハッシュ)およびMurmurPartitioner(つぶやきハッシュ、より良く、より高速)は、ビッグデータと高いアクセス頻度をサポートする場合に必要な方法です。放棄するのは、キー範囲クエリだけです。同じ行にあるものはすべてクラスター内の同じノードにあり、それらに対してコンパレーターと列名の範囲のクエリを使用できます。 TL; DR :適切なバランスをとるためにこれを使用します。大きなことはあきらめません。


cassandraについて知っておくべきこと:

Cassandraは最終的に一貫しています。 Cassandraは、一貫性と高可用性および優れたパーティション分割を選択しました( http://en.wikipedia.org/wiki/CAP_theorem )。しかし、cassandraから一貫性を得ることができます。それは、読み取りと書き込みを行う際の一貫性ポリシーです。 cassandraの使用について話すとき、これは非常に重要で複雑なトピックですが、ここで詳細を読むことができます http://www.datastax.com/docs/1.2/dml/data_consistency

経験則として(そして簡単にするために)私はQUORUM ConsistencyLevelで読み書きします(私のアプリでは読み取りは書き込みと同じ頻度の傾向があるため)。アプリの書き込みが非常に多く、読み取りの頻度が非常に低い場合は、1で書き込み、すべて読み取りを使用します。または、ユースケースが反対の場合(書き込みは読み取りよりもはるかに少ない頻度)、1つで読み取り、ALLで書き込みを試みることができます。一貫性が解決しようとしている場合、書き込みの一貫性レベルとしてANYを使用することは、突然変異がクラスターに到達することを保証しますが、どこにも書き込まれないことを保証するため、素晴らしいアイデアではありません。これは、私がcassandraで静かに失敗するように書いた唯一のケースです。

これらは、cassandra開発の開始を簡単にするための簡単なルールです。実稼働クラスターから可能な限りの一貫性とパフォーマンスを得るには、このトピックを一生懸命研究し、自分で実際に理解する必要があります。

エンティティ(テーブル)間の複雑な関係を備えた人間が読めるデータモデルが必要な場合、Cassandraはあなたには向かないと思います。 MySQLと、おそらくNewSQLがユースケースに役立つ場合があります。

知っておくと良いのは、大まかにcassandraがデータを保存および読み取る方法です。書き込むたびに(削除は実際にはcassandraの「tombstone」値の書き込みです)、システムは新しい値とそのタイムスタンプを新しい物理的な場所に配置します。

読むとき、cassandraは特定のキー/列名の場所に対するすべての書き込みをプルしようとし、検索できる最新のもの(クライアントによって指定されたタイムスタンプが最も高いもの)を返します。そのため、ノードに必要なメモリは、書き込みの頻度に直接依存します。 cassandraには、古い突然変異のクリーニングを処理する圧縮プロセスがあります。 Cassandraには、読み取り時にロケーションの最新の値で更新される内部キャッシュがあります。

SSTable(データを永続化するデータ構造)のディスク上のマージ/圧縮は、読み取りによって引き起こされる可能性がありますが、それに頼らない方が良いです。廃棄標識と期限切れ列のクリーニング(存続時間機能を使用)は、ガベージコレクターによって管理される別のメカニズムです(詳細については、GC猶予時間設定を参照してください)。


これにより、私が最後に言いたいことがあります。書き込みと読み取りがクラスター全体でバランスが取れていることを確認してください。

すべてのユーザーが非常に頻繁に単一の場所を更新する必要があると仮定しましょう。
その理論上の単一の場所を1つの行キーのみにマッピングしないでください!これにより、すべての書き込みがクラスター内の1つのノードのみに分類されます。ロックスターのsysopがあるためにすべてがダウンしない場合は、少なくともクラスターのパフォーマンスが大幅に低下します。
アドバイスは、クラスター内のすべてのノードに書き込みを分散できるように、十分な数の異なる行キーに書き込みをバケット化することです。その単一の理論上の場所のすべてのデータを取得するには、すべての「サブ行キー」でmulti_getを使用します。

例:
すべてのアクティブなhttpセッション(uuidが割り当てられている)のリストが必要です。すべてを1つの「セッション」行キーに保存しないでください。 6ノードのcassandraクラスターの行キーとして使用するのは、_sessionsです。その後、すべてのアクティブなセッションを取得するための小さな16キーmulti_getがありますが、単純なgetを使用するだけでセッションがアクティブかどうかを知ることができます(もちろんそのuidを知っている場合)。クラスターがはるかに大きい場合は、バケットキーの生成にハッシュ関数を使用できます。