Apache ZookeeperのApache Curatorラむブラリ機胜の抂芁







矩務の問題ずしお、分散アプリケヌションの蚭蚈ず開発に察凊する必芁がありたす。 そのようなアプリケヌションは、倚くの堎合、プロセス間の通信のさたざたな手段を䜿甚しお、コンポヌネントの盞互䜜甚を線成したす。 分散方匏で関連デヌタを凊理するアルゎリズムを実装するプロセスでは、特定の困難が発生したす。 このようなタスクをサポヌトするために、専甚の分散調敎システムが䜿甚されたす。 最も人気があり、広く䜿甚されおいる補品はApache Zookeeperです。







Zookeeperは耇雑な補品です。 かなりの幎霢にもかかわらず、定期的に特定の゚ラヌが芋぀かりたした。 ただし、これはその機胜の結果に過ぎず、分散システムの倚くの開発者の生掻を楜にしたす。 次に、その機胜をよりよく理解するのに圹立぀Zookeeperのいく぀かの機胜を芋おから、Apache CuratorNetflixラむブラリに移りたす。これにより、分散゜フトりェア開発者の生掻が楜しくなり、分散調敎オブゞェクトを実装するための倚くの既補のレシピが提䟛されたす。







Apache zookeeper



前述したように、Zookeeperは分散システムの重芁なコンポヌネントです。 Zookeeperデヌタベヌスは、ファむルシステムに䌌たツリヌの圢で想像するのが最も簡単で、ツリヌの各芁玠は/ a / path / to / nodeで識別され、任意のデヌタを栌玍したす。 したがっお、Zookeperの助けを借りお、階局型の分散デヌタりェアハりスやその他の興味深い蚭蚈を敎理するこずができたす。 Zookeeperの有甚性ず広範な䜿甚は、以䞋にリストするいく぀かの重芁なプロパティによっお提䟛されたす。







分散コンセンサス



コンセンサスはZABアルゎリズムを䜿甚しお達成されたす。このアルゎリズムは、 CAP定理のC䞀貫性およびPパヌティション蚱容倀プロパティを提䟛したす。これは、分離に察する敎合性ず耐性を意味し、アクセシビリティを犠牲にしたす。 実際には、これは次の圱響をもたらしたす。







  1. どのサヌバヌでこの状態を芁求しおも、すべおのクラむアントは同じ状態を参照したす。
  2. 状態の倉化は敎然ず発生し、「レヌス」は䞍可胜ですセット操䜜の堎合、get-set操䜜はアトミックではありたせん。
  3. Zookeeprクラスタヌは「バラバラ」になり、完党にアクセスできなくなる可胜性がありたすが、同時にすべおのナヌザヌがアクセスできなくなりたす。


コンセンサスは、分散システムが珟圚の状態に䜕らかの圢で同意する胜力です。 ZookeeperはZABアルゎリズムを䜿甚したすが、他のアルゎリズムもよく䜿甚されたす-Raft 、

いかだ 。


䞀時ノヌド



Zookeeperクラスタヌずの接続を確立するクラむアントは、セッションを䜜成したす。 セッションのフレヌムワヌク内で、他のクラむアントに衚瀺されるが、その有効期間がセッションの有効期間ず等しいノヌドを䜜成するこずができたす。 セッションの終了時に、これらのノヌドは削陀されたす。 このようなノヌドには制限がありたす-タヌミナルのみであり、子孫を持぀こずはできたせん。぀たり、䞀時的なサブツリヌを持぀こずはできたせん。 䞀時ノヌドは、倚くの堎合に䜿甚されたす

サヌビス発芋システムの実装。







負荷分散が実行される耇数のサヌビスむンスタンスがあるずしたす。 むンスタンスのいずれかが衚瀺されるず、そのノヌドの䞀時的なノヌドが䜜成され、そのノヌドにサヌビスのアドレスが配眮されたす。サヌビス障害が発生するず、このノヌドは削陀され、バランシングに䜿甚できなくなりたす。 䞀時ノヌドは非垞に頻繁に䜿甚されたす。







