예제 #1
0
func TestManyClientOneShard(t *testing.T) {
	nclients := 35
	nseconds := 10
	smPorts, gids, kvPorts := setup("basic", false, numGroups, numReplicas)
	//defer clean()

	fmt.Printf("\nBenchmark: many clients, one shard...\n")

	smClerk := shardmaster.MakeClerk(smPorts, true)
	for i := 0; i < len(gids); i++ {
		smClerk.Join(gids[i], kvPorts[i])
	}

	counts := make([]int, nclients)
	for i := 0; i < nclients; i++ {
		go func(i int) {
			ck := shardkv.MakeClerk(smPorts, true)
			tStart := time.Now()
			count := 0
			for time.Since(tStart).Seconds() < float64(nseconds) {
				ck.PutHash("a", strconv.Itoa(rand.Int()))
				count++
			}
			counts[i] = count
		}(i)
	}
	toWait := 12 * time.Second
	time.Sleep(toWait)

	tot := 0
	for _, c := range counts {
		tot += c
	}
	fmt.Printf("%f operations per second\n", float64(tot)/float64(nseconds))

	fmt.Printf("\nBenchmark: many clients, many shards...\n")
	for i := 0; i < nclients; i++ {
		go func(i int) {
			ck := shardkv.MakeClerk(smPorts, true)
			tStart := time.Now()
			count := 0
			for time.Since(tStart).Seconds() < float64(nseconds) {
				ck.PutHash(strconv.Itoa(rand.Int()),
					strconv.Itoa(rand.Int()))
				count++
			}
			counts[i] = count
		}(i)
	}

	time.Sleep(toWait)

	tot = 0
	for _, c := range counts {
		tot += c
	}
	fmt.Printf("%f operations per second\n", float64(tot)/float64(nseconds))
}
예제 #2
0
func doConcurrent(t *testing.T, unreliable bool) {
	smPorts, gids, kvPorts := setup("conc"+strconv.FormatBool(unreliable),
		unreliable, numGroups, numReplicas)

	// Start listening on reboot channel in case we're testing persistence
	//rebootDone := 0
	//go rebootListener(&rebootDone, unreliable, smPorts, gids, kvPorts, kvServers, numGroups, numReplicas)

	smClerk := shardmaster.MakeClerk(smPorts, false)
	for i := 0; i < len(gids); i++ {
		smClerk.Join(gids[i], kvPorts[i])
	}

	const npara = 11
	var doneChannels [npara]chan bool
	for i := 0; i < npara; i++ {
		doneChannels[i] = make(chan bool)
		go func(me int) {
			ok := true
			defer func() { doneChannels[me] <- ok }()
			kvClerk := shardkv.MakeClerk(smPorts, false)
			mysmClerk := shardmaster.MakeClerk(smPorts, false)
			key := strconv.Itoa(me)
			last := ""
			for iters := 0; iters < 3; iters++ {
				nv := strconv.Itoa(rand.Int())
				v := kvClerk.PutHash(key, nv)
				if v != last {
					ok = false
					t.Fatalf("PutHash(%v) expected %v got %v\n",
						key, last, v)
				}
				last = NextValue(last, nv)
				v = kvClerk.Get(key)
				if v != last {
					ok = false
					t.Fatalf("Get(%v) expected %v got %v\n",
						key, last, v)
				}

				mysmClerk.Move(rand.Int()%shardmaster.NShards,
					gids[rand.Int()%len(gids)])

				time.Sleep(time.Duration(rand.Int()%30) * time.Millisecond)
			}
		}(i)
	}

	for i := 0; i < npara; i++ {
		x := <-doneChannels[i]
		if x == false {
			t.Fatalf("something is wrong")
		}
	}

	//rebootDone = 1
	time.Sleep(2 * time.Second)
}
예제 #3
0
// Start all servers/clients on local machine.
// Returns a system and a clean function
func localSetup(name string, args SetupArgs) (System, func()) {
	runtime.GOMAXPROCS(args.NumProcesses)

	// Start shardmasters
	smHosts := make([]string, args.NumMasters)
	sms := make([]*shardmaster.ShardMaster, args.NumMasters)
	for i := 0; i < args.NumMasters; i++ {
		smHosts[i] = port(name+"m", i)
		sms[i] = shardmaster.StartServer(smHosts, i)
	}
	smClerk := shardmaster.MakeClerk(smHosts)

	// Start ShardKV servers
	gids := make([]int64, args.NumGroups)
	skvHosts := make([][]string, args.NumGroups)
	skvs := make([][]*shardkv.ShardKV, args.NumGroups)
	for i := 0; i < args.NumGroups; i++ {
		gids[i] = int64(100 + i)
		skvHosts[i] = make([]string, args.NumReplicas)
		skvs[i] = make([]*shardkv.ShardKV, args.NumReplicas)
		for j := 0; j < args.NumReplicas; j++ {
			skvHosts[i][j] = port(name+"s", i*args.NumReplicas+j)
			skvs[i][j] = shardkv.StartServer(gids[i], smHosts, skvHosts[i], j)
		}
		smClerk.Join(gids[i], skvHosts[i])
	}

	// Start clients
	clerks := make([]*shardkv.Clerk, args.NumClients)
	for i := 0; i < args.NumClients; i++ {
		clerks[i] = shardkv.MakeClerk(smHosts)
	}

	system := System{
		ShardMasterHosts: smHosts,
		ShardMasters:     sms,
		ShardMasterClerk: smClerk,
		GroupIDs:         gids,
		ShardKVHosts:     skvHosts,
		ShardKVs:         skvs,
		Clerks:           clerks,
	}

	clean := func() {
		for i := 0; i < args.NumMasters; i++ {
			sms[i].Kill()
		}
		for i := 0; i < args.NumGroups; i++ {
			for j := 0; j < args.NumReplicas; j++ {
				skvs[i][j].Kill()
			}
		}
	}

	return system, clean
}
예제 #4
0
func BenchmarkClientLatencyOneShard(benchmark *testing.B) {
	smPorts, gids, kvPorts := setup("basic", false, numGroups, numReplicas)
	//defer clean()

	fmt.Printf("\nBenchmark: client latency, one shard...\n")

	smClerk := shardmaster.MakeClerk(smPorts, true)
	smClerk.Join(gids[0], kvPorts[0])
	kvClerk := shardkv.MakeClerk(smPorts, true)

	benchmark.ResetTimer()
	//tStart := time.Now()
	for i := 0; i < benchmark.N; i++ {
		kvClerk.PutHash("a", strconv.Itoa(rand.Int()))
	}
}
예제 #5
0
func TestDiskRecovery(t *testing.T) {
	nclients := 1
	//	numBytes := 20971520 //20MB
	nItems := 99
	keySize := 32
	valSize := 1024 * 1024
	smPorts, gids, kvPorts := setup("basic", false, numGroups, numReplicas)
	//defer clean()

	fmt.Printf("\nDisk recovery benchmark...\n")
	smClerk := shardmaster.MakeClerk(smPorts, true)
	smClerk.Join(gids[0], kvPorts[0])

	counts := make([]int, nclients)
	fmt.Printf("\nBenchmark: many clients, many shards...\n")
	for i := 0; i < nclients; i++ {
		go func(c int) {
			ck := shardkv.MakeClerk(smPorts, true)
			for i := 0; i < nItems; i++ {
				ck.Put(paddedRandIntString(keySize), paddedRandIntString(valSize))
				counts[c]++
			}
		}(i)
	}
	fmt.Println("I am here")
	sum := 0
	toWait := 22 * time.Millisecond
	for sum < nItems {
		time.Sleep(toWait)
		sum = 0
		for _, i := range counts {
			sum += i
		}
		if sum%1024 == 0 {
			fmt.Printf("%v/%v\n", sum, nItems)
		}
	}

	fmt.Println("\n", nItems*(keySize+valSize)*nclients/1000000, " MB of data written to database...\n")
}
예제 #6
0
파일: server.go 프로젝트: jeffchan/pushydb
	return smh, gids, ha, sa, clean, mbh
}

