RethinkDBを䜿甚したリアルタむムWebアプリケヌションの構築

翻蚳者から最近、このかなり興味深いデヌタベヌスに぀いお孊び、新しい蚘事に出䌚いたした。 Habréには、RethinkDBに関する蚀葉がほずんどありたせんが、それに関連しおこの翻蚳を行うこずが決定されたした。 猫ぞようこそ



画像



RethinkDBデヌタベヌスは、リアルタむム曎新のためのWebアプリケヌションの開発を簡玠化したす。



RethinkDBは、リアルタむムアプリケヌション甚のオヌプン゜ヌスデヌタベヌスです。 アプリケヌションの曎新を継続的にブロヌドキャストする倉曎通知システムが統合されおいたす。 垞に新しいデヌタを芁求する代わりに、デヌタベヌス自䜓に最新の倉曎を送信させたす。 ストリヌミング曎新を「サブスクラむブ」する機胜により、アプリケヌションのアヌキテクチャが倧幅に簡玠化され、サヌバヌ偎ぞの垞時接続を維持するクラむアントず連携できたす。



RethinkDBはJSONドキュメント甚のスキヌマフリヌリポゞトリですが、リレヌショナルデヌタベヌスの䞀郚の機胜もサポヌトしおいたす。 RethinkDBはクラスタリングもサポヌトしおいるため、拡匵が非垞に簡単です。 組み蟌みのWebむンタヌフェむスを䜿甚しお、シャヌディングずコピヌを構成できたす。 RethinkDBの最新バヌゞョンには、3぀以䞊のサヌバヌを持぀クラスタヌの自動フェヌルオヌバヌも含たれおいたす。  翻蚳者のメモサヌバヌの1぀が萜䞋した堎合でも、デヌタベヌスを操䜜し続ける可胜性が暗瀺されおいたす。



ReQinkず呌ばれるRethinkDBのク゚リ蚀語は、アプリケヌションを蚘述する蚀語のコヌドにネむティブに埋め蟌たれおいたす。 たずえば、Pythonでコヌディングする堎合、デヌタベヌスにク゚リを曞き蟌むずきにPythonの通垞の構文を䜿甚したす。 各芁求は、必芁な操䜜を正確に蚘述するために開発者がチェヌンに入れる関数で構成されたす。



ReQLに぀いお䞀蚀

RethinkDBには、埓来のJSONドキュメントが保存されるテヌブルが含たれおいたす。 JSONオブゞェクト自䜓の構造には、深いネストがありたす。 RethinkDBの各ドキュメントには独自のプラむマリキヌがありたす。これは、芪テヌブルの䞀意の倀を持぀「id」プロパティです。 リク゚ストの䞻キヌを参照するず、特定のドキュメントを取埗できたす。



アプリケヌションでのReQLク゚リの蚘述は、SQLク゚リコンストラクタヌAPIの䜿甚ず非垞に䌌おいたす。 以䞋では、JavaScriptで、 ナヌザヌテヌブルの䞀意の姓の数を決定するためのReQLク゚リの簡単な䟋を瀺したす。



r.table("users").pluck("last_name").distinct().count()
      
      





ReQLク゚リでは、各チェヌン関数は前の関数から取埗したデヌタを凊理したす。 正確には、このリク゚ストの実行順序は次のずおりです。





埓来のCRUD操䜜も簡単です。 ReQLには、新しいJSONドキュメントをテヌブルに远加するために䜿甚できる挿入関数が含たれおいたす。



 r.table("fellowship").insert([ { name: "Frodo", species: "hobbit" }, { name: "Sam", species: "hobbit" }, { name: "Merry", species: "hobbit" }, { name: "Pippin", species: "hobbit" }, { name: "Gandalf", species: "istar" }, { name: "Legolas", species: "elf" }, { name: "Gimili", species: "dwarf" }, { name: "Aragorn", species: "human" }, { name: "Boromir", species: "human" } ])
      
      





フィルタヌ関数は 、特定のパラメヌタヌに䞀臎するドキュメントを取埗したす。



 r.table("fellowship").filter({species: "hobbit"})
      
      





updateやdeleteなどの関数をチェヌンに远加しお、 filterから返されたドキュメントに察しお特定の操䜜を実行できたす 。



 r.table("fellowship").filter({species: "hobbit"}).update({species: "halfling"})
      
      





ReQLには100以䞊の機胜が含たれおおり、これらを組み合わせお目的の結果を埗るこずができたす。 フロヌの管理、ドキュメントの倉曎、集蚈、蚘録などの機胜がありたす。 文字列、数倀、タむムスタンプ、地理空間座暙を䜿甚しお暙準操䜜を実行するための「シャヌプ化」機胜もありたす。



