func main() { var buf bytes.Buffer logger = log.New(&buf, "", log.LstdFlags|log.Lshortfile) logger.SetOutput(os.Stdout) // use all cpus in the system for concurrency runtime.GOMAXPROCS(runtime.NumCPU()) readFlags() if *debugMode { Logger.SetLogger(logger) Logger.SetLevel(DEBUG) } // launch profiler if in profile mode if *profileMode { go func() { logger.Println(http.ListenAndServe(":6060", nil)) }() } printBenchmarkParams() clientPolicy := NewClientPolicy() // cache lots connections clientPolicy.ConnectionQueueSize = *connQueueSize clientPolicy.User = *user clientPolicy.Password = *password clientPolicy.Timeout = 10 * time.Second client, err := NewClientWithPolicy(clientPolicy, *host, *port) if err != nil { logger.Fatal(err) } logger.Println("Nodes Found:", client.GetNodeNames()) go reporter() wg.Add(*concurrency) for i := 1; i < *concurrency; i++ { go runBench(client, i-1, *keyCount / *concurrency) } go runBench(client, *concurrency-1, *keyCount / *concurrency + *keyCount%*concurrency) wg.Wait() // send term to reporter, and wait for it to terminate countReportChan <- &TStats{Exit: true} time.Sleep(10 * time.Millisecond) <-countReportChan }
// listens to transaction report channel, and print them out on intervals func reporter() { var totalWCount, totalRCount int var totalWErrCount, totalRErrCount int var totalWTOCount, totalRTOCount int var totalCount, totalTOCount, totalErrCount int lastReportTime := time.Now() var memStats = new(runtime.MemStats) var lastTotalAllocs, lastPauseNs uint64 // var wLat, rLat int64 var wTotalLat, rTotalLat int64 var wMinLat, rMinLat int64 var wMaxLat, rMaxLat int64 wLatList := make([]int64, latCols+1) rLatList := make([]int64, latCols+1) var strBuff bytes.Buffer memProfileStr := func() string { var res string if *debugMode { // GC stats runtime.ReadMemStats(memStats) allocMem := (memStats.TotalAlloc - lastTotalAllocs) / (1024) pauseNs := (memStats.PauseTotalNs - lastPauseNs) / 1e6 res = fmt.Sprintf(" (malloc (KiB): %d, GC pause(ms): %d)", allocMem, pauseNs, ) // GC lastPauseNs = memStats.PauseTotalNs lastTotalAllocs = memStats.TotalAlloc } return res } Loop: for { select { case stats := <-countReportChan: totalWCount += stats.W totalRCount += stats.R totalWErrCount += stats.WE totalRErrCount += stats.RE totalWTOCount += stats.WTO totalRTOCount += stats.RTO totalCount += (stats.W + stats.R) totalErrCount += (stats.WE + stats.RE) totalTOCount += (stats.WTO + stats.RTO) wTotalLat += stats.WLat rTotalLat += stats.RLat for i := 0; i <= latCols; i++ { if stats.Wn != nil { wLatList[i] += stats.Wn[i] } if stats.Rn != nil { rLatList[i] += stats.Rn[i] } } if stats.RMax > rMaxLat { rMaxLat = stats.RMax } if stats.RMin < rMinLat { rMinLat = stats.RMin } if stats.WMax > wMaxLat { wMaxLat = stats.WMax } if stats.WMin < wMinLat { wMinLat = stats.WMin } if stats.Exit || time.Now().Sub(lastReportTime) >= time.Second { // reset throughput atomic.StoreInt64(&currThroughput, 0) atomic.StoreInt64(&lastReport, time.Now().UnixNano()) if workloadType == "I" { logger.Printf("write(tps=%d timeouts=%d errors=%d totalCount=%d)%s", totalWCount, totalTOCount, totalErrCount, totalCount, memProfileStr(), ) } else { logger.Printf( "write(tps=%d timeouts=%d errors=%d) read(tps=%d timeouts=%d errors=%d) total(tps=%d timeouts=%d errors=%d, count=%d)%s", totalWCount, totalWTOCount, totalWErrCount, totalRCount, totalRTOCount, totalRErrCount, totalWCount+totalRCount, totalTOCount, totalErrCount, totalCount, memProfileStr(), ) } if *latency != "" { strBuff.WriteString(fmt.Sprintf("\t\tMin(ms)\tAvg(ms)\tMax(ms)\t|<=%4d ms\t", latBase)) for i := 0; i < latCols; i++ { strBuff.WriteString(fmt.Sprintf("|>%4d ms\t", latBase<<uint(i))) } logger.Println(strBuff.String()) strBuff.Reset() strBuff.WriteString(fmt.Sprintf("\tREAD\t%d\t%3.3f\t%d", rMinLat, float64(rTotalLat)/float64(totalRCount+1), rMaxLat)) for i := 0; i <= latCols; i++ { strBuff.WriteString(fmt.Sprintf("\t|%7d/%4.2f%%", rLatList[i], float64(rLatList[i])/float64(totalRCount+1)*100)) } logger.Println(strBuff.String()) strBuff.Reset() strBuff.WriteString(fmt.Sprintf("\tWRITE\t%d\t%3.3f\t%d", wMinLat, float64(wTotalLat)/float64(totalWCount+1), wMaxLat)) for i := 0; i <= latCols; i++ { strBuff.WriteString(fmt.Sprintf("\t|%7d/%4.2f%%", wLatList[i], float64(wLatList[i])/float64(totalWCount+1)*100)) } logger.Println(strBuff.String()) strBuff.Reset() } // reset stats wTotalLat, rTotalLat = 0, 0 wMinLat, wMaxLat = 0, 0 rMinLat, rMaxLat = 0, 0 for i := 0; i <= latCols; i++ { wLatList[i] = 0 rLatList[i] = 0 } totalWCount, totalRCount = 0, 0 totalWErrCount, totalRErrCount = 0, 0 totalTOCount, totalWTOCount, totalRTOCount = 0, 0, 0 lastReportTime = time.Now() if stats.Exit { break Loop } } } } countReportChan <- &TStats{} }