func main() { var ( c, n int url string size int ) flag.IntVar(&c, "c", 50, "number of connections") flag.IntVar(&n, "n", 200, "number of requests") flag.IntVar(&size, "s", 128, "size of put request") // TODO: config the number of concurrency in each connection flag.StringVar(&url, "u", "127.0.0.1:12379", "etcd server endpoint") flag.Parse() if flag.NArg() < 1 { flag.Usage() os.Exit(1) } var act string if act = flag.Args()[0]; act != "get" && act != "put" { fmt.Printf("unsupported action %v\n", act) os.Exit(1) } conn, err := grpc.Dial(url) if err != nil { fmt.Errorf("dial error: %v", err) os.Exit(1) } results = make(chan *result, n) bar = pb.New(n) bar.Format("Bom !") bar.Start() start := time.Now() if act == "get" { var rangeEnd []byte key := []byte(flag.Args()[1]) if len(flag.Args()) > 2 { rangeEnd = []byte(flag.Args()[2]) } benchGet(conn, key, rangeEnd, n, c) } else if act == "put" { key := []byte(flag.Args()[1]) // number of different keys to put into etcd kc, err := strconv.ParseInt(flag.Args()[2], 10, 32) if err != nil { panic(err) } benchPut(conn, key, int(kc), n, c, size) } wg.Wait() bar.Finish() printReport(n, results, time.Now().Sub(start)) }
func rangeFunc(cmd *cobra.Command, args []string) { if len(args) == 0 || len(args) > 2 { fmt.Fprintln(os.Stderr, cmd.Usage()) os.Exit(1) } k := args[0] end := "" if len(args) == 2 { end = args[1] } if rangeConsistency == "l" { fmt.Println("bench with linearizable range") } else if rangeConsistency == "s" { fmt.Println("bench with serializable range") } else { fmt.Fprintln(os.Stderr, cmd.Usage()) os.Exit(1) } results = make(chan result) requests := make(chan v3.Op, totalClients) bar = pb.New(rangeTotal) clients := mustCreateClients(totalClients, totalConns) bar.Format("Bom !") bar.Start() for i := range clients { wg.Add(1) go doRange(clients[i].KV, requests) } pdoneC := printReport(results) go func() { for i := 0; i < rangeTotal; i++ { opts := []v3.OpOption{v3.WithRange(end)} if rangeConsistency == "s" { opts = append(opts, v3.WithSerializable()) } op := v3.OpGet(k, opts...) requests <- op } close(requests) }() wg.Wait() bar.Finish() close(results) <-pdoneC }
func rangeFunc(cmd *cobra.Command, args []string) { if len(args) == 0 || len(args) > 2 { fmt.Fprintln(os.Stderr, cmd.Usage()) os.Exit(1) } k := []byte(args[0]) var end []byte if len(args) == 2 { end = []byte(args[1]) } if rangeConsistency == "l" { fmt.Println("bench with linearizable range") } else if rangeConsistency == "s" { fmt.Println("bench with serializable range") } else { fmt.Fprintln(os.Stderr, cmd.Usage()) os.Exit(1) } results = make(chan result) requests := make(chan etcdserverpb.RangeRequest, totalClients) bar = pb.New(rangeTotal) clients := mustCreateClients(totalClients, totalConns) bar.Format("Bom !") bar.Start() for i := range clients { wg.Add(1) go doRange(clients[i].KV, requests) } pdoneC := printReport(results) go func() { for i := 0; i < rangeTotal; i++ { r := etcdserverpb.RangeRequest{Key: k, RangeEnd: end} if rangeConsistency == "s" { r.Serializable = true } requests <- r } close(requests) }() wg.Wait() bar.Finish() close(results) <-pdoneC }
func main() { var c, n int var url string flag.IntVar(&c, "c", 50, "number of connections") flag.IntVar(&n, "n", 200, "number of requests") // TODO: config the number of concurrency in each connection flag.StringVar(&url, "u", "127.0.0.1:12379", "etcd server endpoint") flag.Parse() if flag.NArg() < 1 { flag.Usage() os.Exit(1) } if act := flag.Args()[0]; act != "get" { fmt.Errorf("unsupported action %v", act) os.Exit(1) } var rangeEnd []byte key := []byte(flag.Args()[1]) if len(flag.Args()) > 2 { rangeEnd = []byte(flag.Args()[2]) } results = make(chan *result, n) bar = pb.New(n) bar.Format("Bom !") bar.Start() start := time.Now() wg.Add(c) requests := make(chan struct{}, n) conn, err := grpc.Dial(url) if err != nil { fmt.Errorf("dial error: %v", err) os.Exit(1) } for i := 0; i < c; i++ { go get(etcdserverpb.NewEtcdClient(conn), key, rangeEnd, requests) } for i := 0; i < n; i++ { requests <- struct{}{} } close(requests) wg.Wait() bar.Finish() printReport(n, results, time.Now().Sub(start)) }
func putFunc(cmd *cobra.Command, args []string) { if keySpaceSize <= 0 { fmt.Fprintf(os.Stderr, "expected positive --key-space-size, got (%v)", keySpaceSize) os.Exit(1) } results = make(chan result) requests := make(chan v3.Op, totalClients) bar = pb.New(putTotal) k, v := make([]byte, keySize), string(mustRandBytes(valSize)) clients := mustCreateClients(totalClients, totalConns) bar.Format("Bom !") bar.Start() for i := range clients { wg.Add(1) go doPut(context.Background(), clients[i], requests) } pdoneC := printReport(results) go func() { for i := 0; i < putTotal; i++ { if seqKeys { binary.PutVarint(k, int64(i%keySpaceSize)) } else { binary.PutVarint(k, int64(rand.Intn(keySpaceSize))) } requests <- v3.OpPut(string(k), v) } close(requests) }() if compactInterval > 0 { go func() { for { time.Sleep(compactInterval) compactKV(clients) } }() } wg.Wait() bar.Finish() close(results) <-pdoneC }
func putFunc(cmd *cobra.Command, args []string) { if keySpaceSize <= 0 { fmt.Fprintf(os.Stderr, "expected positive --key-space-size, got (%v)", keySpaceSize) os.Exit(1) } results = make(chan result) requests := make(chan etcdserverpb.PutRequest, totalClients) bar = pb.New(putTotal) k, v := make([]byte, keySize), mustRandBytes(valSize) conns := make([]*grpc.ClientConn, totalConns) for i := range conns { conns[i] = mustCreateConn() } clients := make([]etcdserverpb.KVClient, totalClients) for i := range clients { clients[i] = etcdserverpb.NewKVClient(conns[i%int(totalConns)]) } bar.Format("Bom !") bar.Start() for i := range clients { wg.Add(1) go doPut(context.Background(), clients[i], requests) } pdoneC := printReport(results) go func() { for i := 0; i < putTotal; i++ { if seqKeys { binary.PutVarint(k, int64(i%keySpaceSize)) } else { binary.PutVarint(k, int64(rand.Intn(keySpaceSize))) } requests <- etcdserverpb.PutRequest{Key: k, Value: v} } close(requests) }() wg.Wait() bar.Finish() close(results) <-pdoneC }
func rangeFunc(cmd *cobra.Command, args []string) { if len(args) == 0 || len(args) > 2 { fmt.Fprintln(os.Stderr, cmd.Usage()) os.Exit(1) } k := []byte(args[0]) var end []byte if len(args) == 1 { end = []byte(args[1]) } results = make(chan *result, rangeTotal) requests := make(chan *etcdserverpb.RangeRequest, rangeTotal) bar = pb.New(rangeTotal) conns := make([]*grpc.ClientConn, totalConns) for i := range conns { conns[i] = mustCreateConn() } clients := make([]etcdserverpb.KVClient, totalClients) for i := range clients { clients[i] = etcdserverpb.NewKVClient(conns[i%int(totalConns)]) } bar.Format("Bom !") bar.Start() for i := range clients { wg.Add(1) go doRange(clients[i], requests) } start := time.Now() for i := 0; i < rangeTotal; i++ { r := &etcdserverpb.RangeRequest{ Key: k, RangeEnd: end, } requests <- r } close(requests) wg.Wait() bar.Finish() printReport(rangeTotal, results, time.Now().Sub(start)) }
func rangeFunc(cmd *cobra.Command, args []string) { if len(args) == 0 || len(args) > 2 { fmt.Fprintln(os.Stderr, cmd.Usage()) os.Exit(1) } k := []byte(args[0]) var end []byte if len(args) == 1 { end = []byte(args[1]) } results = make(chan result) requests := make(chan etcdserverpb.RangeRequest, totalClients) bar = pb.New(rangeTotal) clients := mustCreateClients(totalClients, totalConns) bar.Format("Bom !") bar.Start() for i := range clients { wg.Add(1) go doRange(clients[i].KV, requests) } pdoneC := printReport(results) go func() { for i := 0; i < rangeTotal; i++ { requests <- etcdserverpb.RangeRequest{ Key: k, RangeEnd: end} } close(requests) }() wg.Wait() bar.Finish() close(results) <-pdoneC }
func putFunc(cmd *cobra.Command, args []string) { results = make(chan *result, putTotal) requests := make(chan *etcdserverpb.PutRequest, putTotal) bar = pb.New(putTotal) k, v := mustRandBytes(keySize), mustRandBytes(valSize) conns := make([]*grpc.ClientConn, totalConns) for i := range conns { conns[i] = mustCreateConn() } clients := make([]etcdserverpb.KVClient, totalClients) for i := range clients { clients[i] = etcdserverpb.NewKVClient(conns[i%int(totalConns)]) } bar.Format("Bom !") bar.Start() for i := range clients { wg.Add(1) go doPut(clients[i], requests) } start := time.Now() for i := 0; i < putTotal; i++ { r := &etcdserverpb.PutRequest{ Key: k, Value: v, } requests <- r } close(requests) wg.Wait() bar.Finish() printReport(putTotal, results, time.Now().Sub(start)) }
func main() { count := 5000 bar := pb.New(count) // show percents (by default already true) bar.ShowPercent = true // show bar (by default already true) bar.ShowBar = true // no need counters bar.ShowCounters = true bar.ShowTimeLeft = true // and start bar.Start() for i := 0; i < count; i++ { bar.Increment() time.Sleep(time.Millisecond) } bar.FinishPrint("The End!") }
func watchFunc(cmd *cobra.Command, args []string) { watched := make([][]byte, watchedKeyTotal) for i := range watched { watched[i] = mustRandBytes(32) } requests := make(chan etcdserverpb.WatchRequest, totalClients) conns := make([]*grpc.ClientConn, totalConns) for i := range conns { conns[i] = mustCreateConn() } clients := make([]etcdserverpb.WatchClient, totalClients) for i := range clients { clients[i] = etcdserverpb.NewWatchClient(conns[i%int(totalConns)]) } streams := make([]etcdserverpb.Watch_WatchClient, watchTotalStreams) var err error for i := range streams { streams[i], err = clients[i%int(totalClients)].Watch(context.TODO()) if err != nil { fmt.Fprintln(os.Stderr, "Failed to create watch stream:", err) os.Exit(1) } } for i := range streams { wg.Add(1) go doWatch(streams[i], requests) } // watching phase results = make(chan result) bar = pb.New(watchTotal) bar.Format("Bom !") bar.Start() pdoneC := printRate(results) go func() { for i := 0; i < watchTotal; i++ { requests <- etcdserverpb.WatchRequest{ CreateRequest: &etcdserverpb.WatchCreateRequest{Key: watched[i%(len(watched))]}, } } close(requests) }() wg.Wait() bar.Finish() fmt.Printf("Watch creation summary:\n") close(results) <-pdoneC // put phase kv := etcdserverpb.NewKVClient(conns[0]) // total number of puts * number of watchers on each key eventsTotal := watchPutTotal * (watchTotal / watchedKeyTotal) results = make(chan result) bar = pb.New(eventsTotal) bar.Format("Bom !") bar.Start() putreqc := make(chan etcdserverpb.PutRequest) for i := 0; i < watchPutTotal; i++ { wg.Add(1) go doPut(context.TODO(), kv, putreqc) } pdoneC = printRate(results) go func() { for i := 0; i < eventsTotal; i++ { putreqc <- etcdserverpb.PutRequest{ Key: watched[i%(len(watched))], Value: []byte("data"), } // TODO: use a real rate-limiter instead of sleep. time.Sleep(time.Second / time.Duration(watchPutRate)) } close(putreqc) }() wg.Wait() bar.Finish() fmt.Printf("Watch events received summary:\n") close(results) <-pdoneC }
func stmFunc(cmd *cobra.Command, args []string) { if stmKeyCount <= 0 { fmt.Fprintf(os.Stderr, "expected positive --keys, got (%v)", stmKeyCount) os.Exit(1) } if stmWritePercent < 0 || stmWritePercent > 100 { fmt.Fprintf(os.Stderr, "expected [0, 100] --txn-wr-percent, got (%v)", stmWritePercent) os.Exit(1) } if stmKeysPerTxn < 0 || stmKeysPerTxn > stmKeyCount { fmt.Fprintf(os.Stderr, "expected --keys-per-txn between 0 and %v, got (%v)", stmKeyCount, stmKeysPerTxn) os.Exit(1) } switch stmIsolation { case "r": mkSTM = v3sync.NewSTMRepeatable case "l": mkSTM = v3sync.NewSTMSerializable default: fmt.Fprintln(os.Stderr, cmd.Usage()) os.Exit(1) } results = make(chan result) requests := make(chan stmApply, totalClients) bar = pb.New(stmTotal) clients := mustCreateClients(totalClients, totalConns) bar.Format("Bom !") bar.Start() for i := range clients { wg.Add(1) go doSTM(context.Background(), clients[i], requests) } pdoneC := printReport(results) go func() { for i := 0; i < stmTotal; i++ { kset := make(map[string]struct{}) for len(kset) != stmKeysPerTxn { k := make([]byte, 16) binary.PutVarint(k, int64(rand.Intn(stmKeyCount))) s := string(k) kset[s] = struct{}{} } applyf := func(s v3sync.STM) error { wrs := int(float32(len(kset)*stmWritePercent) / 100.0) for k := range kset { s.Get(k) if wrs > 0 { s.Put(k, string(mustRandBytes(stmValSize))) wrs-- } } return nil } requests <- applyf } close(requests) }() wg.Wait() bar.Finish() close(results) <-pdoneC }
func watchFunc(cmd *cobra.Command, args []string) { if watchKeySpaceSize <= 0 { fmt.Fprintf(os.Stderr, "expected positive --key-space-size, got (%v)", watchKeySpaceSize) os.Exit(1) } watched := make([]string, watchedKeyTotal) for i := range watched { k := make([]byte, watchKeySize) if watchSeqKeys { binary.PutVarint(k, int64(i%watchKeySpaceSize)) } else { binary.PutVarint(k, int64(rand.Intn(watchKeySpaceSize))) } watched[i] = string(k) } requests := make(chan string, totalClients) clients := mustCreateClients(totalClients, totalConns) streams := make([]v3.Watcher, watchTotalStreams) for i := range streams { streams[i] = v3.NewWatcher(clients[i%len(clients)]) } putStartNotifier = make(chan struct{}) // watching phase results = make(chan result) bar = pb.New(watchTotal) bar.Format("Bom !") bar.Start() pdoneC := printRate(results) atomic.StoreInt32(&nrWatchCompleted, int32(0)) watchCompletedNotifier = make(chan struct{}) for i := range streams { go doWatch(streams[i], requests) } go func() { for i := 0; i < watchTotal; i++ { requests <- watched[i%len(watched)] } close(requests) }() <-watchCompletedNotifier bar.Finish() fmt.Printf("Watch creation summary:\n") close(results) <-pdoneC // put phase // total number of puts * number of watchers on each key eventsTotal = watchPutTotal * (watchTotal / watchedKeyTotal) results = make(chan result) bar = pb.New(eventsTotal) bar.Format("Bom !") bar.Start() atomic.StoreInt32(&nrRecvCompleted, 0) recvCompletedNotifier = make(chan struct{}) close(putStartNotifier) putreqc := make(chan v3.Op) for i := 0; i < watchPutTotal; i++ { go doPutForWatch(context.TODO(), clients[i%len(clients)].KV, putreqc) } pdoneC = printRate(results) go func() { for i := 0; i < eventsTotal; i++ { putreqc <- v3.OpPut(watched[i%(len(watched))], "data") // TODO: use a real rate-limiter instead of sleep. time.Sleep(time.Second / time.Duration(watchPutRate)) } close(putreqc) }() <-recvCompletedNotifier bar.Finish() fmt.Printf("Watch events received summary:\n") close(results) <-pdoneC }
func watchFunc(cmd *cobra.Command, args []string) { watched := make([][]byte, watchedKeyTotal) for i := range watched { watched[i] = mustRandBytes(32) } requests := make(chan *etcdserverpb.WatchRequest, watchTotal) conns := make([]*grpc.ClientConn, totalConns) for i := range conns { conns[i] = mustCreateConn() } clients := make([]etcdserverpb.WatchClient, totalClients) for i := range clients { clients[i] = etcdserverpb.NewWatchClient(conns[i%int(totalConns)]) } streams := make([]etcdserverpb.Watch_WatchClient, watchTotalStreams) var err error for i := range streams { streams[i], err = clients[i%int(totalClients)].Watch(context.TODO()) if err != nil { fmt.Fprintln(os.Stderr, "Failed to create watch stream:", err) os.Exit(1) } } for i := range streams { wg.Add(1) go doWatch(streams[i], requests) } // watching phase results = make(chan *result, watchTotal) bar = pb.New(watchTotal) bar.Format("Bom !") bar.Start() start := time.Now() for i := 0; i < watchTotal; i++ { r := &etcdserverpb.WatchRequest{ Key: watched[i%(len(watched))], } requests <- r } close(requests) wg.Wait() bar.Finish() fmt.Printf("Watch creation summary:\n") printRate(watchTotal, results, time.Now().Sub(start)) // put phase kv := etcdserverpb.NewKVClient(conns[0]) // total number of puts * number of watchers on each key eventsTotal := watchPutTotal * (watchTotal / watchedKeyTotal) results = make(chan *result, eventsTotal) bar = pb.New(eventsTotal) bar.Format("Bom !") bar.Start() start = time.Now() // TODO: create multiple clients to do put to increase throughput // TODO: use a real rate-limiter instead of sleep. for i := 0; i < watchPutTotal; i++ { r := &etcdserverpb.PutRequest{ Key: watched[i%(len(watched))], Value: []byte("data"), } _, err := kv.Put(context.TODO(), r) if err != nil { fmt.Fprintln(os.Stderr, "Failed to put:", err) } time.Sleep(time.Second / time.Duration(watchPutRate)) } for { if len(results) == eventsTotal { break } time.Sleep(50 * time.Millisecond) } bar.Finish() fmt.Printf("Watch events received summary:\n") printRate(eventsTotal, results, time.Now().Sub(start)) }
func main() { // check args if len(os.Args) < 3 { printUsage() return } sourceName, destName := os.Args[1], os.Args[2] // check source var source io.Reader var sourceSize int64 if strings.HasPrefix(sourceName, "http://") { // open as url resp, err := http.Get(sourceName) if err != nil { fmt.Printf("Can't get %s: %v\n", sourceName, err) return } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { fmt.Printf("Server return non-200 status: %v\n", resp.Status) return } i, _ := strconv.Atoi(resp.Header.Get("Content-Length")) sourceSize = int64(i) source = resp.Body } else { // open as file s, err := os.Open(sourceName) if err != nil { fmt.Printf("Can't open %s: %v\n", sourceName, err) return } defer s.Close() // get source size sourceStat, err := s.Stat() if err != nil { fmt.Printf("Can't stat %s: %v\n", sourceName, err) return } sourceSize = sourceStat.Size() source = s } // create dest dest, err := os.Create(destName) if err != nil { fmt.Printf("Can't create %s: %v\n", destName, err) return } defer dest.Close() // create bar bar := pb.New(int(sourceSize)).SetUnits(pb.U_BYTES).SetRefreshRate(time.Millisecond * 10) bar.ShowSpeed = true bar.Start() // create multi writer writer := io.MultiWriter(dest, bar) // and copy io.Copy(writer, source) bar.Finish() }
func watchFunc(cmd *cobra.Command, args []string) { watched := make([][]byte, watchedKeyTotal) for i := range watched { watched[i] = mustRandBytes(32) } requests := make(chan etcdserverpb.WatchRequest, totalClients) clients := mustCreateClients(totalClients, totalConns) streams := make([]etcdserverpb.Watch_WatchClient, watchTotalStreams) var err error for i := range streams { streams[i], err = clients[i%len(clients)].Watch.Watch(context.TODO()) if err != nil { fmt.Fprintln(os.Stderr, "Failed to create watch stream:", err) os.Exit(1) } } putStartNotifier = make(chan struct{}) // watching phase results = make(chan result) bar = pb.New(watchTotal) bar.Format("Bom !") bar.Start() pdoneC := printRate(results) atomic.StoreInt32(&nrWatchCompleted, int32(0)) watchCompletedNotifier = make(chan struct{}) for i := range streams { go doWatch(streams[i], requests) } go func() { for i := 0; i < watchTotal; i++ { requests <- etcdserverpb.WatchRequest{ RequestUnion: &etcdserverpb.WatchRequest_CreateRequest{ CreateRequest: &etcdserverpb.WatchCreateRequest{ Key: watched[i%(len(watched))]}}} } close(requests) }() <-watchCompletedNotifier bar.Finish() fmt.Printf("Watch creation summary:\n") close(results) <-pdoneC // put phase // total number of puts * number of watchers on each key eventsTotal = watchPutTotal * (watchTotal / watchedKeyTotal) results = make(chan result) bar = pb.New(eventsTotal) bar.Format("Bom !") bar.Start() atomic.StoreInt32(&nrRecvCompleted, 0) recvCompletedNotifier = make(chan struct{}) close(putStartNotifier) putreqc := make(chan etcdserverpb.PutRequest) for i := 0; i < watchPutTotal; i++ { go doPutForWatch(context.TODO(), clients[i%len(clients)].KV, putreqc) } pdoneC = printRate(results) go func() { for i := 0; i < eventsTotal; i++ { putreqc <- etcdserverpb.PutRequest{ Key: watched[i%(len(watched))], Value: []byte("data"), } // TODO: use a real rate-limiter instead of sleep. time.Sleep(time.Second / time.Duration(watchPutRate)) } close(putreqc) }() <-recvCompletedNotifier bar.Finish() fmt.Printf("Watch events received summary:\n") close(results) <-pdoneC }