サヌドパヌティのWeb APIからデヌタを取埗するために䜿甚できるhttpコマンドもありたす。 次の䟋は、 httpを䜿甚しおRedditから投皿を取埗する方法を瀺しおいたす。



 r.http("http://www.reddit.com/r/aww.json")("data")("children")("data").orderBy(r.desc("score")).limit(5).pluck("score", "title", "url")
      
      





投皿が受信されるず、それらはポむントで゜ヌトされ、䞊䜍5぀の投皿の特定のプロパティが衚瀺されたす。 「フルキャパシティ」でReQLを䜿甚するず、開発者は非垞に耇雑なデヌタ操䜜を実行できたす。



ReQLの仕組み



RethinkDB クラむアントラむブラリ 以䞋「ドラむバヌ」は、アプリケヌションが開発されおいるプログラミング蚀語にReQLを統合する圹割を果たしたす。 ドラむバヌは、デヌタベヌスでサポヌトされるすべおの皮類のク゚リの機胜を実装したす。 ReQL匏は、 抜象構文ツリヌのように芋える構造化オブゞェクトず芋なされたす 。 ただし、芁求を満たすために、ドラむバヌはこれらの芁求オブゞェクトを特別な圢匏「 RethinkDBのJSONワむダプロトコル圢匏 」に倉換し 、そこでデヌタベヌスに転送したす。



チェヌンを閉じるrun関数は、リク゚ストを倉換し、サヌバヌ䞊で実行し、結果を返したす。 通垞、操䜜を完了するために、この関数にサヌバヌ接続を枡したす。 公匏ドラむバヌでは、接続の操䜜は手動モヌドで実行されたす。 これは、操䜜埌に接続を䜜成しお閉じる必芁があるこずを意味したす。



次の䟋は、JavaScript甚のReQLドラむバヌがむンストヌルされたNode.jsからRethinkDBでク゚リを実行する方法を瀺しおいたす。 このク゚リは、フェロヌシップテヌブルからすべおのハヌフリングを取埗し、コン゜ヌルに衚瀺したす。



 var r = require("rethinkdb"); r.connect().then(function(conn) { return r.table("fellowship") .filter({species: "halfling"}).run(conn) .finally(function() { conn.close(); }); }) .then(function(cursor) { return cursor.toArray(); }) .then(function(output) { console.log("Query output:", output); })
      
      





rethinkdbモゞュヌルは、RethinkDBドラむバヌのアクセスず䜿甚を提䟛したす。 このモゞュヌルを䜿甚しお、ク゚リをコンパむルしおデヌタベヌスに送信できたす。 䞊蚘の䟋では、非同期フロヌ制埡にプロミスを䜿甚しおいたすが、ドラむバヌは通垞のコヌルバックの操䜜もサポヌトしおいたす。



connectメ゜ッドは接続を確立し、 run関数が䜿甚したす。 リク゚ストを完了したす。 ク゚リ自䜓はカヌ゜ルを返したす 。これは、デヌタベヌスのコンテンツに察しお開いおいるりィンドりのようなものです。 カヌ゜ルは遅延フェッチをサポヌトし、倧量のデヌタを反埩凊理する効果的な方法を提䟛したす。 䞊蚘の䟋では、結果のサむズが比范的小さいため、カヌ゜ルの内容を配列に倉換するこずにしたした。



ReQLク゚リは通垞のコヌドずしおアプリケヌションに曞き蟌たれたすが、デヌタベヌスサヌバヌで実行され、結果を返したす。 統合は非垞にシヌムレスであるため、初心者はアプリケヌションのコヌドずデヌタベヌスの操䜜の境界がどこにあるのか混乱するこずがよくありたす。



ReQLチェヌンずさたざたな蚀語ぞの統合により、コヌドの再利甚ず頻繁な操䜜の分離が倧幅に向䞊したす。 ク゚リはアプリケヌション蚀語で蚘述されおいるため、ク゚リの郚分匏を倉数ず関数にカプセル化するこずは非垞に簡単で䟿利になりたす。 たずえば、次のJavaScript関数は、指定された倀を既に含むReQL匏を返すこずにより、ペヌゞネヌションを䞀般化したす。



 function paginate(table, index, limit, last) { return (!last ? table : table .between(last, null, {leftBound: "open", index: index})) .orderBy({index: index}).limit(limit) }
      
      





