github.com/siglens/siglens@v0.0.0-20240328180423-f7ce9ae441ed/benchmark_test.go (about) 1 /* 2 Copyright 2023. 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 bench 18 19 import ( 20 "fmt" 21 "os" 22 "testing" 23 "time" 24 25 "github.com/google/uuid" 26 jsoniter "github.com/json-iterator/go" 27 "github.com/siglens/siglens/pkg/blob" 28 dtu "github.com/siglens/siglens/pkg/common/dtypeutils" 29 "github.com/siglens/siglens/pkg/common/fileutils" 30 "github.com/siglens/siglens/pkg/config" 31 "github.com/siglens/siglens/pkg/segment" 32 "github.com/siglens/siglens/pkg/segment/query" 33 "github.com/siglens/siglens/pkg/segment/reader/microreader" 34 "github.com/siglens/siglens/pkg/segment/structs" 35 "github.com/siglens/siglens/pkg/segment/utils" 36 "github.com/siglens/siglens/pkg/segment/writer" 37 serverutils "github.com/siglens/siglens/pkg/server/utils" 38 "github.com/valyala/fastrand" 39 40 localstorage "github.com/siglens/siglens/pkg/blob/local" 41 esquery "github.com/siglens/siglens/pkg/es/query" 42 eswriter "github.com/siglens/siglens/pkg/es/writer" 43 vtable "github.com/siglens/siglens/pkg/virtualtable" 44 log "github.com/sirupsen/logrus" 45 "github.com/valyala/fasthttp" 46 ) 47 48 var json = jsoniter.ConfigFastest 49 50 var loadDataBytes0 = []byte(`{"index" : { "_index" : "test0"} } 51 {"event_id": "f533f3d4-a521-4067-b59b-628bcf8fba62", "timestamp": 1628862769706, "eventType": "pageview", "page_url": "http://www.henry.info/blog/explore/homepage/", "page_url_path": "http://www.johnson.com/", "referer_url": "https://mccall-chavez.com/", "referer_url_scheme": "HEAD", "referer_url_port": 47012, "referer_medium": "bing", "utm_medium": "Beat.", "utm_source": "Edge politics.", "utm_content": "Fly.", "utm_campaign": "Development green.", "click_id": "c21ff7e1-2d96-4b21-8415-9b69f882a593", "geo_latitude": "51.42708", "geo_longitude": "-0.91979", "geo_country": "GB", "geo_timezone": "Europe/London", "geo_region_name": "Lower Earley", "ip_address": "198.13.58.1", "browser_name": "chrome", "browser_user_agent": "Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10_10_4 rv:5.0; iu-CA) AppleWebKit/532.43.2 (KHTML, like Gecko) Version/5.0 Safari/532.43.2", "browser_language": "Part.", "os": "Linux", "os_name": "MacOS", "os_timezone": "Europe/Berlin", "device_type": "hardware", "device_is_mobile": true, "user_custom_id": "petersmichaela@hotmail.com", "user_domain_id": "c8aad4b3-0097-430e-8c74-3a2becbd41f9"} 52 `) 53 var loadDataBytes1 = []byte(`{"index" : { "_index" : "test1"} } 54 {"event_id": "f533f3d4-a521-4067-b59b-628bcf8fba62", "timestamp": 1628862769706, "eventType": "pageview", "page_url": "http://www.henry.info/blog/explore/homepage/", "page_url_path": "http://www.johnson.com/", "referer_url": "https://mccall-chavez.com/", "referer_url_scheme": "HEAD", "referer_url_port": 47012, "referer_medium": "bing", "utm_medium": "Beat.", "utm_source": "Edge politics.", "utm_content": "Fly.", "utm_campaign": "Development green.", "click_id": "c21ff7e1-2d96-4b21-8415-9b69f882a593", "geo_latitude": "51.42708", "geo_longitude": "-0.91979", "geo_country": "GB", "geo_timezone": "Europe/London", "geo_region_name": "Lower Earley", "ip_address": "198.13.58.1", "browser_name": "chrome", "browser_user_agent": "Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10_10_4 rv:5.0; iu-CA) AppleWebKit/532.43.2 (KHTML, like Gecko) Version/5.0 Safari/532.43.2", "browser_language": "Part.", "os": "Linux", "os_name": "MacOS", "os_timezone": "Europe/Berlin", "device_type": "hardware", "device_is_mobile": true, "user_custom_id": "petersmichaela@hotmail.com", "user_domain_id": "c8aad4b3-0097-430e-8c74-3a2becbd41f9"} 55 `) 56 57 var allData = [][]byte{loadDataBytes0, loadDataBytes1} 58 59 func getMyIds() []uint64 { 60 myids := make([]uint64, 1) 61 myids[0] = 0 62 return myids 63 } 64 65 func Benchmark_EndToEnd(b *testing.B) { 66 config.InitializeTestingConfig() 67 _ = localstorage.InitLocalStorage() 68 currTime := utils.GetCurrentTimeMillis() 69 startTime := uint64(0) 70 tRange := &dtu.TimeRange{ 71 StartEpochMs: startTime, 72 EndEpochMs: currTime, 73 } 74 sizeLimit := uint64(100) 75 76 smbasedir := "/Users/ssubramanian/Desktop/SigLens/siglens/data/ingestnodes/Sris-MBP.lan/smr/" 77 config.SetSmrBaseDirForTestOnly(smbasedir) 78 79 err := query.InitQueryNode(getMyIds, serverutils.ExtractKibanaRequests) 80 if err != nil { 81 b.Fatalf("Failed to initialize query node: %v", err) 82 } 83 colVal, err := utils.CreateDtypeEnclosure("batch-101", 1) 84 // colVal, err := utils.CreateDtypeEnclosure("*", 1) 85 if err != nil { 86 log.Fatal(err) 87 } 88 valueFilter := structs.FilterCriteria{ 89 ExpressionFilter: &structs.ExpressionFilter{ 90 LeftInput: &structs.FilterInput{Expression: &structs.Expression{LeftInput: &structs.ExpressionInput{ColumnName: "*"}}}, 91 FilterOperator: utils.Equals, 92 RightInput: &structs.FilterInput{Expression: &structs.Expression{LeftInput: &structs.ExpressionInput{ColumnValue: colVal}}}, 93 }, 94 } 95 queryNode := &structs.ASTNode{ 96 AndFilterCondition: &structs.Condition{FilterCriteria: []*structs.FilterCriteria{&valueFilter}}, 97 TimeRange: tRange, 98 } 99 if err != nil { 100 log.Errorf("Benchmark_LoadMicroIndices: failed to load microindex,err=%v", err) 101 } 102 count := 10 103 allTimes := make([]time.Duration, count) 104 timeSum := float64(0) 105 twoMins := 2 * 60 * 1000 106 107 simpleValueHistogram := &structs.QueryAggregators{ 108 TimeHistogram: &structs.TimeBucket{ 109 StartTime: tRange.StartEpochMs, 110 EndTime: tRange.EndEpochMs, 111 IntervalMillis: uint64(twoMins), 112 AggName: "testValue", 113 }, 114 Sort: &structs.SortRequest{ 115 ColName: "timestamp", 116 Ascending: false, 117 }, 118 } 119 qc := structs.InitQueryContext("ind-v1", sizeLimit, 0, 0, false) 120 b.ResetTimer() 121 for i := 0; i < count; i++ { 122 sTime := time.Now() 123 res := segment.ExecuteQuery(queryNode, simpleValueHistogram, uint64(i), qc) 124 log.Infof("query %v result has %v total matches", i, res.TotalResults) 125 esquery.GetQueryResponseJson(res, "ind-v1", sTime, sizeLimit, uint64(i), simpleValueHistogram) 126 elapTime := time.Since(sTime) 127 allTimes[i] = elapTime 128 if i != 0 { 129 timeSum += elapTime.Seconds() 130 } 131 } 132 log.Infof("Finished benchmark: allTimes: %v", allTimes) 133 log.Infof("Average time: %v", timeSum/float64(count-1)) 134 135 /* 136 go test -run=Bench -bench=Benchmark_EndToEnd -cpuprofile cpuprofile.out -o rawsearch_cpu 137 go tool pprof ./rawsearch_cpu cpuprofile.out 138 139 (for mem profile) 140 go test -run=Bench -bench=Benchmark_EndToEnd -benchmem -memprofile memprofile.out -o rawsearch_mem 141 go tool pprof ./rawsearch_mem memprofile.out 142 143 */ 144 145 } 146 147 func Benchmark_RRCToJson(b *testing.B) { 148 config.InitializeTestingConfig() 149 _ = localstorage.InitLocalStorage() 150 currTime := utils.GetCurrentTimeMillis() 151 startTime := uint64(0) 152 tRange := &dtu.TimeRange{ 153 StartEpochMs: startTime, 154 EndEpochMs: currTime, 155 } 156 sizeLimit := uint64(100) 157 158 smbasedir := "/Users/knawale/code/perf/siglens/data/ingestnodes/kunals-imac.lan/smr/" 159 config.SetSmrBaseDirForTestOnly(smbasedir) 160 161 err := query.InitQueryNode(getMyIds, serverutils.ExtractKibanaRequests) 162 if err != nil { 163 b.Fatalf("Failed to initialize query node: %v", err) 164 } 165 colVal, err := utils.CreateDtypeEnclosure("batch-101", 1) 166 // colVal, err := utils.CreateDtypeEnclosure("*", 1) 167 if err != nil { 168 log.Fatal(err) 169 } 170 valueFilter := structs.FilterCriteria{ 171 ExpressionFilter: &structs.ExpressionFilter{ 172 LeftInput: &structs.FilterInput{Expression: &structs.Expression{LeftInput: &structs.ExpressionInput{ColumnName: "*"}}}, 173 FilterOperator: utils.Equals, 174 RightInput: &structs.FilterInput{Expression: &structs.Expression{LeftInput: &structs.ExpressionInput{ColumnValue: colVal}}}, 175 }, 176 } 177 queryNode := &structs.ASTNode{ 178 AndFilterCondition: &structs.Condition{FilterCriteria: []*structs.FilterCriteria{&valueFilter}}, 179 TimeRange: tRange, 180 } 181 if err != nil { 182 log.Errorf("Benchmark_LoadMicroIndices: failed to load microindex, err=%v", err) 183 } 184 count := 10 185 allTimes := make([]time.Duration, count) 186 timeSum := float64(0) 187 twoMins := 2 * 60 * 1000 188 189 simpleValueHistogram := &structs.QueryAggregators{ 190 TimeHistogram: &structs.TimeBucket{ 191 StartTime: tRange.StartEpochMs, 192 EndTime: tRange.EndEpochMs, 193 IntervalMillis: uint64(twoMins), 194 AggName: "testValue", 195 }, 196 Sort: &structs.SortRequest{ 197 ColName: "timestamp", 198 Ascending: false, 199 }, 200 } 201 qc := structs.InitQueryContext("ind-v1", sizeLimit, 0, 0, false) 202 res := segment.ExecuteQuery(queryNode, simpleValueHistogram, uint64(0), qc) 203 b.ResetTimer() 204 b.ReportAllocs() 205 for i := 0; i < count; i++ { 206 sTime := time.Now() 207 log.Infof("query %v result has %v total matches", i, res.TotalResults) 208 esquery.GetQueryResponseJson(res, "ind-v1", sTime, sizeLimit, uint64(i), simpleValueHistogram) 209 elapTime := time.Since(sTime) 210 allTimes[i] = elapTime 211 if i != 0 { 212 timeSum += elapTime.Seconds() 213 } 214 } 215 log.Infof("Finished benchmark: allTimes: %v", allTimes) 216 log.Infof("Average time: %v", timeSum/float64(count-1)) 217 218 /* 219 go test -run=Bench -bench=Benchmark_RRCToJson -cpuprofile cpuprofile.out -o rawsearch_cpu 220 go tool pprof ./rawsearch_cpu cpuprofile.out 221 222 (for mem profile) 223 go test -run=Bench -bench=Benchmark_RRCToJson -benchmem -memprofile memprofile.out -o rawsearch_mem 224 go tool pprof ./rawsearch_mem memprofile.out 225 226 */ 227 228 } 229 230 func processKibanaIngestRequest(ctx *fasthttp.RequestCtx, request map[string]interface{}, 231 indexNameConverted string, updateArg bool, idVal string, tsNow uint64, myid uint64) error { 232 return nil 233 } 234 235 func Benchmark_esBulkIngest(b *testing.B) { 236 config.InitializeDefaultConfig() 237 _ = vtable.InitVTable() 238 239 var bulkData []byte 240 241 for i := 0; i < 1000; i += 1 { 242 idx := i % len(allData) 243 bulkData = append(bulkData, allData[idx]...) 244 } 245 246 start := time.Now() 247 248 b.ReportAllocs() 249 b.ResetTimer() 250 b.SetParallelism(2) 251 for i := 0; i < b.N; i++ { 252 processedCount, response, err := eswriter.HandleBulkBody(bulkData, nil, 0, processKibanaIngestRequest) 253 if err != nil { 254 log.Errorf("ERROR: err=%v", err) 255 break 256 } 257 if processedCount == 0 { 258 log.Errorf("ERROR: processedCount was 0, resp=%v", response) 259 break 260 } 261 } 262 totalTime := time.Since(start).Seconds() 263 log.Warnf("Total time=%f", totalTime) 264 265 /* 266 go test -run=Bench -bench=Benchmark_esBulkIngest -cpuprofile cpuprofile.out -o rawsearch_cpu 267 go tool pprof ./rawsearch_cpu cpuprofile.out 268 269 (for mem profile) 270 go test -run=Bench -bench=Benchmark_esBulkIngest -benchmem -memprofile memprofile.out -o rawsearch_mem 271 go tool pprof ./rawsearch_mem memprofile.out 272 273 */ 274 275 os.RemoveAll(config.GetDataPath()) 276 } 277 278 // helper benchmark test to debug & read files using a path w/o having to start server up 279 // go test -run=Bench -bench=Benchmark_logSummarySegKey 280 func Benchmark_logSummarySegKey(b *testing.B) { 281 config.InitializeDefaultConfig() 282 283 segKey := "a" 284 285 sidName := segKey + ".sid" 286 segInfo, err := microreader.ReadSegMeta(sidName) 287 if err != nil { 288 b.Fatalf("Failed to read seginfo at %s: %v", sidName, err) 289 } 290 291 log.Infof("Read Seg info: %+v", segInfo) 292 blockSum := structs.GetBsuFnameFromSegKey(segKey) 293 blockInfo, readValues, _, err := microreader.ReadBlockSummaries(blockSum, []byte{}) 294 if err != nil { 295 b.Fatalf("Failed to read seginfo at %s: %v", blockSum, err) 296 } 297 log.Infof("Read block summary info: %+v. Number blocks %+v", blockInfo, len(blockInfo)) 298 299 log.Infof("read values %+v", readValues) 300 } 301 302 func Benchmark_agileTreeIngest(b *testing.B) { 303 config.InitializeDefaultConfig() 304 config.SetAggregationsFlag(true) 305 _ = vtable.InitVTable() 306 307 var bulkData []byte 308 309 idx := "agileTree-0" 310 311 actionLine := "{\"index\": {\"_index\": \"" + idx + "\", \"_type\": \"_doc\"}}\n" 312 313 for i := 0; i < 3_000_000; i += 1 { 314 ev := make(map[string]interface{}) 315 316 ev["a"] = fmt.Sprintf("batch-%d", fastrand.Uint32n(19_000)) 317 ev["b"] = fastrand.Uint32n(1_000_000) 318 ev["c"] = "1103823372288" 319 ev["d"] = fmt.Sprintf("iOS-%d", fastrand.Uint32n(19_000)) 320 ev["e"] = fmt.Sprintf("abde-%d", fastrand.Uint32n(19_000)) 321 ev["f"] = fmt.Sprintf("useastzone-%d", fastrand.Uint32n(19_000)) 322 ev["g"] = uuid.NewString() 323 ev["h"] = fmt.Sprintf("S%d", fastrand.Uint32n(50)) 324 ev["i"] = "ethernet4Zone-test4" 325 ev["j"] = fmt.Sprintf("group %d", fastrand.Uint32n(2)) 326 ev["k"] = "00000000000000000000ffff02020202" 327 ev["l"] = "funccompanysaf3ti" 328 ev["m"] = 6922966563614901991 329 ev["n"] = "gtpv1-c" 330 ev["o"] = fastrand.Uint32n(10_000_000) 331 332 body, _ := json.Marshal(ev) 333 334 bulkData = append(bulkData, []byte(actionLine)...) 335 bulkData = append(bulkData, []byte(body)...) 336 bulkData = append(bulkData, []byte("\n")...) 337 } 338 339 start := time.Now() 340 341 b.ReportAllocs() 342 b.ResetTimer() 343 b.SetParallelism(2) 344 for i := 0; i < b.N; i++ { 345 processedCount, response, err := eswriter.HandleBulkBody(bulkData, nil, 0, processKibanaIngestRequest) 346 if err != nil { 347 log.Errorf("ERROR: err=%v", err) 348 break 349 } 350 if processedCount == 0 { 351 log.Errorf("ERROR: processedCount was 0, resp=%v", response) 352 break 353 } 354 writer.ForceRotateSegmentsForTest() 355 } 356 totalTime := time.Since(start).Seconds() 357 log.Warnf("Total time=%f", totalTime) 358 359 /* 360 go test -run=Bench -bench=Benchmark_agileTreeIngest -cpuprofile cpuprofile.out -o rawsearch_cpu 361 go tool pprof ./rawsearch_cpu cpuprofile.out 362 363 (for mem profile) 364 go test -run=Bench -bench=Benchmark_agileTreeIngest -benchmem -memprofile memprofile.out -o rawsearch_mem 365 go tool pprof ./rawsearch_mem memprofile.out 366 367 */ 368 369 os.RemoveAll(config.GetDataPath()) 370 } 371 372 func Benchmark_E2E_AgileTree(b *testing.B) { 373 config.InitializeTestingConfig() 374 config.SetAggregationsFlag(true) 375 _ = localstorage.InitLocalStorage() 376 currTime := utils.GetCurrentTimeMillis() 377 startTime := uint64(0) 378 tRange := &dtu.TimeRange{ 379 StartEpochMs: startTime, 380 EndEpochMs: currTime, 381 } 382 sizeLimit := uint64(0) 383 384 smbasedir := "/Users/kunalnawale/work/perf/siglens/data/ingestnodes/Kunals-MacBook-Pro.local/" 385 config.SetSmrBaseDirForTestOnly(smbasedir) 386 387 err := query.InitQueryNode(getMyIds, serverutils.ExtractKibanaRequests) 388 if err != nil { 389 b.Fatalf("Failed to initialize query node: %v", err) 390 } 391 392 colVal, err := utils.CreateDtypeEnclosure("*", 1) 393 if err != nil { 394 log.Fatal(err) 395 } 396 valueFilter := structs.FilterCriteria{ 397 ExpressionFilter: &structs.ExpressionFilter{ 398 LeftInput: &structs.FilterInput{Expression: &structs.Expression{LeftInput: &structs.ExpressionInput{ColumnName: "*"}}}, 399 FilterOperator: utils.Equals, 400 RightInput: &structs.FilterInput{Expression: &structs.Expression{LeftInput: &structs.ExpressionInput{ColumnValue: colVal}}}, 401 }, 402 } 403 queryNode := &structs.ASTNode{ 404 AndFilterCondition: &structs.Condition{FilterCriteria: []*structs.FilterCriteria{&valueFilter}}, 405 TimeRange: tRange, 406 } 407 if err != nil { 408 log.Errorf("Benchmark_LoadMicroIndices: failed to load microindex, err=%v", err) 409 } 410 count := 10 411 allTimes := make([]time.Duration, count) 412 timeSum := float64(0) 413 414 grpByCols := []string{"passenger_count", "pickup_date", "trip_distance"} 415 measureOps := []*structs.MeasureAggregator{ 416 {MeasureCol: "total_amount", MeasureFunc: utils.Count}, 417 } 418 grpByRequest := &structs.GroupByRequest{MeasureOperations: measureOps, GroupByColumns: grpByCols} 419 420 aggs := &structs.QueryAggregators{ 421 GroupByRequest: grpByRequest, 422 } 423 qc := structs.InitQueryContext("ind-v1", sizeLimit, 0, 0, false) 424 b.ResetTimer() 425 for i := 0; i < count; i++ { 426 sTime := time.Now() 427 res := segment.ExecuteQuery(queryNode, aggs, uint64(i), qc) 428 log.Infof("query %v result has %v total matches", i, res.TotalResults) 429 esquery.GetQueryResponseJson(res, "ind-v1", sTime, sizeLimit, uint64(i), aggs) 430 elapTime := time.Since(sTime) 431 allTimes[i] = elapTime 432 if i != 0 { 433 timeSum += elapTime.Seconds() 434 } 435 } 436 log.Infof("Finished benchmark: allTimes: %v", allTimes) 437 log.Infof("Average time: %v", timeSum/float64(count)) 438 439 /* 440 go test -run=Bench -bench=Benchmark_E2E_AgileTree -cpuprofile cpuprofile.out -o rawsearch_cpu 441 go tool pprof ./rawsearch_cpu cpuprofile.out 442 443 (for mem profile) 444 go test -run=Bench -bench=Benchmark_E2E_AgileTree -benchmem -memprofile memprofile.out -o rawsearch_mem 445 go tool pprof ./rawsearch_mem memprofile.out 446 447 */ 448 449 } 450 451 func Benchmark_S3_segupload(b *testing.B) { 452 config.InitializeTestingConfig() 453 454 config.SetS3Enabled(true) 455 config.SetS3BucketName("knawale-test") 456 config.SetS3Region("us-east-1") 457 458 count := 10 459 allTimes := make([]time.Duration, count) 460 timeSum := float64(0) 461 462 err := blob.InitBlobStore() 463 if err != nil { 464 log.Errorf("Benchmark_S3_segupload: Error initializing S3: %v", err) 465 return 466 } 467 468 finalBasedir := "ingest0data/ip-172-31-15-17.ec2.internal.AU2LfLWt3UXZtQwswR76PV/final/ind-0/0-0-3544697602014606120/7/" 469 filesToUpload := fileutils.GetAllFilesInDirectory(finalBasedir) 470 471 log.Infof("Benchmark_S3_segupload: uploading %v files", len(filesToUpload)) 472 b.ResetTimer() 473 for i := 0; i < count; i++ { 474 sTime := time.Now() 475 476 err := blob.UploadSegmentFiles(filesToUpload) 477 if err != nil { 478 log.Errorf("Benchmark_S3_segupload: failed to upload segment files , err=%v", err) 479 } 480 elapTime := time.Since(sTime) 481 allTimes[i] = elapTime 482 if i != 0 { 483 timeSum += elapTime.Seconds() 484 } 485 } 486 log.Infof("Finished benchmark: allTimes: %v", allTimes) 487 log.Infof("Average time: %v", timeSum/float64(count)) 488 489 /* 490 go test -run=Bench -bench=Benchmark_S3_segupload -cpuprofile cpuprofile.out -o rawsearch_cpu 491 go tool pprof ./rawsearch_cpu cpuprofile.out 492 493 (for mem profile) 494 go test -run=Bench -bench=Benchmark_S3_segupload -benchmem -memprofile memprofile.out -o rawsearch_mem 495 go tool pprof ./rawsearch_mem memprofile.out 496 497 */ 498 499 }