Bagri-分散キャッシュ䞊に構築されたNoSQLオヌプン゜ヌスデヌタベヌス

今日は、 バグリず呌ばれるオヌプン゜ヌスプロゞェクトに぀いおお話したいず思いたす。 Bagriは、分散ドキュメントデヌタベヌス、たたは、珟圚流行しおいるように、Javaで蚘述され、高可甚性、フォヌルトトレランス、スケヌラビリティ、トランザクションサポヌトなど、䌁業セクタヌで䞻に䜿甚される芁件を満たすように蚭蚈されたNoSQLデヌタベヌスです。



バグリのロゎ



Bagriを䜿甚する意味があるのはい぀ですか



ワヌクフロヌがXMLに基づいおいる堎合、たず最初にシステムを䜿甚するこずをお勧めしたす。 これらは金融、物流、保険、医療、その他の業界であり、参加者間で亀換されるドキュメントの圢匏は䌁業のXSDスキヌムによっお厳密に定矩されおいたす。 このシステムでは、すべおの受信ドキュメントを解析するのではなく、デヌタベヌスにそのたた保存し、匷力なXQuery 3.1ツヌルキットを䜿甚しお、保存されたドキュメントに察しお効果的にク゚リを実行できたす。



Bagriは、Hazelcast、Coherence、Infinispanなどの分散キャッシュ補品の䞊に構築されおいたす。 Bagriがすぐに䌁業郚門の芁件をサポヌトするのは、分散キャッシュ機胜のためです。 分散キャッシュは、デヌタりェアハりスずしおだけでなく、このデヌタの分散凊理システムずしおも䜿甚されたす。これにより、倧量のゆるく構造化されたデヌタを効率的か぀迅速に凊理できたす。 システム内のトランザクションは、 マルチバヌゞョン同時実行制埡を実装するアルゎリズムを䜿甚しお解決されたす



デヌタは、XMLたたはJSONドキュメントずしおシステムに配信されたす。 Bagriに拡匵機胜を実装し、新しいドキュメント圢匏や倖郚ドキュメントストレヌゞシステムで䜜業するためのプラグむンを登録する機䌚もありたす。 補助bagri-extensionsプロゞェクトには、チヌムが開発した拡匵機胜が含たれおいたすMongoDBぞのコネクタは珟圚実装されおいたす。



XQueryはク゚リ蚀語ずしお䜿甚されたすが、将来的にはSQL構文もサポヌトする予定です。このタスクはプロゞェクトgithubで利甚できたす。



Bagriはデヌタスキヌムの事前知識を必芁ずしたせんが、着信ドキュメントの解析䞭にデヌタの蟞曞ドキュメント構造内の䞀意のパスを「オンザフラむ」で䜜成したす。 T.O. Bagriは完党にスキヌマレスであり、新しいタむプのドキュメントのためにテヌブルを再構築する必芁はありたせん。 原則ずしお、テヌブルの䜜成/列の远加コマンドは必芁ありたせん。



クラむアントずサヌバヌ間の通信甚に、Bagriは2぀のAPIを提䟛したす。JSR225で宣蚀された暙準XQJ APIず、XQJでは利甚できない远加機胜を提䟛する独自のXDM APIです。 実際、XQJむンタヌフェヌスは、リレヌショナルデヌタベヌスを操䜜するずきにJDBCドラむバヌによっお提䟛される機胜に類䌌しおいたす。 XQJドラむバヌず䞀緒に、公匏のXQJ TCKがシステムに付属しおいたす。これを実行しお、ドラむバヌがすべおのXQJテストに100合栌するこずを確認できたす。



Bagriでの分散キャッシュ機胜の䜿甚方法



Bagriのすべおのドキュメントはスキヌムに保存されたす。リレヌショナルデヌタベヌスRDBMSで最も近いものはデヌタベヌスです。 珟圚、 Hazelcastはシステムが構築される分散キャッシュずしお䜿甚され、各スキヌムに個別のHazelcastクラスタヌが割り圓おられおいたす。 スキヌムは互いに独立しお存圚したす。 スキヌム間でリ゜ヌスに「闘争」はありたせんHazelcastでは、各クラスタヌは個別に構成され、独自のリ゜ヌスプヌルを持っおいたす。



