分散キャッシュのオブジェクトクエリ言語

著者:イクバルカーン

NCache これにより、中間層にスケーラブルな分散キャッシュを作成できるため、データベースへの高価なアクセスが削減され、アプリケーションのパフォーマンスが大幅に向上します。 また、あまりスケールアップできない単一のデータベース サーバーではなく、この拡張性の高いキャッシュで頻繁に使用されるデータを見つけることができるため、アプリケーションのスケーラビリティも向上します。

アプリケーションは通常、キーに基づいてすべてが保存されるハッシュテーブルとしてキャッシュを使用します。項目をフェッチするにはこのキーが必要です。 これは、データの検索に主キーのみを使用できるリレーショナル データベースに似ています。 これは多くの状況で問題なく機能しますが、実際の複雑なアプリケーションでは、多くの場合、アプリケーションは主キー以外の属性に基づいてデータを検索する必要があります。 また、多くのデータをキャッシュに保存しているので、この方法でキャッシュも検索できれば非常に便利です。 NCache まさにそのような機能を提供します。

この記事では、その方法について説明します NCache オブジェクトのクエリは機能します。

キャッシュ検索の戻りキー

NCache キャッシュを検索できるオブジェクト クエリ言語 (OQL) を提供します。 キャッシュからオブジェクトのコレクションをフェッチするには、API 呼び出しを実行し、この OQL に基づいた検索を指定する必要があります。 キャッシュをクエリするために .NET アプリケーションで使用する必要があるものは次のとおりです。

public class Program
{
    public static void Main(string[] args)
    {
        NCache.InitializeCache("myReplicatedCache");
        String query = "SELECT NCacheQuerySample.Business.Product WHERE this.ProductID > 100";
        // Fetch the keys matching this search criteria
        ICollection keys = NCache.Cache.Search(query);
        if (keys.Count > 0)
        {
            IEnumerator ie = keys.GetEnumerator();
            while (ie.MoveNext())
            {
                String key = (String)ie.Current;
                Product prod = (Product)NCache.Cache.Get(key);

                HandleProduct(prod);
                Console.WriteLine("ProductID: {0}", prod.ProductID);
            }
        }
        NCache.Cache.Dispose();
    }
} 

上記のコードはキャッシュを検索し、キーのコレクションを返します。 次に、返されたすべてのキーを反復処理し、対応するキャッシュされた項目をキャッシュから個別に取得します。 このアプローチの利点は、クエリが自動的に大量のデータを返さず、キーのみを返すことです。 その後、クライアント アプリケーションはどのキーを取得するかを決定できます。 このアプローチの欠点は、とにかくキャッシュからほとんどの項目を取得しようとすると、キャッシュへのアクセスが何度も行われることになることです。 また、キャッシュが分散されると、最終的にコストが高くなる可能性があります。 その場合は、キーと項目を一緒に返す検索を実行できます。

キャッシュ検索返品アイテム

すでに見たように、単純な Cache.Search(...) はキーのコレクションを返します。 ただし、これらのキーに関連付けられたキャッシュされた項目のすべてまたはほとんどをフェッチする場合、 Cache.Search(...) はキャッシュを検索するあまり効率的な方法ではありません。 その理由は、検索を行うために最初に電話をかけるからです。 次に、いくつかの呼び出しを行って、各キーに関連付けられた項目を取得します。 これは非常にコストのかかる操作になる可能性があります。 このような状況では、XNUMX 回の呼び出しですべてのキーと項目をフェッチすることをお勧めします。 以下はまさにそれを行う例です。

public class Program
{
    public static void Main(string[] args)
    {
        NCache.InitializeCache("myReplicatedCache");
        String query = "SELECT NCacheQuerySample.Business.Product WHERE this.ProductID > 100";
        // Fetch the keys matching this search criteria
        IDictionary dict = NCache.Cache.SearchEntries(query);
        if (dict.Count > 0)
        {
            IDictionaryEnumerator ide = dict.GetEnumerator();
            while (ide.MoveNext())
            {
                String key = (String)ide.Key;
                Product prod = (Product)ide.Value;
                HandleProduct(prod);
                Console.WriteLine("Key = {0}, ProductID: {1}",
                key, prod.ProductID);
            }
        }
        NCache.Cache.Dispose();
    }
}

