github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/ccl/importccl/bench_test.go (about)

     1  // Copyright 2018 The Cockroach Authors.
     2  //
     3  // Licensed as a CockroachDB Enterprise file under the Cockroach Community
     4  // License (the "License"); you may not use this file except in compliance with
     5  // the License. You may obtain a copy of the License at
     6  //
     7  //     https://github.com/cockroachdb/cockroach/blob/master/licenses/CCL.txt
     8  
     9  package importccl_test
    10  
    11  import (
    12  	"context"
    13  	"io/ioutil"
    14  	"path/filepath"
    15  	"testing"
    16  
    17  	"github.com/cockroachdb/cockroach/pkg/base"
    18  	"github.com/cockroachdb/cockroach/pkg/ccl/importccl"
    19  	"github.com/cockroachdb/cockroach/pkg/ccl/workloadccl/format"
    20  	"github.com/cockroachdb/cockroach/pkg/keys"
    21  	"github.com/cockroachdb/cockroach/pkg/roachpb"
    22  	"github.com/cockroachdb/cockroach/pkg/server"
    23  	"github.com/cockroachdb/cockroach/pkg/sql/row"
    24  	"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
    25  	"github.com/cockroachdb/cockroach/pkg/sql/sessiondata"
    26  	"github.com/cockroachdb/cockroach/pkg/sql/sqlbase"
    27  	"github.com/cockroachdb/cockroach/pkg/storage"
    28  	"github.com/cockroachdb/cockroach/pkg/testutils"
    29  	"github.com/cockroachdb/cockroach/pkg/testutils/serverutils"
    30  	"github.com/cockroachdb/cockroach/pkg/util/ctxgroup"
    31  	"github.com/cockroachdb/cockroach/pkg/util/hlc"
    32  	"github.com/cockroachdb/cockroach/pkg/util/timeutil"
    33  	"github.com/cockroachdb/cockroach/pkg/workload"
    34  	"github.com/cockroachdb/cockroach/pkg/workload/tpcc"
    35  	"github.com/stretchr/testify/require"
    36  )
    37  
    38  type tableSSTable struct {
    39  	meta    workload.Table
    40  	span    roachpb.Span
    41  	sstData []byte
    42  }
    43  
    44  func BenchmarkImportWorkload(b *testing.B) {
    45  	b.Skip("#41932: broken due to adding keys out-of-order to an sstable")
    46  	if testing.Short() {
    47  		b.Skip("skipping long benchmark")
    48  	}
    49  
    50  	dir, cleanup := testutils.TempDir(b)
    51  	defer cleanup()
    52  
    53  	g := tpcc.FromWarehouses(1)
    54  
    55  	ts := timeutil.Now()
    56  	var tableSSTs []tableSSTable
    57  	for i, table := range g.Tables() {
    58  		tableID := sqlbase.ID(keys.MinUserDescID + 1 + i)
    59  		sst, err := format.ToSSTable(table, tableID, ts)
    60  		require.NoError(b, err)
    61  
    62  		t := tableSSTable{
    63  			meta:    table,
    64  			span:    roachpb.Span{Key: keys.SystemSQLCodec.TablePrefix(uint32(tableID))},
    65  			sstData: sst,
    66  		}
    67  		t.span.EndKey = t.span.Key.PrefixEnd()
    68  
    69  		tableSSTs = append(tableSSTs, t)
    70  	}
    71  
    72  	b.Run(`tpcc/warehouses=1`, func(b *testing.B) {
    73  		b.Run(`WriteAndLink`, func(b *testing.B) {
    74  			benchmarkWriteAndLink(b, dir, tableSSTs)
    75  		})
    76  		b.Run(`AddSStable`, func(b *testing.B) {
    77  			benchmarkAddSSTable(b, dir, tableSSTs)
    78  		})
    79  	})
    80  }
    81  
    82  func benchmarkWriteAndLink(b *testing.B, dir string, tables []tableSSTable) {
    83  	var bytes int64
    84  	var paths []string
    85  	for _, table := range tables {
    86  		path := filepath.Join(dir, table.meta.Name+`.sst`)
    87  		require.NoError(b, ioutil.WriteFile(path, table.sstData, 0644))
    88  		bytes += int64(len(table.sstData))
    89  		paths = append(paths, path)
    90  	}
    91  	b.SetBytes(bytes)
    92  
    93  	ctx := context.Background()
    94  	cache := storage.NewRocksDBCache(server.DefaultCacheSize)
    95  	defer cache.Release()
    96  
    97  	b.ResetTimer()
    98  	for i := 0; i < b.N; i++ {
    99  		b.StopTimer()
   100  		cfg := storage.RocksDBConfig{
   101  			StorageConfig: base.StorageConfig{
   102  				Dir: filepath.Join(dir, `rocksdb`, timeutil.Now().String())}}
   103  		db, err := storage.NewRocksDB(cfg, cache)
   104  		if err != nil {
   105  			b.Fatal(err)
   106  		}
   107  
   108  		b.StartTimer()
   109  		for i, table := range tables {
   110  			require.NoError(b, ioutil.WriteFile(paths[i], table.sstData, 0644))
   111  		}
   112  		require.NoError(b, db.IngestExternalFiles(ctx, paths))
   113  		b.StopTimer()
   114  
   115  		db.Close()
   116  	}
   117  	b.StopTimer()
   118  }
   119  
   120  func benchmarkAddSSTable(b *testing.B, dir string, tables []tableSSTable) {
   121  	ctx := context.Background()
   122  
   123  	var totalBytes int64
   124  	b.ResetTimer()
   125  	for i := 0; i < b.N; i++ {
   126  		b.StopTimer()
   127  		args := base.TestServerArgs{StoreSpecs: []base.StoreSpec{
   128  			{InMemory: false, Path: filepath.Join(dir, "testserver", timeutil.Now().String())},
   129  		}}
   130  		s, _, kvDB := serverutils.StartServer(b, args)
   131  		for _, t := range tables {
   132  			if err := kvDB.AdminSplit(ctx, t.span.Key, t.span.Key, hlc.Timestamp{} /* expirationTime */); err != nil {
   133  				b.Fatal(err)
   134  			}
   135  		}
   136  
   137  		b.StartTimer()
   138  		for _, t := range tables {
   139  			totalBytes += int64(len(t.sstData))
   140  			require.NoError(b, kvDB.AddSSTable(
   141  				ctx, t.span.Key, t.span.EndKey, t.sstData, true /* disallowShadowing */, nil /* stats */, false, /*ingestAsWrites */
   142  			))
   143  		}
   144  		b.StopTimer()
   145  
   146  		s.Stopper().Stop(ctx)
   147  	}
   148  	b.SetBytes(totalBytes / int64(b.N))
   149  }
   150  
   151  func BenchmarkConvertToKVs(b *testing.B) {
   152  	if testing.Short() {
   153  		b.Skip("skipping long benchmark")
   154  	}
   155  
   156  	tpccGen := tpcc.FromWarehouses(1)
   157  	b.Run(`tpcc/warehouses=1`, func(b *testing.B) {
   158  		benchmarkConvertToKVs(b, tpccGen)
   159  	})
   160  }
   161  
   162  func benchmarkConvertToKVs(b *testing.B, g workload.Generator) {
   163  	ctx := context.Background()
   164  	const tableID = sqlbase.ID(keys.MinUserDescID)
   165  	ts := timeutil.Now()
   166  
   167  	var bytes int64
   168  	b.ResetTimer()
   169  	for _, t := range g.Tables() {
   170  		tableDesc, err := format.ToTableDescriptor(t, tableID, ts)
   171  		if err != nil {
   172  			b.Fatal(err)
   173  		}
   174  
   175  		kvCh := make(chan row.KVBatch)
   176  		g := ctxgroup.WithContext(ctx)
   177  		g.GoCtx(func(ctx context.Context) error {
   178  			defer close(kvCh)
   179  			wc := importccl.NewWorkloadKVConverter(
   180  				0, tableDesc, t.InitialRows, 0, t.InitialRows.NumBatches, kvCh)
   181  			evalCtx := &tree.EvalContext{SessionData: &sessiondata.SessionData{}}
   182  			return wc.Worker(ctx, evalCtx)
   183  		})
   184  		for kvBatch := range kvCh {
   185  			for i := range kvBatch.KVs {
   186  				kv := &kvBatch.KVs[i]
   187  				bytes += int64(len(kv.Key) + len(kv.Value.RawBytes))
   188  			}
   189  		}
   190  		if err := g.Wait(); err != nil {
   191  			b.Fatal(err)
   192  		}
   193  	}
   194  	b.StopTimer()
   195  	b.SetBytes(bytes)
   196  }
   197  
   198  func BenchmarkConvertToSSTable(b *testing.B) {
   199  	if testing.Short() {
   200  		b.Skip("skipping long benchmark")
   201  	}
   202  
   203  	tpccGen := tpcc.FromWarehouses(1)
   204  	b.Run(`tpcc/warehouses=1`, func(b *testing.B) {
   205  		benchmarkConvertToSSTable(b, tpccGen)
   206  	})
   207  }
   208  
   209  func benchmarkConvertToSSTable(b *testing.B, g workload.Generator) {
   210  	const tableID = sqlbase.ID(keys.MinUserDescID)
   211  	now := timeutil.Now()
   212  
   213  	var totalBytes int64
   214  	b.ResetTimer()
   215  	for i := 0; i < b.N; i++ {
   216  		for _, table := range g.Tables() {
   217  			sst, err := format.ToSSTable(table, tableID, now)
   218  			if err != nil {
   219  				b.Fatal(err)
   220  			}
   221  			totalBytes += int64(len(sst))
   222  		}
   223  	}
   224  	b.StopTimer()
   225  	b.SetBytes(totalBytes / int64(b.N))
   226  }