ノヌドむベントのサブスクラむブ



クラむアントは、ノヌドむベントをサブスクラむブ監芖し、これらのノヌドに関連するむベントが発生したずきに曎新を受信できたす。 ただし、ここでも制限がありたす。ノヌドでむベントが発生した埌、サブスクリプションはキャンセルされ、再床埩元する必芁がありたすが、明らかに、このノヌドで発生する他のむベントをスキップする可胜性がありたす。 この事実に関連しお、この機胜を䜿甚する可胜性は非垞に限られおいたす。







たずえば、怜出サヌビスのフレヌムワヌク内では、構成の倉曎に察応するために䜿甚できたすが、サブスクリプションをむンストヌルした埌、状態の倉曎がスキップされないこずを確認するために「手動」操䜜を実行する必芁があるこずに泚意する必芁がありたす。







シリアルノヌド



Zookeeperを䜿甚するず、名前が䞀時的に増加する可胜性がある䞀方で、連続しお増加する番号を远加するこずで名前が圢成されるノヌドを䜜成できたす。 この機胜は、適甚された問題たずえば、同じタむプのすべおのサヌビス、短呜ノヌドずしお登録するの解決ず、 公平な分散ブロッキングなどのZookeeperの「レシピ」の実装の䞡方で広く䜿甚されおいたす。







ノヌドのバヌゞョン



ノヌドのバヌゞョンを䜿甚するず、読み取りず曞き蟌みの間にノヌドの倉曎があったかどうかを刀断できたす。぀たり、蚭定操䜜䞭にノヌドの予想されるバヌゞョンを指定できたす。䞀臎しない堎合は、ノヌドの倉曎が別のクラむアントによっお行われ、状態を再床読み取る必芁があるこずを意味したす。 このメカニズムを䜿甚するず、たずえば「レシピ」 分散カりンタを実装する堎合など、デヌタの状態に順序付けられた倉曎を実装できたす。







ノヌドごずのACL



信頌できないアプリケヌションからデヌタを保護するために蚭蚈された、ノヌドのACLによっお定矩されたアクセス制限を蚭定するこずができたす。 もちろん、ACLは悪意のあるクラむアントが䜜成できる過負荷から保護せず、コンテンツぞのアクセスを制限するメカニズムのみを提䟛したす。







ノヌドごずのTTL



Zookeeperでは、TTLノヌドをむンストヌルできたす。その埌、曎新がない堎合ノヌドが削陀されたす。 この機胜は比范的最近登堎したした。







オブザヌバヌサヌバヌ



サヌバヌのクラスタヌにオブザヌバヌモヌドで接続する可胜性がありたすオブザヌバヌ。これは、読み取り操䜜の実行に䜿甚できたす。これは、曞き蟌み操䜜によっお生成されるクラスタヌの負荷が高い堎合に非垞に䟿利です。 オブザヌバヌサヌバヌを䜿甚するず、問題を解決できたす。 疑問が生じるかもしれたせんが、なぜ通垞のノヌドをクラスタヌに远加するだけではありたせんか 答えはコンセンサスアルゎリズムにありたす。デヌタを曞き蟌むこずができるノヌドが倚いほど、コンセンサスに達するたでに時間がかかり、クラスタヌの曞き蟌みパフォヌマンスが䜎䞋したす。 オブザヌバヌサヌバヌはコンセンサスに参加しおいないため、曞き蟌み操䜜のパフォヌマンスには圱響したせん。







ノヌドの時刻同期



Zookeeperは、ノヌドの同期に倖郚時間を䜿甚したせん。 これはかなり有甚なプロパティであり、正確な時間に焊点を圓おたシステムは、その䞍䞀臎に関連する゚ラヌを起こしやすい傟向がありたす。







もちろん、軟膏にはタヌルが含たれおいる必芁がありたす。実際には、Zookeeperには䜿甚を制限できるプロパティがありたす。 Zookeeper- Single Cluster of Failure ©Pinterestでの䜜業の耇雑さを皮肉にも説明する衚珟もありたす。これは、Zookeeperを䜿甚した分散システムを䜿甚しお単䞀障害点を取り陀こうずするず、たさに障害点。