上記のコードはキャッシュを検索し、キーと値の両方を含む辞書を返します。 このようにして、検索条件に基づくすべてのデータが XNUMX 回の呼び出しで取得されます。 NCache。 これは、キャッシュからすべてのデータをフェッチする方法よりもはるかに効率的な方法です。 Cache.Search().

検索可能な属性のインデックス作成

ということに注意してください NCache すべての検索可能な属性にインデックスを付ける必要があります。 これは、インデックスを作成しないと、 NCache ユーザーが探しているアイテムを見つけるには、キャッシュ全体を走査する必要があります。 そして、これは非常にコストのかかる操作であり、キャッシュ全体の速度が低下し、ユーザーが実行した主な理由が元に戻される可能性があります。 NCacheつまり、アプリケーションのパフォーマンスとスケーラビリティを向上させるためです。

NCache 独自のインデックス作成メカニズムを提供します。 .NET アセンブリ内のインデックスを作成するオブジェクトを識別できます。 次に、データを追加すると、 NCache、これらのオブジェクトを追加しているかどうかを確認します。 そして、そうであれば、.NET Reflection を使用してインデックス付き属性からデータを抽出し、内部インデックスを構築します。 次に、Cache.Search() または Cache.SearchEntries() を使用してキャッシュをクエリすると、 NCache これらのインデックスを使用して、目的のオブジェクトをすばやく見つけて返します。

キャッシュを開始する前にオブジェクト属性のインデックスを作成する
図 1: キャッシュを開始する前のオブジェクト属性のインデックス作成

オブジェクト属性にインデックスを指定すると、追加、挿入、および削除の操作の処理時間が少し増えることに注意してください。 ただし、Get 操作は影響を受けません。

さまざまなキャッシュ トポロジのクエリ

クライアント アプリケーションの観点から見た検索動作は、使用しているキャッシュ トポロジに関係なく同じですが、検索の内部構造はトポロジごとに異なります。 たとえば、レプリケートされたキャッシュで検索を実行している場合、検索はすべて、この検索を開始したキャッシュ サーバー上で実行されます。 これは、キャッシュ全体がそこで利用できるためです。 レプリケートされたキャッシュでクエリがどのように実行されるかを次に示します。

クエリは XNUMX つのサーバー上でローカルに実行されます
図 2: クエリは XNUMX つのサーバー上でローカルに実行されます

ただし、パーティション化またはパーティション化されたレプリカ キャッシュ トポロジを使用している場合、すべてのデータがクラスター内の単一のキャッシュ ノードに存在するわけではありません。 この状況では、クエリが開始されたキャッシュ サーバーは、クラスター内の他のすべてのサーバーにクエリを送信し、ローカルでも実行します。 その後、クエリはすべてのサーバーで並行して実行され、その結果がすべてのノードからこの元のサーバー ノードに返されます。 次に、このサーバー ノードはすべての結果を結合し (「結合」を実行)、クライアントに返します。 以下は、これらすべてを示した図です。

クエリはすべてのサーバー ノードで並行して実行されます
図 3: すべてのサーバー ノードでクエリが並行して実行される

.NET アセンブリ

In NCache、インデックス作成はサーバー ノードで行われます。 しかし、 NCache は、クライアント側で .NET Reflection を使用してオブジェクト属性の値を抽出し、それらをサーバーに送信します。 したがって、オブジェクト定義を含む .NET アセンブリは、アプリケーションが存在するクライアント側でのみ必要となります。 InProc モードで実行している場合でも、OutProc モードで実行している場合でも、アセンブリは、クライアント アプリケーションがアクセスできるディレクトリに存在する必要があります。

さらに、 NCache Java クライアントのオブジェクト クエリ言語もサポートします。

クエリ言語の構文

