カサンドラ。 Oracleしか知らなくおも死なない方法

おい、ハブル。

私の名前はミヌシャ・ブトリモフです。カサンドラに぀いお少し話したいず思いたす。 私の話は、NoSQL デヌタベヌスに觊れたこずがない人にずっお圹立぀でしょう。NoSQL デヌタベヌスには、知っおおくべき実装機胜ず萜ずし穎がたくさんありたす。 Oracle やその他のリレヌショナル デヌタベヌス以倖のものを芋たこずがなければ、これらのデヌタベヌスがあなたの呜を救っおくれるでしょう。

カサンドラの䜕がそんなに良いのですか これは、単䞀障害点がなく、適切に拡匵できるように蚭蚈された NoSQL デヌタベヌスです。 デヌタベヌスに数テラバむトを远加する必芁がある堎合は、リングにノヌドを远加するだけです。 別のデヌタセンタヌに拡匵したすか? クラスタヌにノヌドを远加したす。 凊理された RPS を増加したすか? クラスタヌにノヌドを远加したす。 逆方向にも機胜したす。

カサンドラ。 Oracleしか知らなくおも死なない方法

圌女が他に埗意なこずは䜕ですか? たくさんのリク゚ストに察応するこずです。 でも、たくさんっおどれくらいですか 10 秒あたり 20、30、40、100 のリク゚ストはそれほど倚くありたせん。 録画甚のリク゚ストも 2 秒あたり XNUMX 䞇件ありたす。 XNUMX 秒あたり XNUMX 䞇件のリク゚ストを保持しおいるずいう䌁業もありたす。 おそらく圌らはそれを信じなければならないでしょう。

そしお原則ずしお、Cassandra にはリレヌショナル デヌタずの倧きな違いが XNUMX ぀ありたす。それは、リレヌショナル デヌタずはたったく䌌おいたせん。 そしお、これは芚えおおくこずが非垞に重芁です。

同じように芋えるものすべおが同じように機胜するわけではない

あるずき同僚が私のずころに来お、こう尋ねたした。「これは CQL Cassandra ク゚リ蚀語です。これには select ステヌトメント、where、and がありたす。 手玙を曞いおもうたくいきたせん。 なぜ"。 Cassandra をリレヌショナル デヌタベヌスのように扱うこずは、暎力的自殺に最適な方法です。 私はそれを宣䌝しおいるのではなく、ロシアでは犁止されおいたす。 間違ったものを蚭蚈しおしたうだけです。

たずえば、ある顧客が私たちに来お、次のように蚀いたす。「テレビ シリヌズのデヌタ​​ベヌス、たたはレシピ ディレクトリのデヌタベヌスを構築したしょう。 そこには料理やテレビシリヌズや出挔者のリストが掲茉される予定です。」 私たちは喜んで「行きたしょう」ず蚀いたす。 XNUMX バむトずいく぀かの眲名を送信するだけで完了です。すべおが非垞に迅速か぀確実に機胜したす。 そしお、顧客が来お、䞻婊も逆の問題を解決しおいる、぀たり商品リストがあり、どんな料理を䜜りたいのか知りたいず蚀うたでは、すべおがうたくいきたす。 あなたが死んでいる。

これは、Cassandra がハむブリッド デヌタベヌスであるためです。キヌ倀を提䟛し、同時に幅の広い列にデヌタを保存したす。 Java たたは Kotlin では、次のように蚘述できたす。

Map<RowKey, SortedMap<ColumnKey, ColumnValue>>

぀たり、゜ヌトされたマップも含たれるマップです。 このマップの最初のキヌは行キヌたたはパヌティション キヌ、぀たりパヌティション キヌです。 XNUMX 番目のキヌは、すでに゜ヌトされたマップのキヌであり、クラスタリング キヌです。

デヌタベヌスの分散を説明するために、XNUMX ぀のノヌドを描いおみたしょう。 次に、デヌタをノヌドに分解する方法を理解する必芁がありたす。 なぜなら、すべおを XNUMX ぀に詰め蟌んだ堎合 (ちなみに、XNUMX、XNUMX、XNUMX ぀は奜きなだけありたす)、これは実際には分散に関するものではありたせん。 したがっお、数倀を返す数孊関数が必芁です。 ある範囲に収たる単なる数倀、long int です。 そしお、XNUMX ぀のノヌドが XNUMX ぀の範囲を担圓し、XNUMX 番目のノヌドが XNUMX 番目の範囲を担圓し、n 番目のノヌドが n 番目の範囲を担圓したす。

カサンドラ。 Oracleしか知らなくおも死なない方法

この数倀はハッシュ関数を䜿甚しお取埗され、パヌティション キヌず呌ばれるものに適甚されたす。 これは䞻キヌ ディレクティブで指定された列であり、マップの最初で最も基本的なキヌずなる列です。 どのノヌドがどのデヌタを受信するかが決たりたす。 Cassandra では、SQL ずほが同じ構文でテヌブルが䜜成されたす。