ZookeeperデヌタベヌスはRAMに収たる必芁がありたす



Zookeeperはベヌスをメモリにロヌドし、そこに保持したす。 デヌタベヌスがRAMに収たらない堎合、スワップに配眮され、パフォヌマンスが倧幅に䜎䞋したす。 デヌタベヌスが倧きい堎合は、十分な量のRAMを備えたサヌバヌが必芁ですただし、サヌバヌ䞊の1 TBのRAMが制限からかけ離れおいる堎合、珟時点では問題になりたせん。







セッションタむムアりト時間



クラむアントの構成䞭にセッションタむムアりト時間が誀っお遞択されるず、クラスタヌの負荷が増加し、䞀郚のクラスタヌノヌドで障害が発生した堎合に、予枬䞍胜な結果が悪化する可胜性がありたす。 ナヌザヌはセッションの時間デフォルトでは30秒を短瞮しおシステムの収束性を高めようずしたす。これは、䞀時ノヌドがより速く削陀されるためです。







クラスタヌ内のノヌドの数による生産性の䜎䞋



通垞、クラスタヌはコンセンサスの達成に関䞎する3぀のノヌドを䜿甚したすが、ノヌドを远加したい堎合、曞き蟌み操䜜のパフォヌマンスが倧幅に䜎䞋したす。 ノヌドの数はそれぞれ奇数である必芁がありZABアルゎリズムの芁件、クラスタヌを5、7、9ノヌドに拡匵するずパフォヌマンスに悪圱響を及がしたす。 問題が読み取り操䜜にある堎合は、オブザヌバヌノヌドを䜿甚したす。







ノヌドごずの最倧デヌタサむズ



ノヌドあたりの最倧デヌタサむズは1MBに制限されおいたす。 倧量のデヌタを保存する必芁がある堎合、Zookeeperは保存したせん。







子孫リスト内のノヌドの最倧数



Zookepeerは、ノヌドが子孫を持぀こずができる量を課したせんが、サヌバヌがクラむアントに送信できるデヌタパケットの最倧サむズは4MBjute.maxbufferです。 ノヌドにそのリストが1぀のパッケヌゞに収たらないほど倚くの子孫がある堎合、残念ながら、それらに関する情報を取埗する方法はありたせん。 この制限は、キャッシュがファむルシステムに構築され、オブゞェクト名たたはダむゞェストが郚分に分割され、階局構造に線成されるのず同じ方法で階局「擬䌌フラット」リストを線成するこずによっおバむパスされたす。







欠点にもかかわらず、それらの利点を䞊回るため、Zookeeperは、Cloudera CDH5、DC / OS、Apache Kafkaなどの倚くの分散゚コシステムの䞍可欠なコンポヌネントになりたす。







開発者向けのZookeeper



ZookeeperはJava蚀語を䜿甚しお実装されおいるため、JVM環境での䜿甚は自然なものです。たずえば、Javaからサヌバヌたたはサヌバヌクラスタヌを起動し、サヌドパヌティサヌバヌを展開するこずなくアプリケヌションの統合たたはスモヌクテストを実装するのは非垞に簡単です。 ただし、ZookeeperクラむアントAPIは非垞に䜎レベルであり、操䜜を実行できたすが、川に逆らっお泳ぐこずに䌌おいたす。 さらに、䟋倖凊理を適切に実装するには、Zookeeperの基本を深く理解する必芁がありたす。 たずえば、Zookeeperでの䜜業に基本的なむンタヌフェむスを䜿甚した堎合、分散調敎および怜出コヌドの゚ラヌのデバッグず怜玢は非垞に倧きな問題を匕き起こし、かなりの時間を必芁ずしたした。







ただし、Netflix開発者のJordan Zimmermanによっお゜リュヌションが存圚し、コミュニティに寄付されおいたす。 Apache Curatorに䌚っおください。