NCache オブジェクトクエリ言語 (OQL) と呼ばれる SQL に似た言語をサポートします。 この言語の構文は次のとおりです。 NCache.

SELECT NCacheQuerySample.Business.Product WHERE this.ProductID > 100;

SELECT NCacheQuerySample.Business.Product WHERE (this.ProductID != 100 AND this.ProductID <= 200);

SELECT NCacheQuerySample.Business.Product WHERE (this.ProductID == 150 OR this.ProductID == 160);

SELECT NCacheQuerySample.Business.Product WHERE this.ProductID IN (1, 4, 7, 10);

SELECT NCacheQuerySample.Business.Product WHERE this.ProductID NOT IN (1, 4, 7, 10);

SELECT NCacheQuerySample.Business.Employee WHERE this.HiringDate > DateTime.now;

SELECT NCacheQuerySample.Business.Employee WHERE this.HiringDate > DateTime ('01/01/2007');

SELECT NCacheQuerySample.Business.Employee WHERE this.Hired = true;

AND と OR、またはネストされた括弧を使用して、複数の式を組み合わせることができます。 クエリ言語の完全な構文文法を以下に示します。

<Query>                 ::= SELECT <ObjectType> 
                          | SELECT <ObjectType> WHERE <Expression>

<Expression>            ::= <OrExpr>

<OrExpr>                ::= <OrExpr> 'OR' <AndExpr>
                          | <AndExpr>

<AndExpr>               ::= <AndExpr> 'AND' <UnaryExpr>
                          | <UnaryExpr>

<UnaryExpr>             ::= 'NOT'  <CompareExpr>
                          | <CompareExpr>

<CompareExpr>           ::= <Atrrib> '='  <Value>
                          | <Atrrib> '!=' <Value>
                          | <Atrrib> '==' <Value>
                          | <Atrrib> '<>' <Value>
                          | <Atrrib> '<'  <Value>
                          | <Atrrib> '>'  <Value>
                          | <Atrrib> '<=' <Value>
                          | <Atrrib> '>=' <Value>
                          | <Atrrib> 'IN' <InList>
                          | <Atrrib> 'NOT' 'IN' <InList>
                          | '(' <Expression> ')'

<Atrrib>		::= <ObjectValue>                                                    

<Value>                 ::= '-' <NumLiteral> 
                          | <NumLiteral> 
                          | <StrLiteral>
                          | 'true'
                          | 'false'
                          | <Date>

<Date>                  ::= 'DateTime' '.' 'now'
                          | 'DateTime' '(' StringLiteral ')'

<StrLiteral>		::= StringLiteral
			  | 'null'  

<NumLiteral>            ::= IntegerLiteral 
                          | RealLiteral

<ObjectType>            ::= '*' 
                          | <Property>

<Property>		::= <Property> '.' Identifier
			  | Identifier

<ObjectValue>           ::= Keyword '.' Identifier              

<InList>                ::= '(' <ListType> ')'

<ListType>              ::= <NumLiteralList>
                          | <StrLiteralList>
                          | <DateList>

<NumLiteralList>        ::=  <NumLiteral> ',' <NumLiteralList>
                          | <NumLiteral>

<StrLiteralList>        ::= <StrLiteral> ',' <StrLiteralList>
                          | <StrLiteral>

<DateList>              ::= <Date> ',' <DateList>
                          | <Date> 

まとめ

あなたが見たように、 NCache これにより、分散キャッシュへのクエリが非常に簡単になります。 これは、キャッシュをより有意義な方法で使用し、キャッシュ内の内容をより簡単に検索できるようにする強力な機能です。 見てみな。


著者: イクバル・カーンの勤務先 Alachisoft 、.NETおよびJava分散キャッシング、O / Rマッピング、SharePointストレージ最適化ソリューションを提供する大手ソフトウェア会社。 あなたは彼に到達することができます iqbal @alachisoft.COM.

お問い合わせ(英語)

電話
©著作権 Alachisoft 2002 - . All rights reserved. NCache はダイヤテック株式会社の登録商標です。