Пример #1
0
func main() {
	var database databases.Database
	var workload workloads.Workload

	// Read configuration file
	config := ReadConfig()

	// Create driver instance
	switch config.Database.Driver {
	case "MongoDB":
		database = &databases.MongoDB{}
	default:
		log.Fatal("Unsupported competitor")
	}
	switch config.Workload.Type {
	case "DefaultWorkload":
		workload = &workloads.DefaultWorkload{}
	default:
		log.Fatal("Unsupported workload type")
	}

	// Initialize database and workload
	database.Init(config.Database)
	workload.Init(config.Workload)

	// Run concurrent workload
	wg := sync.WaitGroup{}
	wgStats := sync.WaitGroup{}
	state := workloads.State{}
	state.Records = config.Workload.Records

	// Initialize benchmark events
	state.Init()

	// Start concurrent goroutines
	state.Events["Started"] = time.Now()
	for worker := 0; worker < config.Workload.Workers; worker++ {
		wg.Add(1)
		go workload.RunWorkload(database, &state, &wg)
	}
	// Continuously report performance stats
	wgStats.Add(2)
	go state.ReportThroughput(config.Workload, &wgStats)
	go state.MeasureLatency(database, workload, config.Workload, &wgStats)

	wg.Wait()
	state.Events["Finished"] = time.Now()
	wgStats.Wait()

	// Close active connections (if any) and report final summary
	database.Shutdown()
	state.ReportSummary()
}
Пример #2
0
func (state *State) MeasureLatency(database databases.Database,
	workload Workload, config Config, wg *sync.WaitGroup) {
	defer wg.Done()

	for state.Operations < config.Operations {
		if config.CreatePercentage > 0 {
			state.Operations++
			state.Records++
			key := workload.GenerateNewKey(state.Records)
			value := workload.GenerateValue(key, config.IndexableFields, config.ValueSize)
			t0 := time.Now()
			database.Create(key, value)
			t1 := time.Now()
			state.Latency["Create"].AddSample(summstat.Sample(t1.Sub(t0)))
		}
		if config.ReadPercentage > 0 {
			state.Operations++
			key := workload.GenerateExistingKey(state.Records)
			t0 := time.Now()
			database.Read(key)
			t1 := time.Now()
			state.Latency["Read"].AddSample(summstat.Sample(t1.Sub(t0)))
		}
		if config.UpdatePercentage > 0 {
			state.Operations++
			key := workload.GenerateExistingKey(state.Records)
			value := workload.GenerateValue(key, config.IndexableFields, config.ValueSize)
			t0 := time.Now()
			database.Update(key, value)
			t1 := time.Now()
			state.Latency["Update"].AddSample(summstat.Sample(t1.Sub(t0)))
		}
		if config.DeletePercentage > 0 {
			state.Operations++
			key := workload.GenerateKeyForRemoval()
			t0 := time.Now()
			database.Delete(key)
			t1 := time.Now()
			state.Latency["Delete"].AddSample(summstat.Sample(t1.Sub(t0)))
		}
		if config.QueryPercentage > 0 {
			state.Operations++
			fieldName, fieldValue, limit := workload.GenerateQuery(config.IndexableFields,
				state.Records)
			t0 := time.Now()
			database.Query(fieldName, fieldValue, limit)
			t1 := time.Now()
			state.Latency["Query"].AddSample(summstat.Sample(t1.Sub(t0)))
		}
		time.Sleep(time.Second)
	}
}
Пример #3
0
// Sequentially send 100 requests
func (workload *DefaultWorkload) DoBatch(db databases.Database, state *State) {
	batch := workload.PrepareBatch()

	for _, v := range batch {
		// Increase number of passed operarions *before* batch
		// execution in order to normally share key space with
		// other workers
		if state.Operations < workload.Config.Operations {
			var err error
			state.Operations++
			switch v {
			case "c":
				state.Records++
				key := workload.GenerateNewKey(state.Records)
				value := workload.GenerateValue(key,
					workload.Config.IndexableFields, workload.Config.ValueSize)
				err = db.Create(key, value)
			case "r":
				key := workload.GenerateExistingKey(state.Records)
				err = db.Read(key)
			case "u":
				key := workload.GenerateExistingKey(state.Records)
				value := workload.GenerateValue(key,
					workload.Config.IndexableFields, workload.Config.ValueSize)
				err = db.Update(key, value)
			case "d":
				key := workload.GenerateKeyForRemoval()
				err = db.Delete(key)
			case "q":
				fieldName, fieldValue, limit := workload.GenerateQuery(
					workload.Config.IndexableFields, state.Records)
				err = db.Query(fieldName, fieldValue, limit)
			}
			if err != nil {
				state.Errors[v]++
				state.Errors["total"]++
			}
		}
	}
}