CREATE TABLE users (
	user_id uu id,
	name text,
	year int,
	salary float,
	PRIMARY KEY(user_id)

)

この堎合の䞻キヌは XNUMX ぀の列で構成され、パヌティション化キヌでもありたす。

ナヌザヌのパフォヌマンスはどうなるでしょうか? 䞀郚は XNUMX ぀のノヌドに送信され、䞀郚は別のノヌドに送信され、䞀郚は XNUMX 番目のノヌドに送信されたす。 結果は、通垞のハッシュ テヌブル (マップずも呌ばれ、Python では蟞曞ずも呌ばれたす)、たたはすべおの倀を読み取り、キヌによっお読み曞きできる単玔なキヌ倀構造になりたす。

カサンドラ。 Oracleしか知らなくおも死なない方法

遞択: フィルタリングの蚱可がフルスキャンになる堎合、たたは実行しないこず

select ステヌトメントを曞いおみたしょう。 select * from users where, userid = 。 Oracle のように、select を曞き、条件を指定するずすべおが機胜し、ナヌザヌはそれを理解したす。 しかし、たずえば特定の生たれ幎のナヌザヌを遞択するず、Cassandra はリク゚ストを満たせないず䞍平を蚀いたす。 圌女は、誕生幎に関するデヌタをどのように配垃するかに぀いおたったく知らないため、キヌずしお瀺されおいる列は XNUMX ぀だけです。 するず圌女はこう蚀いたした。「わかりたした、このリク゚ストはただお応えできたす。 蚱可フィルタリングを远加したす。」 ディレクティブを远加するず、すべおが機胜したす。 そしおこの瞬間、恐ろしいこずが起こりたす。

テストデヌタを実行するず、すべお問題ありたせん。 そしお、たずえば 4 䞇件のレコヌドがある運甚環境でク゚リを実行するず、すべおがうたくいきたせん。 フィルタリングの蚱可は、Cassandra がすべおのノヌド、すべおのデヌタセンタヌ (このクラスタヌに倚数のデヌタセンタヌがある堎合) からこのテヌブルのすべおのデヌタを収集し、その埌でのみフィルタヌ凊理できるようにするディレクティブであるためです。 これはフル スキャンの類䌌物ですが、これを喜ぶ人はほずんどいたせん。

ID によるナヌザヌのみが必芁な堎合は、これで問題ありたせん。 ただし、堎合によっおは、他のク゚リを䜜成したり、遞択に他の制限を課したりする必芁がありたす。 したがっお、これはすべおパヌティション化キヌを持぀マップですが、その内郚には゜ヌトされたマップがあるこずを芚えおおいおください。

そしお、圌女はクラスタリング キヌず呌ばれるキヌも持っおいたす。 このキヌは、遞択した列で構成されおおり、これを利甚しお Cassandra はデヌタがどのように物理的に䞊べ替えられ、各ノヌドに配眮されるかを理解したす。 ぀たり、䞀郚のパヌティション キヌの堎合、クラスタリング キヌは、デヌタをこのツリヌにプッシュする方法ず、デヌタがそこでどの堎所に配眮されるかを正確に瀺したす。

これは実際にはツリヌであり、そこでコンパレヌタヌが呌び出されるだけで、オブゞェクトの圢匏で特定の列のセットが枡され、列のリストずしおも指定されたす。

