vitess.io/vitess@v0.16.2/go/mysql/query_benchmark_test.go (about)

     1  /*
     2  Copyright 2019 The Vitess Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package mysql
    18  
    19  import (
    20  	"context"
    21  	"math/rand"
    22  	"net"
    23  	"strings"
    24  	"testing"
    25  )
    26  
    27  // Override the default here to test with different values.
    28  var testReadConnBufferSize = connBufferSize
    29  
    30  const benchmarkQueryPrefix = "benchmark "
    31  
    32  type mkListenerCfg func(AuthServer, Handler) ListenerConfig
    33  
    34  func mkDefaultListenerCfg(authServer AuthServer, handler Handler) ListenerConfig {
    35  	return ListenerConfig{
    36  		Protocol:           "tcp",
    37  		Address:            "127.0.0.1:",
    38  		AuthServer:         authServer,
    39  		Handler:            handler,
    40  		ConnReadBufferSize: testReadConnBufferSize,
    41  	}
    42  }
    43  
    44  func mkReadBufferPoolingCfg(authServer AuthServer, handler Handler) ListenerConfig {
    45  	cfg := mkDefaultListenerCfg(authServer, handler)
    46  	cfg.ConnBufferPooling = true
    47  	return cfg
    48  }
    49  
    50  func benchmarkQuery(b *testing.B, threads int, query string, mkCfg mkListenerCfg) {
    51  	th := &testHandler{}
    52  
    53  	authServer := NewAuthServerNone()
    54  
    55  	lCfg := mkCfg(authServer, th)
    56  
    57  	l, err := NewListenerWithConfig(lCfg)
    58  	if err != nil {
    59  		b.Fatalf("NewListener failed: %v", err)
    60  	}
    61  	defer l.Close()
    62  
    63  	go func() {
    64  		l.Accept()
    65  	}()
    66  
    67  	b.SetParallelism(threads)
    68  	if query != "" {
    69  		b.SetBytes(int64(len(query)))
    70  	}
    71  
    72  	host := l.Addr().(*net.TCPAddr).IP.String()
    73  	port := l.Addr().(*net.TCPAddr).Port
    74  	params := &ConnParams{
    75  		Host:  host,
    76  		Port:  port,
    77  		Uname: "user1",
    78  		Pass:  "password1",
    79  	}
    80  	ctx := context.Background()
    81  
    82  	b.ResetTimer()
    83  
    84  	// MaxPacketSize is too big for benchmarks, so choose something smaller
    85  	maxPacketSize := connBufferSize * 4
    86  
    87  	b.RunParallel(func(pb *testing.PB) {
    88  		conn, err := Connect(ctx, params)
    89  		if err != nil {
    90  			b.Fatal(err)
    91  		}
    92  		defer func() {
    93  			conn.writeComQuit()
    94  			conn.Close()
    95  		}()
    96  
    97  		for pb.Next() {
    98  			execQuery := query
    99  			if execQuery == "" {
   100  				// generate random query
   101  				n := rand.Intn(maxPacketSize-len(benchmarkQueryPrefix)) + 1
   102  				execQuery = benchmarkQueryPrefix + strings.Repeat("x", n)
   103  
   104  			}
   105  			if _, err := conn.ExecuteFetch(execQuery, 1000, true); err != nil {
   106  				b.Fatalf("ExecuteFetch failed: %v", err)
   107  			}
   108  		}
   109  	})
   110  }
   111  
   112  // This file contains various long-running tests for mysql.
   113  
   114  // BenchmarkParallelShortQueries creates N simultaneous connections, then
   115  // executes M queries on them, then closes them.
   116  // It is meant as a somewhat real load test.
   117  func BenchmarkParallelShortQueries(b *testing.B) {
   118  	benchmarkQuery(b, 10, benchmarkQueryPrefix+"select rows", mkDefaultListenerCfg)
   119  }
   120  
   121  func BenchmarkParallelMediumQueries(b *testing.B) {
   122  	benchmarkQuery(
   123  		b,
   124  		10,
   125  		benchmarkQueryPrefix+"select"+strings.Repeat("x", connBufferSize),
   126  		mkDefaultListenerCfg,
   127  	)
   128  }
   129  
   130  func BenchmarkParallelRandomQueries(b *testing.B) {
   131  	benchmarkQuery(b, 10, "", mkDefaultListenerCfg)
   132  }
   133  
   134  func BenchmarkParallelShortQueriesWithReadBufferPooling(b *testing.B) {
   135  	benchmarkQuery(b, 10, benchmarkQueryPrefix+"select rows", mkReadBufferPoolingCfg)
   136  }
   137  
   138  func BenchmarkParallelMediumQueriesWithReadBufferPooling(b *testing.B) {
   139  	benchmarkQuery(
   140  		b,
   141  		10,
   142  		benchmarkQueryPrefix+"select"+strings.Repeat("x", connBufferSize),
   143  		mkReadBufferPoolingCfg,
   144  	)
   145  }
   146  
   147  func BenchmarkParallelRandomQueriesWithReadBufferPooling(b *testing.B) {
   148  	benchmarkQuery(b, 10, "", mkReadBufferPoolingCfg)
   149  }