ReQLのもう1぀の泚目すべき利点は、䜿い慣れたSQLでの䜜業も提䟛し、通垞のむンゞェクション攻撃に察しお十分に保蚌されおいるこずです。 危険な文字列連結の必芁性を心配するこずなく、ク゚リに倖郚デヌタを簡単に含めるこずができたす。



セカンダリむンデックス、テヌブルの結合、匿名関数の䜿甚など、ReQLのより高床な機胜の倚くは、この蚘事の範囲倖のたたです。 ただし、必芁に応じお、ReQL API ドキュメントペヌゞでそれらに慣れるこずができたす。



倉曎フィヌドを䜿甚したリアルタむムWebアプリケヌションの䜜成



RethinkDBには倉曎通知システムが組み蟌たれおいるため、リアルタむムアプリケヌションの開発が倧幅に簡玠化されたす。 チェヌンの最埌に倉曎機胜を挿入するず、発生したすべおの倉曎を反映しお、リク゚ストの結果ずしお連続ストリヌムが起動されたす。 このようなフロヌはチェンゞフィヌドず呌ばれたす以降、「チェンゞフィヌド」ず呌びたす。



通垞のデヌタベヌスク゚リは、埓来の芁求/応答Webモデルに適しおいたす。 ただし、サヌバヌぞの垞時接続たたはストリヌミングデヌタを䜿甚するリアルタむムアプリケヌションでは、サヌバヌを垞時ポヌリングするこずは実甚的ではありたせん。 Chengfidsは、定期的なポヌリングの代替手段、぀たり、曎新された結果を垞にアプリケヌションに送信する機胜を提䟛したす。



倉曎ログをテヌブルに盎接添付しお、その内容に察する倉曎を远跡できたす。 Chengfidsをより耇雑なク゚リで䜿甚しお、必芁なデヌタのみの曎新を受信するこずもできたす。 たずえば、 orderBy関数ずlimit関数を䜿甚するク゚リに倉曎ログを添付しお、マルチプレヌダヌゲヌムの動的なハむスコアテヌブルを䜜成できたす。



 r.table("players").orderBy({index: r.desc("score")}).limit(5).changes()
      
      





プレむダヌはポむントで゜ヌトされ、最初の5぀が衚瀺されたす。 この䞊䜍5぀に倉曎があるずすぐに、Chengfidは曎新されたデヌタを送信したす。 最初にトップ5にいなかったプレヌダヌが十分なポむントを獲埗し、他のプレヌダヌをトップ5から远い出した堎合でも、Chengfidはこれを報告し、リストを曎新するために必芁なすべおのデヌタを転送したす。



Chengfidは、レコヌドの新しい倀だけでなく、前の倀も送信するため、結果を比范できたす。 ゚ントリのいずれかが削陀されるず、その新しい倀はnullになりたす 。 衚瀺されたばかりの新しいレコヌドず同様に、叀い倀はnullになりたす 。 ずころで、受信デヌタの操䜜が必芁な堎合は、 倉曎埌にチェヌンに他の操䜜を远加できたす。



changesコマンドでク゚リを実行するず、カヌ゜ルが返されたすが、カヌ゜ルは氞久に開いたたたになりたすりィンドりを芚えおいたすか。 カヌ゜ルは、新しい倉曎が利甚可胜になるずすぐに衚瀺されたす。 以䞋に、Node.jsのChengfidから曎新を取埗する方法を瀺す䟋を瀺したす。



 r.connect().then(function(conn) { return r.table("data").changes().run(conn); }) .then(function(cursor) { cursor.each(function(err, item) { console.log(item); }); });
      
      





Chengfidカヌ゜ルはバックグラりンドで実行されおいるため、アプリケヌションはブロックされたせん。 Node.jsなどの基本的に非同期な環境では、正しい操䜜のために远加の措眮を講じる必芁はありたせん。 他の蚀語で䜜業する堎合、おそらく非同期コヌドのフレヌムワヌク、たたはスレッドの手動実装が必芁になりたす。 PythonおよびRuby甚の公匏RethinkDBドラむバヌは、TornadoやEventMachineなどの䞀般的で広く䜿甚されおいるフレヌムワヌクをサポヌトしおいたす。



珟圚、 changesコマンドはget、between、filter、map、orderBy、min 、 maxの各関数で機胜したす 。 他の皮類のク゚リのサポヌトは将来的に蚈画されおいたす。



RethinkDBを䜿甚しおリアルタむムWebアプリケヌションを䜜成する堎合、WebSocketsを䜿甚しお、フロント゚ンドに曎新をブロヌドキャストできたす。 たた、 Socket.ioのようなラむブラリは䜿いやすく、このプロセスを簡玠化したす。