Apacheキュレヌタヌ



プロゞェクトのメむンペヌゞには匕甚がありたす。













この声明はキュレヌタヌを100反映しおいたす。 このラむブラリの䜿甚を開始するず、Zookeeperを操䜜するためのコヌドがシンプルで理解しやすくなり、゚ラヌの数ずそれらを解決する時間が芁因によっお枛少するこずがわかりたした。 前述のように、暙準クラむアントが朮に逆らっお泳ぐこずに䌌おいる堎合、キュレヌタヌによっお状況は180床倉化したす。 さらに、キュレヌタヌのフレヌムワヌク内で、倚数の既補のレシピが実装されおいたす。これに぀いおはさらに怜蚎したす。







ベヌスAPI



APIは、非垞に䟿利な流䜓むンタヌフェヌスの圢で䜜成されおおり、必芁なアクションを簡単か぀簡朔に決定できたす。 䟋以䞋、Scala蚀語で䟋を瀺したす







client .create() .orSetData() .forPath("/object/path", byteArray)
      
      





これは、 「ノヌドを䜜成するか、存圚する堎合は、パスのデヌタを蚭定するだけ」/オブゞェクト/パス「およびそれにbyteArrayを曞き蟌む」ず翻蚳できたす。







たたは、䟋えば







 client .create() .withMode(CreateMode.EPHEMERAL_SEQUENTIAL) .forPath("/head/child", byteArray)
      
      





「パスにシリアルタむプず゚フェメラルタむプのノヌドを䜜成する」/ head / child000000XXXX「それにbyteArrayを曞き蟌む」 このマニュアルペヌゞには、さらにいく぀かの䟋がありたす 。







非同期操䜜



キュレヌタヌは、同期操䜜ず非同期操䜜の䞡方をサポヌトしおいたす。 非同期䜿甚の堎合、クラむアントは、同期CuratorFramework



ずは異なり、タむプAsyncCuratorFramework



CuratorFramework



。 そしお、各呌び出しチェヌンはthenAccept



メ゜ッドを受け入れたす。これは、操䜜が完了するず呌び出されるCallbackを瀺したす。 非同期むンタヌフェむスの詳现に぀いおは、専甚のマニュアルペヌゞを参照しおください 。







 val async = AsyncCuratorFramework.wrap(client); async.checkExists().forPath(somePath).thenAccept(stat -> mySuccessOperation(stat))
      
      





Scalaを䜿甚する堎合、非同期むンタヌフェむスを䜿甚するこずは正圓化されおいないように思われたす。機胜はScala Futureを䜿甚しお簡単に実装できるため、コヌドはscala-way開発の機胜を保持できたす。 ただし、Javaおよび他のJVM蚀語の堎合、このむンタヌフェヌスは䟿利です。


デヌタスキヌマのサポヌト



Zookeeperは、保存されたデヌタのセマンティクスをサポヌトしおいたせん。 これは、デヌタが保存される圢匏ずその配眮方法に぀いお、開発者が単独で責任を負うこずを意味したす。 これは、たずえば新しい開発者がプロ​​ゞェクトに来たずきなど、倚くの堎合に䞍䟿になる可胜性がありたす。 これらの問題を解決するために、キュレヌタヌは、これらのパス内のパスずノヌドタむプに制限を蚭定できるデヌタスキヌムをサポヌトしおいたす。 構成から䜜成された回路は、Json圢匏で衚すこずができたす。







 [ { "name": "test", "path": "/a/b/c", "ephemeral": "must", "sequential": "cannot", "metadata": { "origin": "outside", "type": "large" } } ]
      
      





移行サポヌト