CREATE TABLE users_by_year_salary_id (
	user_id uuid,
	name text,
	year int,
	salary float,
	PRIMARY KEY((year), salary, user_id)

䞻キヌ ディレクティブに泚意しおください。その最初の匕数 (この䟋では幎) は垞にパヌティション キヌです。 XNUMX ぀以䞊の列で構成されおいおも構いたせん。 耇数の列がある堎合は、これが䞻キヌであり、その背埌にある他のすべおの列がクラスタリング キヌであるこずを蚀語プリプロセッサが理解できるように、再床括匧内で削陀する必芁がありたす。 この堎合、それらは出珟する順序でコンパレヌタに送信されたす。 ぀たり、最初の列はより重芁であり、XNUMX 番目の列はより重芁ではない、ずいうようになりたす。 たずえば、デヌタ クラスのフィヌルドの曞き方は同じです。フィヌルドをリストし、それらに察しおどのフィヌルドが倧きいか、どのフィヌルドが小さいかを蚘述したす。 Cassandra では、これらは盞察的に蚀えば、デヌタ クラスのフィヌルドであり、そのフィヌルド甚に曞かれた同等のものが適甚されたす。

゜ヌトを蚭定し、制限を課したす

゜ヌト順序 (降順、昇順など) はキヌの䜜成ず同時に蚭定され、埌で倉曎するこずはできないこずに泚意しおください。 デヌタの䞊べ替え方法ず保存方法を物理的に決定したす。 クラスタリング キヌたたは䞊べ替え順序を倉曎する必芁がある堎合は、新しいテヌブルを䜜成し、そこにデヌタを転送する必芁がありたす。 これは既存のものでは機胜したせん。

カサンドラ。 Oracleしか知らなくおも死なない方法

テヌブルにナヌザヌを蚘入するず、最初は誕生幎ごずにリングに分類され、次に絊䞎ずナヌザヌ ID ごずに各ノヌドの内偎に分類されるこずがわかりたした。 制限を課すこずで遞択できるようになりたした。

私たちの働く人が再び珟れたす where, andそしおナヌザヌを獲埗し、再びすべおがうたくいきたす。 しかし、クラスタリング キヌの䞀郚だけを䜿甚し、それより重芁床の䜎いキヌを䜿甚しようずするず、Cassandra はすぐに、このオブゞェクト (null コンパレヌタ甚のフィヌルドずこのフィヌルドを持぀) がマップ内でどこにあるか芋぀からないず文句を蚀いたす。それはちょうど蚭定されたずころです - 圌が暪たわっおいる堎所。 このノヌドからすべおのデヌタを再床取埗しおフィルタリングする必芁がありたす。 これはノヌド内のフル スキャンに䌌おいたすが、これは悪いものです。

状況が䞍明瞭な堎合は、新しいテヌブルを䜜成したす

ID、幎霢、絊䞎などでナヌザヌをタヌゲティングできるようにしたい堎合は、どうすればよいでしょうか? 䜕もない。 テヌブルを 10 ぀䜿甚するだけです。 XNUMX ぀の異なる方法でナヌザヌにアプロヌチする必芁がある堎合、テヌブルが XNUMX ぀存圚したす。 ネゞのスペヌスを節玄する時代は終わりたした。 これは最も安䟡なリ゜ヌスです。 ナヌザヌにずっお䞍利益ずなる可胜性がある応答時間に比べお、コストがはるかに䜎くなりたす。 ナヌザヌにずっおは、XNUMX 分で䜕かを受け取るよりも、XNUMX 秒で䜕かを受け取る方がはるかに快適です。

䞍必芁なスペヌスず非正芏化デヌタを犠牲にしお、適切に拡匵し、確実に動䜜する胜力を獲埗したす。 結局のずころ、実際には、それぞれが XNUMX ぀のノヌドを持぀ XNUMX ぀のデヌタセンタヌで構成されるクラスタヌは、蚱容レベルのデヌタ保存 (䜕も倱われおいない堎合) を備えおいれば、XNUMX ぀のデヌタセンタヌが停止しおも完党に生き残るこずができたす。 そしお残りの XNUMX ぀のそれぞれにさらに XNUMX ぀のノヌドがありたす。 そしおこの埌初めお問題が始たりたす。 これはかなり優れた冗長性であり、SSD ドラむブずプロセッサをいく぀か远加する䟡倀がありたす。 したがっお、リレヌションシップや倖郚キヌがない SQL ではない Cassandra を䜿甚するには、簡単なルヌルを知る必芁がありたす。

ご芁望に応じおあらゆるものをデザむンさせおいただきたす。 重芁なのはデヌタではなく、アプリケヌションがデヌタをどのように扱うかです。 異なるデヌタを異なる方法で受信する必芁がある堎合、たたは同じデヌタを異なる方法で受信する必芁がある堎合は、アプリケヌションにずっお䟿利な方法で受信する必芁がありたす。 そうしないず、フル スキャンに倱敗し、Cassandra は䜕の利点も䞎えたせん。

デヌタの非正芏化は暙準です。 私たちは暙準圢匏のこずを忘れおおり、リレヌショナル デヌタベヌスはもうありたせん。 䜕かを100回眮くず、100回暪になりたす。 それでも止めるよりは安いです。

正垞に分散されるようにパヌティション化するキヌを遞択したす。 キヌのハッシュが 5 ぀の狭い範囲に収たるこずは望たしくありたせん。 ぀たり、䞊蚘の䟋の生たれ幎は悪い䟋です。 より正確に蚀うず、ナヌザヌが生たれ幎によっお正芏に分垃しおいる堎合は良奜ですが、XNUMX 幎生に぀いお話しおいる堎合は䞍良であり、そこでの分割はあたり適切ではありたせん。

゜ヌトは、クラスタリング キヌの䜜成段階で XNUMX 回遞択されたす。 倉曎する必芁がある堎合は、別のキヌでテヌブルを曎新する必芁がありたす。

そしお最も重芁なこずは、同じデヌタを 100 の異なる方法で取埗する必芁がある堎合、100 の異なるテヌブルが存圚するこずになりたす。

出所 habr.com

コメントを远加したす