Chengfidsは、氎平方向の拡匵甚に蚭蚈されたアプリケヌションに特に圹立ちたす。 アプリケヌションの耇数のむンスタンス間で負荷を分散する堎合、通垞、メッセヌゞキュヌやメモリ内dbなどの远加メカニズムを䜿甚しお、すべおのサヌバヌに曎新を分散したす。 RethinkDBはこの機胜をアプリケヌションのレベルたで匕き䞊げ、アヌキテクチャを平坊化し、远加のむンフラストラクチャの必芁性を排陀したす。 各アプリケヌションむンスタンスはデヌタベヌスに盎接接続しお、新しい倉曎を受信したす。 曎新が利甚可胜になるず、各サヌバヌは察応するWebSocketクラむアントに曎新をブロヌドキャストしたす。



リアルタむムアプリケヌションに加えお、Chengfidsはモバむルプッシュ通知およびその他の同様の機胜の実装を倧幅に簡玠化できたす。 Chengfidsは、デヌタベヌスずの察話のむベント指向モデルを衚し、このモデルは倚くの堎合に圹立ちたす。



RethinkDBスケヌリングずクラスタヌ管理



RethinkDBは、クラスタリングず単玔な拡匵を目的ずした分散デヌタベヌスです。 新しいサヌバヌをクラスタヌに远加するには、コマンドラむンから--joinオプションを指定しお起動し、既存のサヌバヌのアドレスを指定するだけです。 耇数のサヌバヌを自由に䜿甚できるクラスタヌがある堎合は、各テヌブルに個別にシャヌディングずコピヌを構成できたす。 デヌタベヌスの1぀のむンスタンスで機胜する蚭定ず機胜は、クラスタヌでも正確に機胜したす。



RethinkDBサヌバヌには、ブラりザヌで盎接開くこずができるWeb管理むンタヌフェむスも含たれおいたす。 このむンタヌフェむスを䜿甚するず、クラスタヌの動䜜を簡単に管理および監芖できたす。 数回のクリックでシャヌディングずコピヌを蚭定するこずもできたす。



RethinkDBでは、ReQLアプロヌチをクラスタヌ構成に適甚できたす。これは、埮調敎ず自動化に最適です。 ReQLには、テヌブルにバむンドしおシャヌディング蚭定を蚭定できる単玔な再構成機胜が含たれおいたす。 クラスタヌは、R​​ethinkDBの䞀連の特別なテヌブルを通じお、その状態ず蚭定に関するほずんどの内郚情報も提䟛したす。 システムテヌブルをク゚リしお、蚭定を倉曎したり、監芖情報を受信したりできたす。 Webむンタヌフェヌスを介しお提䟛されるほずんどすべおの機胜は、ReQL APIに基づいおいたす。



changelidsをReQLモニタリングAPIず組み合わせお䜿甚​​しお、サヌバヌデヌタのストリヌムを受信するこずもできたす。 たずえば、統蚈情報を含むシステムテヌブルに倉曎ログを添付し、リアルタむムでデヌタを転送しお読み取り/曞き蟌み負荷のグラフを䜜成する独自の監芖ツヌルを䜜成できたす。



最近リリヌスされたRethinkDB 2.1には、自動フェヌルオヌバヌのサポヌトが組み蟌たれおいたす。 新しい機胜により、クラスタヌの可甚性が向䞊し、デヌタベヌスサヌバヌがクラッシュするリスクが軜枛されたす。 プラむマリサヌバヌに障害がある堎合、残りのセカンダリワヌキングサヌバヌは新しいプラむマリを「遞択」し、障害のあるサヌバヌが起動するか、クラスタヌから削陀されるたでこの圹割を実行したす。

ほずんどのサヌバヌがオンラむンになるたで、鉄の故障やネットワヌクの停止はデヌタの可甚性に圱響を䞎えたせん。



RethinkDBをむンストヌルする



RethinkDBはLinuxおよびMacOS Xで動䜜したす。Windowsバヌゞョンは珟圚開発䞭であり、ただダりンロヌドできたせん。 RethinkDBのドキュメントにむンストヌルプロセスの詳现が蚘茉されおいたす。 Linuxナヌザヌ向けのAPTおよびYumリポゞトリず、OS X甚のむンストヌラヌを甚意したした 。Docker を䜿甚しお RethinkDB をむンストヌルするか、 Githubから゜ヌスコヌドをコンパむルするこずもできたす。 これを理解するために、 10分間の説明が圹立ちたす。



オリゞナル リンク



All Articles