2016-11-17 6 views
3

2つのサーバーと1つのクライアントからなる起動クラスタをセットアップしました。次のように クラスタ構成は次のとおりです。Apacheの起動時にクエリのパフォーマンスを向上させる方法

IgniteConfiguration icfg = new IgniteConfiguration(); 

icfg.setIncludeEventTypes(EventType.EVT_TASK_STARTED,EventType.EVT_TASK_FINISHED,EventType.EVT_TASK_FAILED); 

icfg.setMetricsUpdateFrequency(-1); 

Ignite ignite = Ignition.start(icfg); 

私はメトリックの更新頻度を無効とのIgniteドキュメントのパフォーマンスのヒントセクションで提案されているように、わずか数のイベント通知を有効にしています。

私は、次の構成で、クラスタ内のキャッシュを作成しました:

CacheConfiguration<Integer,DataPOJO> cacheConfiguration = new CacheConfiguration<>(); 

cacheConfiguration.setStatisticsEnabled(false); 

cacheConfiguration.setName("testCache"); 

私は100の000のエントリでクライアントからキャッシュをロードしています。

import java.io.Externalizable; 
import java.io.IOException; 
import java.io.ObjectInput; 
import java.io.ObjectOutput; 
import java.sql.Date; 

import org.apache.ignite.binary.BinaryObjectException; 
import org.apache.ignite.binary.BinaryReader; 
import org.apache.ignite.binary.BinaryWriter; 
import org.apache.ignite.binary.Binarylizable; 
import org.apache.ignite.cache.query.annotations.QuerySqlField; 

public class DataPOJO implements Externalizable,Binarylizable{ 

    private static final long serialVersionUID = 1L; 

    @QuerySqlField(index = true) 
    private int primaryKey; 

    @QuerySqlField 
    private int foreignKey1; 

    @QuerySqlField 
    private int foreignKey2; 

    @QuerySqlField 
    private String stringField1; 

    @QuerySqlField 
    private String stringField2; 

    @QuerySqlField 
    private String stringField3; 

    @QuerySqlField 
    private Date dateField; 

    @QuerySqlField(index = true) 
    private String stringField4; 

    public int getPrimaryKey() { 
     return primaryKey; 
    } 

    public void setPrimaryKey(int primaryKey) { 
     this.primaryKey = primaryKey; 
    } 

    public int getForeignKey1() { 
     return foreignKey1; 
    } 

    public void setForeignKey1(int foreignKey1) { 
     this.foreignKey1 = foreignKey1; 
    } 

    public int getForeignKey2() { 
     return foreignKey2; 
    } 

    public void setForeignKey2(int foreignKey2) { 
     this.foreignKey2 = foreignKey2; 
    } 

    public String getStringField1() { 
     return stringField1; 
    } 

    public void setStringField1(String stringField1) { 
     this.stringField1 = stringField1; 
    } 

    public String getStringField2() { 
     return stringField2; 
    } 

    public void setStringField2(String stringField2) { 
     this.stringField2 = stringField2; 
    } 

    public String getStringField3() { 
     return stringField3; 
    } 

    public void setStringField3(String stringField3) { 
     this.stringField3 = stringField3; 
    } 

    public Date getDateField() { 
     return dateField; 
    } 

    public void setDateField(Date dateField) { 
     this.dateField = dateField; 
    } 

    public String getStringField4() { 
     return stringField4; 
    } 

    public void setStringField4(String stringField4) { 
     this.stringField4 = stringField4; 
    } 

    @Override 
    public String toString() { 
     return "DataPOJO [primaryKey=" + primaryKey + ", foreignKey1=" + foreignKey1 + ", foreignKey2=" + foreignKey2 
       + ", stringField1=" + stringField1 + ", stringField2=" + stringField2 + ", stringField3=" + stringField3 
       + ", dateField=" + dateField + ", stringField4=" + stringField4 + "]"; 
    } 

    @Override 
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { 
     primaryKey = in.readInt(); 
     foreignKey1 = in.readInt(); 
     foreignKey2 = in.readInt(); 
     stringField1 = (String) in.readObject(); 
     stringField2 = (String) in.readObject(); 
     stringField3 = (String) in.readObject(); 
     stringField4 = (String) in.readObject(); 
     dateField = (Date) in.readObject(); 
    } 

    @Override 
    public void writeExternal(ObjectOutput out) throws IOException { 
     out.writeInt(primaryKey); 
     out.writeInt(foreignKey1); 
     out.writeInt(foreignKey2); 
     out.writeObject(stringField1); 
     out.writeObject(stringField2); 
     out.writeObject(stringField3); 
     out.writeObject(stringField4); 
     out.writeObject(dateField); 
    } 

    @Override 
    public void writeBinary(BinaryWriter writer) throws BinaryObjectException { 
     writer.writeInt("primarykey",primaryKey); 
     writer.writeInt("foreignkey1",foreignKey1); 
     writer.writeInt("foreignkey2",foreignKey2); 
     writer.writeString("stringField1",stringField1); 
     writer.writeString("stringField2",stringField2); 
     writer.writeString("stringField3",stringField3); 
     writer.writeString("stringField4",stringField4); 
     writer.writeDate("dateField",new java.util.Date(dateField.getTime())); 
    } 

