mirror of https://github.com/k3s-io/k3s
Merge pull request #24532 from rsc/master
Automatic merge from submit-queue apiserver latency reductions Combined effect of these two commits on the latency observed by the 1000-node kubemark benchmark: ``` name old ms/op new ms/op delta LIST_nodes_p50 127 ±16% 121 ± 9% -4.58% (p=0.000 n=29+27) LIST_nodes_p90 326 ±12% 266 ±12% -18.48% (p=0.000 n=29+27) LIST_nodes_p99 453 ±11% 400 ±14% -11.79% (p=0.000 n=29+28) LIST_replicationcontrollers_p50 29.4 ±49% 26.2 ±54% ~ (p=0.085 n=30+29) LIST_replicationcontrollers_p90 83.0 ±78% 68.6 ±59% -17.33% (p=0.013 n=30+28) LIST_replicationcontrollers_p99 216 ±43% 177 ±49% -17.68% (p=0.000 n=29+29) DELETE_pods_p50 24.5 ±14% 24.3 ±13% ~ (p=0.562 n=30+29) DELETE_pods_p90 30.7 ± 1% 30.7 ± 1% -0.30% (p=0.011 n=29+29) DELETE_pods_p99 77.2 ±34% 54.2 ±23% -29.76% (p=0.000 n=30+27) PUT_replicationcontrollers_p50 5.86 ±26% 5.94 ±32% ~ (p=0.734 n=29+29) PUT_replicationcontrollers_p90 15.8 ± 7% 15.5 ± 6% -2.06% (p=0.010 n=29+29) PUT_replicationcontrollers_p99 57.8 ±35% 39.5 ±55% -31.60% (p=0.000 n=29+29) PUT_nodes_p50 14.9 ± 2% 14.8 ± 2% -0.68% (p=0.012 n=30+27) PUT_nodes_p90 16.5 ± 1% 16.3 ± 2% -0.90% (p=0.000 n=27+28) PUT_nodes_p99 57.9 ±47% 41.3 ±35% -28.61% (p=0.000 n=30+28) POST_replicationcontrollers_p50 6.35 ±29% 6.34 ±20% ~ (p=0.944 n=30+28) POST_replicationcontrollers_p90 15.4 ± 5% 15.0 ± 5% -2.18% (p=0.001 n=29+29) POST_replicationcontrollers_p99 52.2 ±71% 32.9 ±46% -36.99% (p=0.000 n=29+27) POST_pods_p50 8.99 ±13% 8.95 ±16% ~ (p=0.903 n=30+29) POST_pods_p90 16.2 ± 4% 16.1 ± 4% ~ (p=0.287 n=29+29) POST_pods_p99 30.9 ±21% 26.4 ±12% -14.73% (p=0.000 n=28+28) POST_bindings_p50 9.34 ±12% 8.92 ±15% -4.54% (p=0.013 n=30+28) POST_bindings_p90 16.6 ± 1% 16.5 ± 3% -0.73% (p=0.017 n=28+29) POST_bindings_p99 23.5 ± 9% 21.1 ± 4% -10.09% (p=0.000 n=27+28) PUT_pods_p50 10.8 ±11% 10.2 ± 5% -5.47% (p=0.000 n=30+27) PUT_pods_p90 16.1 ± 1% 16.0 ± 1% -0.64% (p=0.000 n=29+28) PUT_pods_p99 23.4 ± 9% 20.9 ± 9% -10.93% (p=0.000 n=28+27) DELETE_replicationcontrollers_p50 2.42 ±16% 2.50 ±13% ~ (p=0.054 n=29+28) DELETE_replicationcontrollers_p90 11.5 ±12% 11.8 ±13% ~ (p=0.141 n=30+28) DELETE_replicationcontrollers_p99 19.5 ±21% 19.1 ±21% ~ (p=0.397 n=29+29) GET_nodes_p50 0.77 ±10% 0.76 ±10% ~ (p=0.317 n=28+28) GET_nodes_p90 1.20 ±16% 1.14 ±24% -4.66% (p=0.036 n=28+29) GET_nodes_p99 11.4 ±48% 7.5 ±46% -34.28% (p=0.000 n=28+29) GET_replicationcontrollers_p50 0.74 ±17% 0.73 ±17% ~ (p=0.222 n=30+28) GET_replicationcontrollers_p90 1.04 ±25% 1.01 ±27% ~ (p=0.231 n=30+29) GET_replicationcontrollers_p99 12.1 ±81% 10.0 ±145% ~ (p=0.063 n=28+29) GET_pods_p50 0.78 ±12% 0.77 ±10% ~ (p=0.178 n=30+28) GET_pods_p90 1.06 ±19% 1.02 ±19% ~ (p=0.120 n=29+28) GET_pods_p99 3.92 ±43% 2.45 ±38% -37.55% (p=0.000 n=27+25) LIST_services_p50 0.20 ±13% 0.20 ±16% ~ (p=0.854 n=28+29) LIST_services_p90 0.28 ±15% 0.27 ±14% ~ (p=0.219 n=29+28) LIST_services_p99 0.49 ±20% 0.47 ±24% ~ (p=0.140 n=29+29) LIST_endpoints_p50 0.19 ±14% 0.19 ±15% ~ (p=0.709 n=29+29) LIST_endpoints_p90 0.26 ±16% 0.26 ±13% ~ (p=0.274 n=29+28) LIST_endpoints_p99 0.46 ±24% 0.44 ±21% ~ (p=0.111 n=29+29) LIST_horizontalpodautoscalers_p50 0.16 ±15% 0.15 ±13% ~ (p=0.253 n=30+27) LIST_horizontalpodautoscalers_p90 0.22 ±24% 0.21 ±16% ~ (p=0.152 n=30+28) LIST_horizontalpodautoscalers_p99 0.31 ±33% 0.31 ±38% ~ (p=0.817 n=28+29) LIST_daemonsets_p50 0.16 ±20% 0.15 ±11% ~ (p=0.135 n=30+27) LIST_daemonsets_p90 0.22 ±18% 0.21 ±25% ~ (p=0.135 n=29+28) LIST_daemonsets_p99 0.29 ±28% 0.29 ±32% ~ (p=0.606 n=28+28) LIST_jobs_p50 0.16 ±16% 0.15 ±12% ~ (p=0.375 n=29+28) LIST_jobs_p90 0.22 ±18% 0.21 ±16% ~ (p=0.090 n=29+26) LIST_jobs_p99 0.31 ±28% 0.28 ±35% -10.29% (p=0.005 n=29+27) LIST_deployments_p50 0.15 ±16% 0.15 ±13% ~ (p=0.565 n=29+28) LIST_deployments_p90 0.22 ±22% 0.21 ±19% ~ (p=0.107 n=30+28) LIST_deployments_p99 0.31 ±27% 0.29 ±34% ~ (p=0.068 n=29+28) LIST_namespaces_p50 0.21 ±25% 0.21 ±26% ~ (p=0.768 n=29+27) LIST_namespaces_p90 0.28 ±29% 0.26 ±25% ~ (p=0.101 n=30+28) LIST_namespaces_p99 0.30 ±48% 0.29 ±42% ~ (p=0.339 n=30+29) LIST_replicasets_p50 0.15 ±18% 0.15 ±16% ~ (p=0.612 n=30+28) LIST_replicasets_p90 0.22 ±19% 0.21 ±18% -5.13% (p=0.011 n=28+27) LIST_replicasets_p99 0.31 ±39% 0.28 ±29% ~ (p=0.066 n=29+28) LIST_persistentvolumes_p50 0.16 ±23% 0.15 ±21% ~ (p=0.124 n=30+29) LIST_persistentvolumes_p90 0.21 ±23% 0.20 ±23% ~ (p=0.092 n=30+25) LIST_persistentvolumes_p99 0.21 ±24% 0.20 ±23% ~ (p=0.053 n=30+25) LIST_resourcequotas_p50 0.16 ±12% 0.16 ±13% ~ (p=0.175 n=27+28) LIST_resourcequotas_p90 0.20 ±22% 0.20 ±24% ~ (p=0.388 n=30+28) LIST_resourcequotas_p99 0.22 ±24% 0.22 ±23% ~ (p=0.575 n=30+28) LIST_persistentvolumeclaims_p50 0.15 ±21% 0.15 ±29% ~ (p=0.079 n=30+28) LIST_persistentvolumeclaims_p90 0.19 ±26% 0.18 ±34% ~ (p=0.446 n=29+29) LIST_persistentvolumeclaims_p99 0.19 ±26% 0.18 ±34% ~ (p=0.446 n=29+29) LIST_pods_p50 68.0 ±16% 56.3 ± 9% -17.19% (p=0.000 n=29+28) LIST_pods_p90 119 ±19% 93 ± 8% -21.88% (p=0.000 n=28+28) LIST_pods_p99 230 ±18% 202 ±14% -12.13% (p=0.000 n=27+28) ```pull/6/head
commit
28bc4b32c2
|
@ -163,7 +163,19 @@ func MatchPod(label labels.Selector, field fields.Selector) generic.Matcher {
|
|||
if !ok {
|
||||
return nil, nil, fmt.Errorf("not a pod")
|
||||
}
|
||||
return labels.Set(pod.ObjectMeta.Labels), PodToSelectableFields(pod), nil
|
||||
|
||||
// podLabels is already sitting there ready to be used.
|
||||
// podFields is not available directly and requires allocation of a map.
|
||||
// Only bother if the fields might be useful to determining the match.
|
||||
// One common case is for a replication controller to set up a watch
|
||||
// based on labels alone; in that case we can avoid allocating the field map.
|
||||
// This is especially important in the apiserver.
|
||||
podLabels := labels.Set(pod.ObjectMeta.Labels)
|
||||
var podFields fields.Set
|
||||
if !field.Empty() && label.Matches(podLabels) {
|
||||
podFields = PodToSelectableFields(pod)
|
||||
}
|
||||
return podLabels, podFields, nil
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -497,14 +497,39 @@ func (c *cacheWatcher) stop() {
|
|||
}
|
||||
}
|
||||
|
||||
var timerPool sync.Pool
|
||||
|
||||
func (c *cacheWatcher) add(event watchCacheEvent) {
|
||||
t := time.NewTimer(5 * time.Second)
|
||||
defer t.Stop()
|
||||
// Try to send the event immediately, without blocking.
|
||||
select {
|
||||
case c.input <- event:
|
||||
return
|
||||
default:
|
||||
}
|
||||
|
||||
// OK, block sending, but only for up to 5 seconds.
|
||||
// cacheWatcher.add is called very often, so arrange
|
||||
// to reuse timers instead of constantly allocating.
|
||||
const timeout = 5 * time.Second
|
||||
t, ok := timerPool.Get().(*time.Timer)
|
||||
if ok {
|
||||
t.Reset(timeout)
|
||||
} else {
|
||||
t = time.NewTimer(timeout)
|
||||
}
|
||||
defer timerPool.Put(t)
|
||||
|
||||
select {
|
||||
case c.input <- event:
|
||||
stopped := t.Stop()
|
||||
if !stopped {
|
||||
// Consume triggered (but not yet received) timer event
|
||||
// so that future reuse does not get a spurious timeout.
|
||||
<-t.C
|
||||
}
|
||||
case <-t.C:
|
||||
// This means that we couldn't send event to that watcher.
|
||||
// Since we don't want to blockin on it infinitely,
|
||||
// Since we don't want to block on it infinitely,
|
||||
// we simply terminate it.
|
||||
c.forget(false)
|
||||
c.stop()
|
||||
|
|
Loading…
Reference in New Issue