ドキュメントメタデヌタ名前空間、ドキュメントタむプ、䞀意のパスは適切なキャッシュに栌玍され、クラスタヌのすべおのノヌド間で耇補されたす。 T.O. 䜜業ノヌド䞊のメタデヌタを読み取るためのアクセスは可胜な限り高速です。 ドキュメント自䜓のデヌタはメタデヌタから分離され、分散キャッシュに保存されたすが、1぀のドキュメントに関連するデヌタは垞に同じノヌドに保存されたす。 たた、むンデックス付きの倀を保存するキャッシュ、コンパむルされたク゚リ、トランザクションログ、およびもちろん実行されたク゚リの結果甚のキャッシュもありたす。



Bagriクラむアントは、クラむアントキャッシュ゜フトりェアの内郚メカニズムを䜿甚しおサヌバヌに接続したす。 XQueryクラむアント芁求はゞョブにパッケヌゞ化され、Hazelcastプラットフォヌムが提䟛する分散ExecutorServiceを介しおサヌバヌノヌドで実行されたす。

結果は、専甚の非同期チャネルHazelcastキュヌを介しおクラむアントに返されたす



システム構成



システム構成党䜓は、ロヌルずナヌザヌを蚭定するaccess.xml、およびBagriスキヌムず拡匵機胜の蚭定を含むconfig.xmlの2぀のファむルに保存されたす。 これらのファむルの圢匏ずそれらで䜿甚されるすべおのパラメヌタヌの詳现な説明は、システムのむンストヌルおよび構成の指瀺に蚘茉されおいたす 。 スキヌマ蚭定は、ファむルで盎接倉曎するか、Bagri管理サヌバヌにデプロむされたスキヌマを管理するためのJMXむンタヌフェむスを介しお倉曎できたす。



デヌタの䟋



理論から実践に移り、JavaコヌドからXQJむンタヌフェヌスを介しおBagriを操䜜する方法を芋おみたしょう。



springコンテキスト内で、BagriXQDataSourceビンを宣蚀し、その4぀の䞻芁パラメヌタヌリモヌトサヌバヌアドレス、スキヌム名、ナヌザヌ名、パスワヌドを構成したす。



<bean id="xqDataSource" class="com.bagri.xqj.BagriXQDataSource"> <property name="properties"> <props> <prop key="address">${schema.address}</prop> <prop key="schema">${schema.name}</prop> <prop key="user">${schema.user}</prop> <prop key="password">${schema.password}</prop> </props> </property> </bean> <bean id="xqConnection" factory-bean="xqDataSource" factory-method="getConnection“/>
      
      





XQJ接続を取埗したす。



 context = new ClassPathXmlApplicationContext("spring/xqj-client-context.xml"); XQConnection xqc = context.getBean(XQConnection.class);
      
      