    @Override 
    public void readBinary(BinaryReader reader) throws BinaryObjectException { 
     primaryKey = reader.readInt("primarykey"); 
     foreignKey1 = reader.readInt("foreignkey1"); 
     foreignKey2 = reader.readInt("foreignkey2"); 
     stringField1 = reader.readString("stringField1"); 
     stringField2 = reader.readString("stringField2"); 
     stringField3 = reader.readString("stringField3"); 
     stringField4 = reader.readString("stringField4"); 
     dateField = new Date(reader.readDate("dateField").getTime()); 
    } 

} 

私はそれがパフォーマンスを妨げるようにjava.io.Serializableを利用するようにしたくなかった、次のように

使用POJOクラスのコードです。私は、 "primaryKey"と "stringField4"という2つのフィールドにインデックスを作成しました。

フィールドstringField4は、すべてのエントリのフィールドprimaryKeyの文字列表現になります。 primaryKey = 1の場合、stringField4 = "1"。

primaryKeyは、キャッシュ内のanyエントリのキーです。

私がクライアントから実行したクエリは、フィールドstringField4の10,000の値に基づいてキャッシュから10,000エントリをフェッチすることでした。 次のようにクエリは次のとおりです。平均で

IgniteCache<Integer,DataPOJO> testCache= ignite.getOrCreateCache("testCache"); 

SqlQuery<Integer,DataPOJO> query = new SqlQuery<>(DataPOJO.class,"stringField4 = ?"); 

long startTime,totalTimeElapsed = 0; 

QueryCursor<Entry<Integer,DataPOJO>> cursor; 

for(int i=1;i<=10000;i++){ 

    startTime = System.nanoTime(); 

    cursor = testCache.query(query.setArgs(i)); 

    for(Entry<Integer,DataPOJO> entry : cursor){ 
     System.out.println("Entry fetched with key "+entry.getKey()); 
     totalTimeElapsed += System.nanoTime() - startTime; 
    } 
} 

System.out.println("Total time taken to execute query is "+totalTimeElapsed+"ns"); 

すべてのクエリを実行するために9〜10秒を要しました。

与えられたデータに基づいて、Can Igniteは100〜200ミリ秒で同じ結果を返しますか?パフォーマンスを向上させるためにIgnite Docs(これらすべてを試しました)に記載されている以外のクラスタ構成またはキャッシュ構成を作成できますか?

これはキーベースのフェッチではなく、クエリよりも高速です。

答えて

0

インデックスが使用されている場合ははるかに速くなければなりません。 EXPLAINを実行して実行計画を確認することをお勧めします。

+0

クイック返信ありがとう@Valentin。私は、インデックス付きのタイプを設定していると、次のようにクエリのいずれかのH2計画がある: –

+0

は[[__C0 AS DATAPOJO._KEY、__C1 AS DATAPOJO._VAL、__C2 AS DATAPOJO.PRIMARYKEY、__C3 AS DATAPOJO.FOREIGNKEY1を選択します__C4、 DATAPOJO.STRINGFIELD1 AS __C5、 DATAPOJO.STRINGFIELD2 AS __C6、 DATAPOJO.STRINGFIELD3 AS __C7、__C8、 "cache1" .DATAPOJO FROM DATAPOJO.STRINGFIELD4 AS __C9 AS DATAPOJO.DATEFIELD AS、 DATAPOJO.FOREIGNKEY2/* "cache1"。"stringField4_idx":STRINGFIELD4 STRINGFIELD4 = 1] –

+0

、[STRINGFIELD1 AS FOREIGNKEY2、 __C5 AS FOREIGNKEY1、 __C4 AS PRIMARYKEY、 __C3 AS _val、 __C2 AS _key、 __C1 AS __C0をSELECT */ = 1?は? 、STRINGFIELD2 AS __C6、STRINGFIELD3 AS __C7、日付フィールドAS __C8、PUBLIC .__ T0 FROM STRINGFIELD4 AS __C9 /* "cache1"。 "merge_scan" * /]] –

1

クエリが無限に実行されていたのと同じ問題に直面していました。だから私は正しい秒数でクエリを実行するために正しいインデックスを使用しますので、あなたのクエリを説明するプランをチェックし、適切な個別またはグループ化されたインデックスを置くことがわかったらクエリ実行プランでフルキャッシュスキャンがあることを確認してください。 1つのクエリとそのExplainプランを共有できる場合は、モードのアイデアを与えることができます。

+0

私は@Valentinと私の質問のクエリにコメントの説明を共有している –

+0

@AnikethJainあなたは私たちがあなたのために助けることができるクエリをsooを共有してくださいすることができます –

+0

私の質問を参照してください。とにかくここにはクエリがあります:SqlQuery query =新しいSqlQuery <>(DataPOJO.class、 "stringField4 =?"); –

関連する問題