go.etcd.io/etcd@v3.3.27+incompatible/functional/tester/stresser.go (about) 1 // Copyright 2018 The etcd Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package tester 16 17 import ( 18 "fmt" 19 "time" 20 21 "github.com/coreos/etcd/functional/rpcpb" 22 23 "go.uber.org/zap" 24 ) 25 26 // Stresser defines stressing client operations. 27 type Stresser interface { 28 // Stress starts to stress the etcd cluster 29 Stress() error 30 // Pause stops the stresser from sending requests to etcd. Resume by calling Stress. 31 Pause() map[string]int 32 // Close releases all of the Stresser's resources. 33 Close() map[string]int 34 // ModifiedKeys reports the number of keys created and deleted by stresser 35 ModifiedKeys() int64 36 } 37 38 // newStresser creates stresser from a comma separated list of stresser types. 39 func newStresser(clus *Cluster, m *rpcpb.Member) (stressers []Stresser) { 40 stressers = make([]Stresser, len(clus.Tester.Stressers)) 41 for i, stype := range clus.Tester.Stressers { 42 clus.lg.Info( 43 "creating stresser", 44 zap.String("type", stype), 45 zap.String("endpoint", m.EtcdClientEndpoint), 46 ) 47 48 switch stype { 49 case "KV": 50 // TODO: Too intensive stressing clients can panic etcd member with 51 // 'out of memory' error. Put rate limits in server side. 52 stressers[i] = &keyStresser{ 53 stype: rpcpb.Stresser_KV, 54 lg: clus.lg, 55 m: m, 56 keySize: int(clus.Tester.StressKeySize), 57 keyLargeSize: int(clus.Tester.StressKeySizeLarge), 58 keySuffixRange: int(clus.Tester.StressKeySuffixRange), 59 keyTxnSuffixRange: int(clus.Tester.StressKeySuffixRangeTxn), 60 keyTxnOps: int(clus.Tester.StressKeyTxnOps), 61 clientsN: int(clus.Tester.StressClients), 62 rateLimiter: clus.rateLimiter, 63 } 64 65 case "LEASE": 66 stressers[i] = &leaseStresser{ 67 stype: rpcpb.Stresser_LEASE, 68 lg: clus.lg, 69 m: m, 70 numLeases: 10, // TODO: configurable 71 keysPerLease: 10, // TODO: configurable 72 rateLimiter: clus.rateLimiter, 73 } 74 75 case "ELECTION_RUNNER": 76 reqRate := 100 77 args := []string{ 78 "election", 79 fmt.Sprintf("%v", time.Now().UnixNano()), // election name as current nano time 80 "--dial-timeout=10s", 81 "--endpoints", m.EtcdClientEndpoint, 82 "--total-client-connections=10", 83 "--rounds=0", // runs forever 84 "--req-rate", fmt.Sprintf("%v", reqRate), 85 } 86 stressers[i] = newRunnerStresser( 87 rpcpb.Stresser_ELECTION_RUNNER, 88 m.EtcdClientEndpoint, 89 clus.lg, 90 clus.Tester.RunnerExecPath, 91 args, 92 clus.rateLimiter, 93 reqRate, 94 ) 95 96 case "WATCH_RUNNER": 97 reqRate := 100 98 args := []string{ 99 "watcher", 100 "--prefix", fmt.Sprintf("%v", time.Now().UnixNano()), // prefix all keys with nano time 101 "--total-keys=1", 102 "--total-prefixes=1", 103 "--watch-per-prefix=1", 104 "--endpoints", m.EtcdClientEndpoint, 105 "--rounds=0", // runs forever 106 "--req-rate", fmt.Sprintf("%v", reqRate), 107 } 108 stressers[i] = newRunnerStresser( 109 rpcpb.Stresser_WATCH_RUNNER, 110 m.EtcdClientEndpoint, 111 clus.lg, 112 clus.Tester.RunnerExecPath, 113 args, 114 clus.rateLimiter, 115 reqRate, 116 ) 117 118 case "LOCK_RACER_RUNNER": 119 reqRate := 100 120 args := []string{ 121 "lock-racer", 122 fmt.Sprintf("%v", time.Now().UnixNano()), // locker name as current nano time 123 "--endpoints", m.EtcdClientEndpoint, 124 "--total-client-connections=10", 125 "--rounds=0", // runs forever 126 "--req-rate", fmt.Sprintf("%v", reqRate), 127 } 128 stressers[i] = newRunnerStresser( 129 rpcpb.Stresser_LOCK_RACER_RUNNER, 130 m.EtcdClientEndpoint, 131 clus.lg, 132 clus.Tester.RunnerExecPath, 133 args, 134 clus.rateLimiter, 135 reqRate, 136 ) 137 138 case "LEASE_RUNNER": 139 args := []string{ 140 "lease-renewer", 141 "--ttl=30", 142 "--endpoints", m.EtcdClientEndpoint, 143 } 144 stressers[i] = newRunnerStresser( 145 rpcpb.Stresser_LEASE_RUNNER, 146 m.EtcdClientEndpoint, 147 clus.lg, 148 clus.Tester.RunnerExecPath, 149 args, 150 clus.rateLimiter, 151 0, 152 ) 153 } 154 } 155 return stressers 156 }