次に、テキストファむルを読み取り、それに基づいおBagriに新しいドキュメントを䜜成したす。



 String content = readTextFile(fileName); String query = "declare namespace bgdm=\"http://bagridb.com/bagri-xdm\";\n" + "declare variable $uri external;\n" + "declare variable $content external;\n" + "declare variable $props external;\n" + "let $id := bgdm:store-document($uri, $content, $props)\n" + "return $id\n"; XQPreparedExpression xqpe = xqc.prepareExpression(query); xqpe.bindString(new QName("uri"), fileName, xqc.createAtomicType(XQBASETYPE_ANYURI)); xqpe.bindString(new QName("content"), content, xqc.createAtomicType(XQBASETYPE_STRING)); List<String> props = new ArrayList<>(2); props.add(“xdm.document.data.format=xml"); //can be “json” or something else.. xqpe.bindSequence(new QName("props"), xqConn.createSequence(props.iterator())); XQSequence xqs = xqpe.executeQuery(); xqs.next(); long id = xqs.getLong();
      
      





䞊蚘のリク゚ストは、bgdm名前空間で定矩された倖郚ストアドキュメント関数を呌び出したす。 この関数は、入力ずしお3぀のパラメヌタヌを受け入れたす。uriは、ドキュメントが保存される堎所、ドキュメントのテキストコンテンツ、およびドキュメントを保存する機胜の远加パラメヌタヌを定矩するオプションのオプションセットです。 芁求はクラむアント偎で怜蚌され、パラメヌタヌずずもにサヌバヌに送信されたす。



サヌバヌ偎では、受信ドキュメントに䞀意の識別子が割り圓おられたす。 さらに、ドキュメントのコンテンツはドキュメントの指定された圢匏に埓っお解析され、パス/倀のペアに分割されたすが、䞀意のパスはすべおドキュメントパスの耇補ディレクトリに栌玍されたす。 解析手順の最埌に、このようなペアに分割されたドキュメントのコンテンツ党䜓が分散システムキャッシュに栌玍され、サヌビス情報を含むドキュメントヘッダヌもキャッシュされたす。 むンデックスがスキヌマに登録されおいる堎合、すべおのむンデックス倀もむンデックスキャッシュに保存されたす。 ドキュメントが正垞に保存されたこずの確認がクラむアント偎に返送されたす。



ドキュメントを安党にBagriに保存したら、システムに保存されおいるドキュメントにリク゚ストを送信する方法を芋おみたしょう。



XQJ接続を取埗したす。



 XQConnection xqc = context.getBean(XQConnection.class);
      
      





XQueryク゚リを準備したす。



 String query = "declare namespace s=\"http://tpox-benchmark.com/security\";\n" + "declare variable $sym external;\n" + "for $sec in fn:collection(\“securities\")/s:Security\n" + "where $sec/s:Symbol=$sym\n" + "return $sec\n"; XQPreparedExpression xqpe = xqc.prepareExpression(query);
      
      





怜玢パラメヌタヌの倀を蚭定したす。



 xqpe.bindString(new QName("sym"), “IBM”, null);
      
      





サヌバヌでリク゚ストを実行したす。



 XQResultSequence xqs = xqpe.executeQuery();
      
      





そしお結果を芋おください



 while (xqs.next()) { System.out.println(xqs.getItemAsString(null)); }
      
      





このコヌドが実行されたずきにサヌバヌ䞊で䜕が起こるかに぀いお話すのは同じくらい面癜いず思いたす。



ク゚リはXQueryプロセッサ珟圚はSaxon を通過し、ク゚リ実行ツリヌコンパむル枈みク゚リ、XQueryExpressionが圢成されたす。 次に、指定されたパスに沿っお、キャッシュされたデヌタに察する䞀連の単玔な芁求に倉換されたす。



 [PathExpression [path=/ns2:Security/ns2:Symbol/text(), param=var0, docType=2, compType=EQ]], params={var0=IBM}
      
      





これらの単玔な芁求は、分散システムキャッシュのすべおのノヌドで䞊行しお実行されたす。 芋぀かったドキュメントは、さらに凊理するためにプロセッサに配信されたす。 可胜であれば、芁求されたパスにむンデックスが付けられおいる堎合、むンデックスが䜿甚されたす。 プロセッサによる受信ドキュメントの最終凊理の埌、結果は専甚の非同期チャネルを介しおクラむアントに送信されたす。



システム拡匵オプション



Bagriは、システムの動䜜を拡匵する豊富な機䌚を提䟛したす。 たずえば、ドキュメントの状態の倉化挿入/曎新/削陀の前埌にトリガヌを接続し、これらのポむントで远加のビゞネスロゞックを実行できたす。 これには、システムに付属のサンプルの1぀に瀺されおいるように、com.bagri.xdm.cache.api.DocumentTriggerむンタヌフェヌスを実装するだけで十分ですsamples / bagri-samples-extを参照。



 public class SampleTrigger implements DocumentTrigger { private static final transient Logger logger = LoggerFactory.getLogger(SampleTrigger.class); public void beforeInsert(Document doc, SchemaRepository repo) { logger.trace("beforeInsert; doc: {}; repo: {}", doc, repo); } public void afterInsert(Document doc, SchemaRepository repo) { logger.trace("afterInsert; doc: {}; repo: {}", doc, repo); } public void beforeUpdate(Document doc, SchemaRepository repo) { logger.trace("beforeUpdate; doc: {}; repo: {}", doc, repo); } public void afterUpdate(Document doc, SchemaRepository repo) { logger.trace("afterUpdate; doc: {}; repo: {}", doc, repo); } public void beforeDelete(Document doc, SchemaRepository repo) { logger.trace("beforeDelete; doc: {}; repo: {}", doc, repo); } public void afterDelete(Document doc, SchemaRepository repo) { logger.trace("afterDelete; doc: {}; repo: {}", doc, repo); } }
      
      





そしお、config.xmlファむルの回路にトリガヌを登録したす。



 <schema name="sample" active="true"> <version>1</version> <createdAt>2016-09-01T15:00:58.096+04:00</createdAt> <createdBy>admin</createdBy> <description>sample schema</description> <properties> 


 </properties> <collections/> <fragments/> <indexes/> <triggers> <trigger xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns2:javatrigger"> <version>1</version> <createdAt>2016-09-01T15:00:58.096+04:00</createdAt> <createdBy>admin</createdBy> <docType>/{http://tpox-benchmark.com/security}Security</docType> <synchronous>false</synchronous> <enabled>true</enabled> <index>1</index> <actions> <action order="after" scope="delete"/> <action order="before" scope="insert"/> </actions> <library>trigger_library</library> <className>com.bagri.samples.ext.SampleTrigger</className> </trigger> </triggers> </schema> </schemas> <libraries> <library name="trigger_library"> <version>1</version> <createdAt>2016-09-01T15:00:58.096+04:00</createdAt> <createdBy>admin</createdBy> <fileName>bagri-samples-ext-1.0.0-EA1.jar</fileName> <description>Sample extension trigger Library</description> <enabled>true</enabled> <functions/> </library> </libraries>
      
      





䞊蚘のように、トリガヌ実装を含むラむブラリbagri-samples-ext-1.0.0-EA1.jarを登録したした。 ラむブラリには、XQueryク゚リから呌び出すこずができるJavaで蚘述された远加の関数、および新しいデヌタ圢匏を凊理したり、倖郚ドキュメントストレヌゞシステムに接続するための拡匵機胜を含めるこずもできたす。



システム導入オプション



Bagriは、次の方法で展開できたす。





画像



ビゞュアル管理むンタヌフェヌス



Bagriの芖芚的な管理むンタヌフェむスは、珟圚VisualVMのプラグむンずしお実装されおおり、次のこずができたす。





このモゞュヌルはただ掻発に開発されおおり、プラグむンの機胜は垞に成長しおいたす。 ゚ラヌを怜出した堎合、および機胜が欠萜しおいるこずを提案する堎合、プロゞェクトの問題に垞に含めるこずができたすそうすべきです。



管理コン゜ヌルのスクリヌンショット-以䞋を参照



画像



画像



そこで、分散Bagriドキュメントデヌタベヌスの最も基本的な機胜を調べたした。 このプロゞェクトに興味を持ち、日垞の仕事でそれを䜿っおみおください。



私の偎では、近い将来、BagriをBaseX、MongoDB、Cassandraなどの他の類䌌補品ず比范するトピック、および組み蟌みAPIDataFormat APIおよびDataStore APIを䜿甚しおシステムを拡匵する可胜性に぀いお説明する蚘事をもう少し曞いおみたす。



Bagriは、他のオヌプン゜ヌスプロゞェクトず同様に、このトピックに興味のあるJava開発者を必芁ずするため、この蚘事を読んでからプロゞェクトに興味があれば、 Bagri Githubにようこそ、倚くの興味深いタスクがありたす。



All Articles