You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@ignite.apache.org by "Alexander Lapin (Jira)" <ji...@apache.org> on 2022/06/10 15:36:00 UTC

[jira] [Updated] (IGNITE-17155) JDBC-based benchmaeks performance issue

     [ https://issues.apache.org/jira/browse/IGNITE-17155?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Alexander Lapin updated IGNITE-17155:
-------------------------------------
    Description: 
According to the latest benchmarks IGNITE_GET_METADATA_LOCALLY_ONLY doesn't effect JDBC performance at all: 
{code:java}
3 node
without IGNITE_GET_METADATA_LOCALLY_ONLY:   15.1 req/sec
with IGNITE_GET_METADATA_LOCALLY_ONLY=true: 14.3 req/sec
1 node
without IGNITE_GET_METADATA_LOCALLY_ONLY:   9.5 req/sec
with IGNITE_GET_METADATA_LOCALLY_ONLY=true: 10.6 req/sec{code}
Fist af all it's required to check how sql engine synchronizes table meta, seems that it skips our common IGNITE_GET_METADATA_LOCALLY_ONLY aware directProxy approach.

Benchmark itself:
{code:java}
class YCSBWorker extends Worker<YCSBBenchmark> {    private final ZipfianGenerator readRecord;
    private static CounterGenerator insertRecord;
    private final ZipfianGenerator randScan;    private final char[] data = new char[YCSBConstants.FIELD_SIZE];
    private final String[] params = new String[YCSBConstants.NUM_FIELDS];
    private final String[] results = new String[YCSBConstants.NUM_FIELDS];    private final UpdateRecord procUpdateRecord;
    private final ScanRecord procScanRecord;
    private final ReadRecord procReadRecord;
    private final ReadModifyWriteRecord procReadModifyWriteRecord;
    private final InsertRecord procInsertRecord;
    private final DeleteRecord procDeleteRecord;    public YCSBWorker(YCSBBenchmark benchmarkModule, int id, int init_record_count) {
        super(benchmarkModule, id);
        readRecord = new ZipfianGenerator(init_record_count);// pool for read keys
        randScan = new ZipfianGenerator(YCSBConstants.MAX_SCAN);        synchronized (YCSBWorker.class) {
            // We must know where to start inserting
            if (insertRecord == null) {
                insertRecord = new CounterGenerator(init_record_count);
            }
        }        // This is a minor speed-up to avoid having to invoke the hashmap look-up
        // everytime we want to execute a txn. This is important to do on 
        // a client machine with not a lot of cores
        this.procUpdateRecord = this.getProcedure(UpdateRecord.class);
        this.procScanRecord = this.getProcedure(ScanRecord.class);
        this.procReadRecord = this.getProcedure(ReadRecord.class);
        this.procReadModifyWriteRecord = this.getProcedure(ReadModifyWriteRecord.class);
        this.procInsertRecord = this.getProcedure(InsertRecord.class);
        this.procDeleteRecord = this.getProcedure(DeleteRecord.class);
    }    @Override
    protected TransactionStatus executeWork(Connection conn, TransactionType nextTrans) throws UserAbortException, SQLException {
        Class<? extends Procedure> procClass = nextTrans.getProcedureClass();        if (procClass.equals(DeleteRecord.class)) {
            deleteRecord(conn);
        } else if (procClass.equals(InsertRecord.class)) {
            insertRecord(conn);
        } else if (procClass.equals(ReadModifyWriteRecord.class)) {
            readModifyWriteRecord(conn);
        } else if (procClass.equals(ReadRecord.class)) {
            readRecord(conn);
        } else if (procClass.equals(ScanRecord.class)) {
            scanRecord(conn);
        } else if (procClass.equals(UpdateRecord.class)) {
            updateRecord(conn);
        }
        return (TransactionStatus.SUCCESS);
    }    private void updateRecord(Connection conn) throws SQLException {        int keyname = readRecord.nextInt();
        this.buildParameters();
        this.procUpdateRecord.run(conn, keyname, this.params);
    }    private void scanRecord(Connection conn) throws SQLException {        int keyname = readRecord.nextInt();
        int count = randScan.nextInt();
        this.procScanRecord.run(conn, keyname, count, new ArrayList<>());
    }    private void readRecord(Connection conn) throws SQLException {        int keyname = readRecord.nextInt();
        this.procReadRecord.run(conn, keyname, this.results);
    }    private void readModifyWriteRecord(Connection conn) throws SQLException {        int keyname = readRecord.nextInt();
        this.buildParameters();
        this.procReadModifyWriteRecord.run(conn, keyname, this.params, this.results);
    }    private void insertRecord(Connection conn) throws SQLException {        int keyname = insertRecord.nextInt();
        this.buildParameters();
        this.procInsertRecord.run(conn, keyname, this.params);
    }    private void deleteRecord(Connection conn) throws SQLException {        int keyname = readRecord.nextInt();
        this.procDeleteRecord.run(conn, keyname);
    }    private void buildParameters() {
        Random rng = rng();
        for (int i = 0; i < this.params.length; i++) {
            this.params[i] = new String(TextGenerator.randomFastChars(rng, this.data));
        }
    }
} {code}

  was:
According to the latest benchmarks IGNITE_GET_METADATA_LOCALLY_ONLY doesn't effect JDBC performance at all:
{code:java}
3 node
without IGNITE_GET_METADATA_LOCALLY_ONLY:   15.1 req/sec
with IGNITE_GET_METADATA_LOCALLY_ONLY=true: 14.3 req/sec
1 node
without IGNITE_GET_METADATA_LOCALLY_ONLY:   9.5 req/sec
with IGNITE_GET_METADATA_LOCALLY_ONLY=true: 10.6 req/sec{code}
Fist af all it's required to check how sql engine synchronizes table meta, seems that it skips our common IGNITE_GET_METADATA_LOCALLY_ONLY aware directProxy approach.

Benchmark itself:
{code:java}
class YCSBWorker extends Worker<YCSBBenchmark> {    private final ZipfianGenerator readRecord;
    private static CounterGenerator insertRecord;
    private final ZipfianGenerator randScan;    private final char[] data = new char[YCSBConstants.FIELD_SIZE];
    private final String[] params = new String[YCSBConstants.NUM_FIELDS];
    private final String[] results = new String[YCSBConstants.NUM_FIELDS];    private final UpdateRecord procUpdateRecord;
    private final ScanRecord procScanRecord;
    private final ReadRecord procReadRecord;
    private final ReadModifyWriteRecord procReadModifyWriteRecord;
    private final InsertRecord procInsertRecord;
    private final DeleteRecord procDeleteRecord;    public YCSBWorker(YCSBBenchmark benchmarkModule, int id, int init_record_count) {
        super(benchmarkModule, id);
        readRecord = new ZipfianGenerator(init_record_count);// pool for read keys
        randScan = new ZipfianGenerator(YCSBConstants.MAX_SCAN);        synchronized (YCSBWorker.class) {
            // We must know where to start inserting
            if (insertRecord == null) {
                insertRecord = new CounterGenerator(init_record_count);
            }
        }        // This is a minor speed-up to avoid having to invoke the hashmap look-up
        // everytime we want to execute a txn. This is important to do on 
        // a client machine with not a lot of cores
        this.procUpdateRecord = this.getProcedure(UpdateRecord.class);
        this.procScanRecord = this.getProcedure(ScanRecord.class);
        this.procReadRecord = this.getProcedure(ReadRecord.class);
        this.procReadModifyWriteRecord = this.getProcedure(ReadModifyWriteRecord.class);
        this.procInsertRecord = this.getProcedure(InsertRecord.class);
        this.procDeleteRecord = this.getProcedure(DeleteRecord.class);
    }    @Override
    protected TransactionStatus executeWork(Connection conn, TransactionType nextTrans) throws UserAbortException, SQLException {
        Class<? extends Procedure> procClass = nextTrans.getProcedureClass();        if (procClass.equals(DeleteRecord.class)) {
            deleteRecord(conn);
        } else if (procClass.equals(InsertRecord.class)) {
            insertRecord(conn);
        } else if (procClass.equals(ReadModifyWriteRecord.class)) {
            readModifyWriteRecord(conn);
        } else if (procClass.equals(ReadRecord.class)) {
            readRecord(conn);
        } else if (procClass.equals(ScanRecord.class)) {
            scanRecord(conn);
        } else if (procClass.equals(UpdateRecord.class)) {
            updateRecord(conn);
        }
        return (TransactionStatus.SUCCESS);
    }    private void updateRecord(Connection conn) throws SQLException {        int keyname = readRecord.nextInt();
        this.buildParameters();
        this.procUpdateRecord.run(conn, keyname, this.params);
    }    private void scanRecord(Connection conn) throws SQLException {        int keyname = readRecord.nextInt();
        int count = randScan.nextInt();
        this.procScanRecord.run(conn, keyname, count, new ArrayList<>());
    }    private void readRecord(Connection conn) throws SQLException {        int keyname = readRecord.nextInt();
        this.procReadRecord.run(conn, keyname, this.results);
    }    private void readModifyWriteRecord(Connection conn) throws SQLException {        int keyname = readRecord.nextInt();
        this.buildParameters();
        this.procReadModifyWriteRecord.run(conn, keyname, this.params, this.results);
    }    private void insertRecord(Connection conn) throws SQLException {        int keyname = insertRecord.nextInt();
        this.buildParameters();
        this.procInsertRecord.run(conn, keyname, this.params);
    }    private void deleteRecord(Connection conn) throws SQLException {        int keyname = readRecord.nextInt();
        this.procDeleteRecord.run(conn, keyname);
    }    private void buildParameters() {
        Random rng = rng();
        for (int i = 0; i < this.params.length; i++) {
            this.params[i] = new String(TextGenerator.randomFastChars(rng, this.data));
        }
    }
} {code}


> JDBC-based benchmaeks performance issue
> ---------------------------------------
>
>                 Key: IGNITE-17155
>                 URL: https://issues.apache.org/jira/browse/IGNITE-17155
>             Project: Ignite
>          Issue Type: Task
>            Reporter: Alexander Lapin
>            Priority: Major
>              Labels: ignite-3
>
> According to the latest benchmarks IGNITE_GET_METADATA_LOCALLY_ONLY doesn't effect JDBC performance at all: 
> {code:java}
> 3 node
> without IGNITE_GET_METADATA_LOCALLY_ONLY:   15.1 req/sec
> with IGNITE_GET_METADATA_LOCALLY_ONLY=true: 14.3 req/sec
> 1 node
> without IGNITE_GET_METADATA_LOCALLY_ONLY:   9.5 req/sec
> with IGNITE_GET_METADATA_LOCALLY_ONLY=true: 10.6 req/sec{code}
> Fist af all it's required to check how sql engine synchronizes table meta, seems that it skips our common IGNITE_GET_METADATA_LOCALLY_ONLY aware directProxy approach.
> Benchmark itself:
> {code:java}
> class YCSBWorker extends Worker<YCSBBenchmark> {    private final ZipfianGenerator readRecord;
>     private static CounterGenerator insertRecord;
>     private final ZipfianGenerator randScan;    private final char[] data = new char[YCSBConstants.FIELD_SIZE];
>     private final String[] params = new String[YCSBConstants.NUM_FIELDS];
>     private final String[] results = new String[YCSBConstants.NUM_FIELDS];    private final UpdateRecord procUpdateRecord;
>     private final ScanRecord procScanRecord;
>     private final ReadRecord procReadRecord;
>     private final ReadModifyWriteRecord procReadModifyWriteRecord;
>     private final InsertRecord procInsertRecord;
>     private final DeleteRecord procDeleteRecord;    public YCSBWorker(YCSBBenchmark benchmarkModule, int id, int init_record_count) {
>         super(benchmarkModule, id);
>         readRecord = new ZipfianGenerator(init_record_count);// pool for read keys
>         randScan = new ZipfianGenerator(YCSBConstants.MAX_SCAN);        synchronized (YCSBWorker.class) {
>             // We must know where to start inserting
>             if (insertRecord == null) {
>                 insertRecord = new CounterGenerator(init_record_count);
>             }
>         }        // This is a minor speed-up to avoid having to invoke the hashmap look-up
>         // everytime we want to execute a txn. This is important to do on 
>         // a client machine with not a lot of cores
>         this.procUpdateRecord = this.getProcedure(UpdateRecord.class);
>         this.procScanRecord = this.getProcedure(ScanRecord.class);
>         this.procReadRecord = this.getProcedure(ReadRecord.class);
>         this.procReadModifyWriteRecord = this.getProcedure(ReadModifyWriteRecord.class);
>         this.procInsertRecord = this.getProcedure(InsertRecord.class);
>         this.procDeleteRecord = this.getProcedure(DeleteRecord.class);
>     }    @Override
>     protected TransactionStatus executeWork(Connection conn, TransactionType nextTrans) throws UserAbortException, SQLException {
>         Class<? extends Procedure> procClass = nextTrans.getProcedureClass();        if (procClass.equals(DeleteRecord.class)) {
>             deleteRecord(conn);
>         } else if (procClass.equals(InsertRecord.class)) {
>             insertRecord(conn);
>         } else if (procClass.equals(ReadModifyWriteRecord.class)) {
>             readModifyWriteRecord(conn);
>         } else if (procClass.equals(ReadRecord.class)) {
>             readRecord(conn);
>         } else if (procClass.equals(ScanRecord.class)) {
>             scanRecord(conn);
>         } else if (procClass.equals(UpdateRecord.class)) {
>             updateRecord(conn);
>         }
>         return (TransactionStatus.SUCCESS);
>     }    private void updateRecord(Connection conn) throws SQLException {        int keyname = readRecord.nextInt();
>         this.buildParameters();
>         this.procUpdateRecord.run(conn, keyname, this.params);
>     }    private void scanRecord(Connection conn) throws SQLException {        int keyname = readRecord.nextInt();
>         int count = randScan.nextInt();
>         this.procScanRecord.run(conn, keyname, count, new ArrayList<>());
>     }    private void readRecord(Connection conn) throws SQLException {        int keyname = readRecord.nextInt();
>         this.procReadRecord.run(conn, keyname, this.results);
>     }    private void readModifyWriteRecord(Connection conn) throws SQLException {        int keyname = readRecord.nextInt();
>         this.buildParameters();
>         this.procReadModifyWriteRecord.run(conn, keyname, this.params, this.results);
>     }    private void insertRecord(Connection conn) throws SQLException {        int keyname = insertRecord.nextInt();
>         this.buildParameters();
>         this.procInsertRecord.run(conn, keyname, this.params);
>     }    private void deleteRecord(Connection conn) throws SQLException {        int keyname = readRecord.nextInt();
>         this.procDeleteRecord.run(conn, keyname);
>     }    private void buildParameters() {
>         Random rng = rng();
>         for (int i = 0; i < this.params.length; i++) {
>             this.params[i] = new String(TextGenerator.randomFastChars(rng, this.data));
>         }
>     }
> } {code}



--
This message was sent by Atlassian Jira
(v8.20.7#820007)