|
| 1 | +# bulkbench |
| 2 | + |
| 3 | +bulkbench was created in the context of a performance / throughput analysis of different hdb client implementations. |
| 4 | + |
| 5 | +## Test object |
| 6 | + |
| 7 | +Test object is a column table consisting of 2 columns, one of type integer and one of type double: |
| 8 | + |
| 9 | +``` |
| 10 | +create column table <TableName> (id integer, field double) |
| 11 | +``` |
| 12 | + |
| 13 | +## Test variants |
| 14 | + |
| 15 | +The basic idea is to insert data in chunks (batchCount) of a fixed amount of records (batchSize) whether sequentially or 'in parallel'. |
| 16 | +The actual 'grade of parallelization' is heavily depending on the test environment (CPU cores, TCP/IP stack). bulkbench 'enables' |
| 17 | +potential parallelism 'idiomatically' via Goroutines. Each Goroutine is using an own dedicated database connection for the tests |
| 18 | +being independent of the Go sql.DB connection pool handling and configuration. |
| 19 | +As the test performance results are heavily 'I/O bound' the implementation mainly tries to reduce client server round-trips. Therefore |
| 20 | +the go-hdb driver bulk insert capabilities are used (please refer to the [go-hdb driver documentation and examples](https://github.com/SAP/go-hdb) |
| 21 | +for details). |
| 22 | + |
| 23 | +## In a real world example... |
| 24 | + |
| 25 | +... one might consider |
| 26 | + |
| 27 | +* to implement a worker pool with the number of concurrent workers set in relation to GOMAXPROCS |
| 28 | +* optimizing the number of records per chunk (batchSize) |
| 29 | +* optimizing the go-hdb driver TCP/IP buffer size. |
| 30 | + * all writes to the TCP/IP connection are buffered by the go-hdb client |
| 31 | + * the buffer size can be configured via the driver.Connector object (BufferSize) |
| 32 | + * when reaching the buffer size, the go-hdb driver writes the buffered data to the TCP/IP connection |
| 33 | + |
| 34 | +## Execute tests |
| 35 | + |
| 36 | +**Caution: please do NOT use a productive HANA instance for testing as bulkbench does create schemas and database tables.** |
| 37 | + |
| 38 | +Executing bulkbench starts a HTTP server on 'localhost:8080'. |
| 39 | + |
| 40 | +After starting a browser pointing to the server address the following HTML page should be visible in the browser window: |
| 41 | + |
| 42 | + |
| 43 | + |
| 44 | +* the first section displays some runtime information like GOMAXPROCS and the driver and database version |
| 45 | +* the second section lists all test relevant parameters which can be set as environment variables or commandline parameters |
| 46 | +* the third sections allows to execute tests with predefined BatchCount and BatchSize parameters (see parameters command-line flag) |
| 47 | +* the last section provides some database operations for the selected test database schema and table |
| 48 | + |
| 49 | +Clicking on one of the predefined test will execute it and display the result consisting of test parameters and the duration in seconds. |
| 50 | +The result is a JSON payload, which provides an easy way to be interpreted by a program. |
| 51 | + |
| 52 | +## URL format |
| 53 | + |
| 54 | +Running bulkbench as HTTP server a test can be executed via a HTTP GET using the following URL format: |
| 55 | + |
| 56 | +``` |
| 57 | +http://<host>:<port>/test/<TestType>?batchcount=<number>&batchsize=<number> |
| 58 | +``` |
| 59 | +with |
| 60 | +``` |
| 61 | +<TestType> =:= Seq | Par |
| 62 | +``` |
| 63 | + |
| 64 | +## Benchmark |
| 65 | + |
| 66 | +Parallel to the single execution using the browser or any other HTTP client (like wget, curl, ...), the tests can be executed automatically |
| 67 | +as Go benchmark. The benchmark can be executed whether by |
| 68 | +``` |
| 69 | +go test -bench . |
| 70 | +``` |
| 71 | +or compiling the benchmark with |
| 72 | +``` |
| 73 | +go test -c |
| 74 | +``` |
| 75 | +and executing it via |
| 76 | +``` |
| 77 | +./bulkbench.test -test.bench . |
| 78 | +``` |
| 79 | + |
| 80 | +The benchmark is 'self-contained', meaning it includes its own http server (for details please see [httptest](https://golang.org/pkg/net/http/httptest/). |
| 81 | + |
| 82 | +In addition to the standard Go benchmarks four additional metrics are reported: |
| 83 | +* avgsec/op: the average time (*) |
| 84 | +* maxsec/op: the maximum time (*) |
| 85 | +* medsec/op: the median time (*) |
| 86 | +* minsec/op: the minimal time (*) |
| 87 | + |
| 88 | +(*) inserting BatchCount x BatchSize records into the database table when executing one test several times. |
| 89 | + |
| 90 | +For details about Go benchmarks please see the [Golang testing documentation](https://golang.org/pkg/testing). |
| 91 | + |
| 92 | +### Benchmark examples |
| 93 | + |
| 94 | +Finally let's see some examples executing the benchmark. |
| 95 | + |
| 96 | +``` |
| 97 | +export GOHDBDSN="hdb://MyUser:MyPassword@host:port" |
| 98 | +go test -c |
| 99 | +``` |
| 100 | + |
| 101 | +* set the data source name (dsn) via environment variable |
| 102 | +* and compile the benchmark |
| 103 | + |
| 104 | + |
| 105 | +``` |
| 106 | +./bulkbench.test -test.bench . -test.benchtime 10x |
| 107 | +``` |
| 108 | + |
| 109 | +* -test.bench . (run all benchmarks) |
| 110 | +* -test.benchtime 10x (run each benchmark ten times) |
| 111 | +* run benchmarks for all BatchCount / BatchSize combinations defined as parameters |
| 112 | +* the test database table is dropped and re-created before each benchmark execution (command-line parameter drop defaults to true) |
| 113 | + |
| 114 | +``` |
| 115 | +./bulkbench.test -test.bench . -test.benchtime 10x -parameters "10x10000" |
| 116 | +``` |
| 117 | +* same like before but |
| 118 | +* execute benchmarks only for 10x10000 as BatchCount / BatchSize combination |
| 119 | + |
| 120 | +``` |
| 121 | +./bulkbench.test -test.bench . -test.benchtime 10x -wait 5 |
| 122 | +``` |
| 123 | + |
| 124 | +* same like first example and |
| 125 | +* -wait 5 (wait 5 seconds before starting a benchmark run to reduce database pressure) |
| 126 | + |
| 127 | +### Benchmark example output |
| 128 | + |
| 129 | +``` |
| 130 | +./bulkbench.test -test.bench . -test.benchtime 10x -wait 5 |
| 131 | +
|
| 132 | +GOMAXPROCS: 8 |
| 133 | +NumCPU: 8 |
| 134 | +Driver Version: 0.110.0 |
| 135 | +HANA Version: 2.00.045.00.1575639312 |
| 136 | +goos: darwin |
| 137 | +goarch: arm64 |
| 138 | +pkg: github.com/SAP/go-hdb/cmd/bulkbench |
| 139 | +Benchmark/seq-1x100000-8 10 5633601117 ns/op 0.2156 avgsec/op 0.2486 maxsec/op 0.2155 medsec/op 0.1947 minsec/op |
| 140 | +Benchmark/seq-10x10000-8 10 5699490917 ns/op 0.2786 avgsec/op 0.3108 maxsec/op 0.2803 medsec/op 0.2559 minsec/op |
| 141 | +Benchmark/seq-100x1000-8 10 6165608862 ns/op 0.7506 avgsec/op 0.8077 maxsec/op 0.7440 medsec/op 0.6990 minsec/op |
| 142 | +Benchmark/seq-1x1000000-8 10 6938632171 ns/op 1.514 avgsec/op 1.629 maxsec/op 1.515 medsec/op 1.407 minsec/op |
| 143 | +Benchmark/seq-10x100000-8 10 7054997538 ns/op 1.636 avgsec/op 1.725 maxsec/op 1.622 medsec/op 1.536 minsec/op |
| 144 | +Benchmark/seq-100x10000-8 10 7810094800 ns/op 2.397 avgsec/op 2.557 maxsec/op 2.411 medsec/op 2.262 minsec/op |
| 145 | +Benchmark/seq-1000x1000-8 10 12483512412 ns/op 7.064 avgsec/op 7.356 maxsec/op 7.038 medsec/op 6.812 minsec/op |
| 146 | +Benchmark/par-1x100000-8 10 5599063146 ns/op 0.2224 avgsec/op 0.2483 maxsec/op 0.2207 medsec/op 0.2002 minsec/op |
| 147 | +Benchmark/par-10x10000-8 10 5897479183 ns/op 0.1346 avgsec/op 0.1571 maxsec/op 0.1305 medsec/op 0.1186 minsec/op |
| 148 | +Benchmark/par-100x1000-8 10 9334510842 ns/op 0.2375 avgsec/op 0.2488 maxsec/op 0.2389 medsec/op 0.2175 minsec/op |
| 149 | +Benchmark/par-1x1000000-8 10 6892064029 ns/op 1.451 avgsec/op 1.581 maxsec/op 1.434 medsec/op 1.361 minsec/op |
| 150 | +Benchmark/par-10x100000-8 10 6699703246 ns/op 0.9531 avgsec/op 1.022 maxsec/op 0.9434 medsec/op 0.9004 minsec/op |
| 151 | +Benchmark/par-100x10000-8 10 10699403688 ns/op 0.9221 avgsec/op 0.9838 maxsec/op 0.9181 medsec/op 0.8722 minsec/op |
| 152 | +Benchmark/par-1000x1000-8 10 50726314071 ns/op 2.204 avgsec/op 2.301 maxsec/op 2.216 medsec/op 2.096 minsec/op |
| 153 | +PASS |
| 154 | +``` |
0 commit comments