キュレヌタヌの移行は、ZookeeperのLiquibaseに䌌おいたす。 圌らの助けを借りお、デヌタベヌスの進化を補品の新しいバヌゞョンに反映させるこずができたす。 移行は、連続しお実行される䞀連の操䜜で構成されたす。 各操䜜は、Zookeeperデヌタベヌスに察するいく぀かの倉換によっお衚されたす。 キュレヌタヌは、Zookeeperを䜿甚しお移行のアプリケヌションを個別に監芖したす。 この機胜は、アプリケヌションの新しいバヌゞョンをデプロむするプロセスで䜿甚できたす。 移行に぀いおは、察応するマニュアルペヌゞで詳しく説明しおいたす 。







テストサヌバヌずテストクラスタヌ



テストを簡玠化するために、キュレヌタヌを䜿甚するず、アプリケヌションにサヌバヌたたはZookeeperサヌバヌのクラスタヌを埋め蟌むこずができたす。 この問題は、Zookeeperを䜿甚する堎合のみ、Curatorを䜿甚せずに非垞に簡単に解決できたすが、Curatorはより簡朔なむンタヌフェヌスを提䟛したす。 たずえば、キュ​​レヌタヌのないZookeeperの堎合







 class ZookeeperTestServer(zookeperPort: Int, tmp: String) { val properties = new Properties() properties.setProperty("tickTime", "2000") properties.setProperty("initLimit", "10") properties.setProperty("syncLimit", "5") properties.setProperty("dataDir", s"$tmp") properties.setProperty("clientPort", s"$zookeperPort") val zooKeeperServer = new ZooKeeperServerMain val quorumConfiguration = new QuorumPeerConfig() quorumConfiguration.parseProperties(properties) val configuration = new ServerConfig() configuration.readFrom(quorumConfiguration) private val thread = new Thread() { override def run() = { zooKeeperServer.runFromConfig(configuration) } } def start = { thread.start() } def stop = { thread.interrupt() } } ... val s = new ZookeeperTestServer(port, tmp) s.start ... s.stop
      
      





キュレヌタヌの堎合







 val s = new TestingServer(port) s.start() ... s.stop()
      
      





キュレヌタヌのレシピ



キュレヌタヌレシピは、このラむブラリを䜿甚しお分散プロセス盞互䜜甚メカニズムを実装する䞻な動機です。 次に、キュレヌタヌがサポヌトする䞻なレシピず、それらの適甚方法をリストしたす。 私は実際にはいく぀かのレシピを適甚しなかったので、マニュアルに可胜な限り近い翻蚳が䞎えられたした。







リヌダヌズチョむス



これらのレシピは、珟圚のリヌダヌがいお、いく぀かのプロセスがホットリザヌブ内にあるフォヌルトトレラントプロセス実行モデルを実装するこずを目的ずしおいたす。 リヌダヌが機胜を果たすのをやめるずすぐに、別のプロセスがリヌダヌになりたす。 2぀の適切なレシピがありたす。







  1. Leader Latchは、CountDownLatchに類䌌しおおり、プロセスがリヌダヌになるたでロックされたす。
  2. Leader Election 。メ゜ッド呌び出しを通じおリヌダヌの遞択を実装したす。 プロセスがリヌダヌになった瞬間にメ゜ッドが呌び出され、そこからの出口はリヌダヌシップの喪倱を瀺したす。


ロック



ロックは、分散プロセス間同期の最も重芁なメカニズムの1぀です。 キュレヌタヌは、幅広いロックオブゞェクトを提䟛したす。







  1. 共有再入可胜ロック -アクセスできるクラむアントが再入力できる分散ロック。
  2. 共有ロック -分散ロック。
  3. 共有リ゚ントラント読み取り/曞き蟌みロック -読み取りず曞き蟌みを別々にロックできるオブゞェクト。耇数のクラむアントが同時に読み取り甚にオブゞェクトをロックできたすが、曞き蟌みロックは排他的です。
  4. 共有セマフォ -カりントセマフォの助けを借りお、32ビット敎数で指定された限られた量のリ゜ヌスで簡単に䜜業できたす。
  5. マルチ共有ロックは、耇数の分散ロックの操䜜をアトミックに実行できる高レベルのオブゞェクトです。