func listener(ck *shardkv.Clerk) {
	for {
		v := <-ck.Receive
		fmt.Printf("%+v\n", v)
		// send v on socket
		sendMe := "Key: " + v.Key() + ", Value: " + v.PutValue()
		fmt.Printf("Sending %s", sendMe)
		h.broadcast <- []byte(sendMe)
	}
}

var smh, gids, ha, _, clean, _ = setup("demo", false, false)
var ck = shardkv.MakeClerk(smh)

func main() {
	defer clean()

	mck := shardmaster.MakeClerk(smh)
	mck.Join(gids[0], ha[0])

	ck.Subscribe("a")
	ck.Subscribe("b")
	ck.Subscribe("c")
	ck.Subscribe("d")
	ck.Subscribe("e")
	defer cleanupClerk(ck)

	go listener(ck)
예제 #7
0
func TestBasic(t *testing.T) {
	smPorts, gids, kvPorts := setup("basic", false, numGroups, numReplicas)
	//defer clean()

	fmt.Printf("\nTest: Basic Join/Leave...\n")

	smClerk := shardmaster.MakeClerk(smPorts, true)
	smClerk.Join(gids[0], kvPorts[0])
	kvClerk := shardkv.MakeClerk(smPorts, true)
	kvClerk.Put("a", "x")
	v := kvClerk.PutHash("a", "b")
	if v != "x" {
		t.Fatalf("Puthash got wrong value")
	}
	ov := NextValue("x", "b")
	if kvClerk.Get("a") != ov {
		t.Fatalf("Get got wrong value")
	}
	log.Printf("got here6\n")
	keys := make([]string, 10)
	vals := make([]string, len(keys))
	for i := 0; i < len(keys); i++ {
		keys[i] = strconv.Itoa(rand.Int())
		vals[i] = strconv.Itoa(rand.Int())
		kvClerk.Put(keys[i], vals[i])
	}
	log.Printf("got here7\n")
	// are keys still there after joins?
	for g := 1; g < len(gids); g++ {
		smClerk.Join(gids[g], kvPorts[g])
		fmt.Printf("gid 10%d joined\n", g)
		time.Sleep(1 * time.Second)
		for i := 0; i < len(keys); i++ {
			v := kvClerk.Get(keys[i])
			if v != vals[i] {
				t.Fatalf("joining; wrong value; g=%v k=%v wanted=%v got=%v",
					g, keys[i], vals[i], v)
			}
			vals[i] = strconv.Itoa(rand.Int())
			kvClerk.Put(keys[i], vals[i])
		}
	}
	log.Printf("got here8\n")
	// are keys still there after leaves?
	for g := 0; g < len(gids)-1; g++ {
		fmt.Printf("gid 10%d wants to leave\n", g)
		smClerk.Leave(gids[g])
		fmt.Printf("gid 10%d left\n", g)
		time.Sleep(1 * time.Second)
		for i := 0; i < len(keys); i++ {
			fmt.Printf("getting %v\n", keys[i])
			v := kvClerk.Get(keys[i])
			fmt.Printf("got %v\n", keys[i])
			if v != vals[i] {
				t.Fatalf("leaving; wrong value; g=%v k=%v wanted=%v got=%v",
					g, keys[i], vals[i], v)
			}
			vals[i] = strconv.Itoa(rand.Int())
			fmt.Printf("putting %v\n", keys[i])
			kvClerk.Put(keys[i], vals[i])
			fmt.Printf("put success %v\n", keys[i])
		}
	}

	//rebootDone = 1
	fmt.Printf("\n\tPassed\n")
	time.Sleep(2 * time.Second)
}
예제 #8
0
func TestLimp(t *testing.T) {
	smPorts, gids, kvPorts := setup("limp", false, numGroups, numReplicas)

	fmt.Printf("\nTest: Reconfiguration with some dead replicas...")

	smClerk := shardmaster.MakeClerk(smPorts, false)
	smClerk.Join(gids[0], kvPorts[0])

	kvClerk := shardkv.MakeClerk(smPorts, false)

	// Start listening on reboot channel in case we're testing persistence
	//rebootDone := 0
	//go rebootListener(&rebootDone, false, smPorts, gids, kvPorts, kvServers, numGroups, numReplicas)

	kvClerk.Put("a", "b")
	if kvClerk.Get("a") != "b" {
		t.Fatalf("got wrong value")
	}

	for g := 0; g < len(kvPorts); g++ {
		//FIXME!
		//kvServers[g][rand.Int()%len(kvServers[g])].Kill()
	}

	keys := make([]string, 10)
	vals := make([]string, len(keys))
	for i := 0; i < len(keys); i++ {
		keys[i] = strconv.Itoa(rand.Int())
		vals[i] = strconv.Itoa(rand.Int())
		kvClerk.Put(keys[i], vals[i])
	}

	// are keys still there after joins?
	for g := 1; g < len(gids); g++ {
		smClerk.Join(gids[g], kvPorts[g])
		time.Sleep(1 * time.Second)
		for i := 0; i < len(keys); i++ {
			v := kvClerk.Get(keys[i])
			if v != vals[i] {
				t.Fatalf("joining; wrong value; g=%v k=%v wanted=%v got=%v",
					g, keys[i], vals[i], v)
			}
			vals[i] = strconv.Itoa(rand.Int())
			kvClerk.Put(keys[i], vals[i])
		}
	}

	// are keys still there after leaves?
	for g := 0; g < len(gids)-1; g++ {
		smClerk.Leave(gids[g])
		time.Sleep(2 * time.Second)
		for i := 0; i < len(kvPorts[g]); i++ {
			//FIXME
			//kvServers[g][i].Kill()
		}
		for i := 0; i < len(keys); i++ {
			v := kvClerk.Get(keys[i])
			if v != vals[i] {
				t.Fatalf("leaving; wrong value; g=%v k=%v wanted=%v got=%v",
					g, keys[i], vals[i], v)
			}
			vals[i] = strconv.Itoa(rand.Int())
			kvClerk.Put(keys[i], vals[i])
		}
	}

	//rebootDone = 1
	time.Sleep(2 * time.Second)
	fmt.Printf("\n\tPassed\n")
}
예제 #9
0
func TestMove(t *testing.T) {
	smPorts, gids, kvPorts := setup("move", false, numGroups, numReplicas)

	fmt.Printf("\nTest: Shards really move...")

	smClerk := shardmaster.MakeClerk(smPorts, false)
	smClerk.Join(gids[0], kvPorts[0])

	kvClerk := shardkv.MakeClerk(smPorts, false)

	// Start listening on reboot channel in case we're testing persistence
	//rebootDone := 0
	//go rebootListener(&rebootDone, false, smPorts, gids, kvPorts, kvServers, numGroups, numReplicas)

	// insert one key per shard
	for i := 0; i < shardmaster.NShards; i++ {
		kvClerk.Put(string('0'+i), string('0'+i))
	}

	// add group 1.
	smClerk.Join(gids[1], kvPorts[1])
	time.Sleep(5 * time.Second)

	// check that keys are still there.
	for i := 0; i < shardmaster.NShards; i++ {
		if kvClerk.Get(string('0'+i)) != string('0'+i) {
			t.Fatalf("missing key/value")
		}
	}

	// remove sockets from group 0.  How do we know shards have
	// been xferred...does join not succeed until they have?
	for i := 0; i < len(kvPorts[0]); i++ {
		//FIXME
		//deafen(kvPorts[0][i])
	}

	count := 0
	var mu sync.Mutex
	for i := 0; i < shardmaster.NShards; i++ {
		go func(me int) {
			myck := shardkv.MakeClerk(smPorts, false)
			v := myck.Get(string('0' + me))
			if v == string('0'+me) {
				mu.Lock()
				count++
				mu.Unlock()
			} else {
				t.Fatalf("Get(%v) yielded %v\n", i, v)
			}
		}(i)
	}

	time.Sleep(30 * time.Second)

	//rebootDone = 1
	time.Sleep(2 * time.Second)
	if count > shardmaster.NShards/3 && count < 2*(shardmaster.NShards/3) {
		fmt.Printf("\n\tPassed\n")
	} else {
		t.Fatalf("%v keys worked after killing 1/2 of groups; wanted %v",
			count, shardmaster.NShards/2)
	}
}
예제 #10
0
func TestNetwork(t *testing.T) {
	runtime.GOMAXPROCS(4)
	paxos.Network = "tcp" // set connection types to tcp
	shardmaster.Network = "tcp"
	shardkv.Network = "tcp"

	// Start shardmster
	fmt.Printf("Starting shardmaster...\n")
	smHosts := make([]string, N)
	for i := 0; i < N; i++ {
		smHosts[i] = fmt.Sprintf("%s:%d", SERVERS[i], PORT0)
	}
	sm := shardmaster.StartServer(smHosts, Index)

	// Start ShardKV server
	fmt.Printf("Starting shard server...\n")
	gids := make([]int64, N)
	skvHosts := make([][]string, N)
	skvs := make([]*shardkv.ShardKV, N)
	for i := 0; i < N; i++ {
		gids[i] = int64(100 + i)
		skvHosts[i] = make([]string, N)
		for j := 0; j < N; j++ {
			skvHosts[i][j] = fmt.Sprintf("%s:%d", SERVERS[j], PORT0+1+i)
		}
		skvs[i] = shardkv.StartServer(gids[i], smHosts, skvHosts[i], Index)
	}

	// Start shardmaster clerk, if this is the first machine.
	fmt.Printf("Starting shardmaster clerk...\n")
	if Index == 0 {
		smClerk := shardmaster.MakeClerk(smHosts)
		for i := 0; i < N; i++ {
			smClerk.Join(gids[i], skvHosts[i])
		}
	}

	// Start client
	fmt.Printf("Starting client...\n")
	client := shardkv.MakeClerk(smHosts)

	// Make requests
	time.Sleep(5000 * time.Millisecond)
	startTime := time.Now().UnixNano()
	for i := 0; i < NumOperations; i++ {
		client.Put("a", "x")
		client.Get("a")
	}
	endTime := time.Now().UnixNano()

	latency := elapsed(startTime, endTime) / float64(NumOperations)

	fmt.Printf("Total num operations: %d\n", NumOperations)
	fmt.Printf("Latency: %.3f s\n", latency)
	fmt.Printf("Note: a put() and get() query make up one operation.\n")

	// Wait for every to finish, then clean up
	fmt.Printf("Cleaning up...\n")
	time.Sleep(10000 * time.Millisecond)
	sm.Kill()
	for i := 0; i < N; i++ {
		skvs[i].Kill()
	}
}