障壁



  1. バリア -特定の条件が満たされるたで、他の参加者のコヌドセクションぞのアクセスをクラむアントがブロックし、発生した堎合にアクセスをロック解陀できるオブゞェクト。これにより、すべおの参加者が実行を継続できたす。
  2. ダブルバリア -このオブゞェクトを䜿甚するず、特定の数のクラむアントの゚ントリをコヌドセグメントに同期し、そこから終了するこずができたす。


カりンタヌ



  1. 共有カりンタヌ -レヌス保護付きの通垞の敎数カりンタヌ32ビット。
  2. 分散アトミックロング -カりンタヌタむプロング64ビット。


キャッシュ



  1. パスキャッシュ -ノヌドを監芖し、その子ノヌドに぀いおロヌカルキャッシュを曎新し、オプションでデヌタが倉曎されたずきにデヌタに぀いお曎新するオブゞェクト。
  2. ノヌドキャッシュ - ノヌドを監芖し、ノヌドずそのデヌタに関するロヌカルキャッシュを曎新するオブゞェクト。
  3. ツリヌキャッシュ -ノヌドの子孫のツリヌ党䜓を監芖し、ツリヌ内で倉曎されるずロヌカルキャッシュを曎新するオブゞェクト。


結び目



  1. 氞続ノヌド -このレシピを䜿甚するず、倖郚の圱響䞋でもキュレヌタヌがその存圚ず䞍倉性を確保するために努力するデヌタを持぀ノヌドを䜜成できたす。
  2. 氞続的TTLノヌド -存続期間がTTLによっお決定されるノヌドを䜜成するためのレシピ。氞続的ノヌドず同じプロパティをサポヌトしたす。
  3. グルヌプメンバヌ - メンバヌのグルヌプを線成できたす。


キュヌ



Zookeeperは、集䞭分散キュヌを線成するのに最適な候補ではないこずに泚意しおください。倧量のメッセヌゞを確実に通過させる必芁がある堎合は、Apache Kafka、RabbitMQなどの特別に蚭蚈された゜リュヌションを䜿甚するこずをお勧めしたす。 ただし、キュレヌタヌはキュヌをサポヌトするための䞀連のレシピを提䟛したす。


  1. 分散キュヌ -優先床の高い順にメッセヌゞを入れたり取り出したりできる通垞の分散キュヌ。
  2. 分散IDキュヌ -各メッセヌゞに識別子を栌玍し、識別子を䜿っおキュヌからメッセヌゞをすぐに削陀できるようにする分散キュヌ。
  3. 分散優先床キュヌ -優先床キュヌ。
  4. 分散遅延キュヌ -キュヌを䜿甚するず、远加された各アむテムの時間をUnixtime圢匏で蚭定でき、キュヌからの読み取りが可胜になりたす。
  5. Simple Distributed Queueは、暙準のZookeeper APIによっお提䟛されるキュヌに類䌌しおいたす。


おわりに



Apache Curatorラむブラリヌは確かに䜿甚を怜蚎する䟡倀があり、゚ンゞニアリング䜜業の優れた䟋であり、Apache Zookeeperずの察話を倧幅に簡玠化できたす。 ラむブラリの短所には、ドキュメントの量が少ないため、初心者の開発者にずっお参入障壁が高くなりたす。 私の実践では、特定のレシピがどのように機胜するかを理解するために、ラむブラリの゜ヌスコヌドを繰り返し調査する必芁がありたした。 ただし、これにはプラスの効果もありたす。実装を深く理解するこずで、仮定に基づいた論理゚ラヌが少なくなりたす。







キュレヌタヌの開発者は、ラむブラリの䜿甚を開始する前に、Zookeeperのドキュメントを孊習するこずをお勧めしたす。 Zookeeperは効果的な䜿甚のための補品であり、そのAPIを知っおいるだけでなく、その仕組みを理解する必芁があるため、これは非垞に合理的なアドバむスです。 これらのコストは確実に報われ、経隓豊富な゚ンゞニアがZookeeper機胜を䜿甚するこずで、信頌性が高く生産的な分散システムを䜜成できたす。








All Articles