use signature-v2 for 'object perf' tests to avoid CPU using sha256 (#15151)

It is observed in a local 8 drive system the CPU seems to be
bottlenecked at

```
(pprof) top
Showing nodes accounting for 1385.31s, 88.47% of 1565.88s total
Dropped 1304 nodes (cum <= 7.83s)
Showing top 10 nodes out of 159
      flat  flat%   sum%        cum   cum%
      724s 46.24% 46.24%       724s 46.24%  crypto/sha256.block
   219.04s 13.99% 60.22%    226.63s 14.47%  syscall.Syscall
   158.04s 10.09% 70.32%    158.04s 10.09%  runtime.memmove
   127.58s  8.15% 78.46%    127.58s  8.15%  crypto/md5.block
    58.67s  3.75% 82.21%     58.67s  3.75%  github.com/minio/highwayhash.updateAVX2
    40.07s  2.56% 84.77%     40.07s  2.56%  runtime.epollwait
    33.76s  2.16% 86.93%     33.76s  2.16%  github.com/klauspost/reedsolomon._galMulAVX512Parallel84
     8.88s  0.57% 87.49%     11.56s  0.74%  runtime.step
     7.84s   0.5% 87.99%      7.84s   0.5%  runtime.memclrNoHeapPointers
     7.43s  0.47% 88.47%     22.18s  1.42%  runtime.pcvalue
```

Bonus changes:

- re-use transport for bucket replication clients, also site replication clients.
- use 32KiB buffer for all read and writes at transport layer seems to help
  TLS read connections.
- Do not have 'MaxConnsPerHost' this is problematic to be used with net/http
  connection pooling 'MaxIdleConnsPerHost' is enough.
This commit is contained in:
Harshavardhana 2022-06-22 16:28:25 -07:00 committed by GitHub
parent f3bec41eb9
commit 1a40c7c27c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 19 additions and 25 deletions

View File

@ -19,7 +19,6 @@ package cmd
import ( import (
"context" "context"
"net/http"
"sync" "sync"
"time" "time"
@ -325,25 +324,16 @@ func (sys *BucketTargetSys) set(bucket BucketInfo, meta BucketMetadata) {
sys.targetsMap[bucket.Name] = cfg.Targets sys.targetsMap[bucket.Name] = cfg.Targets
} }
// getRemoteTargetInstanceTransport contains a singleton roundtripper.
var (
getRemoteTargetInstanceTransport http.RoundTripper
getRemoteTargetInstanceTransportOnce sync.Once
)
// Returns a minio-go Client configured to access remote host described in replication target config. // Returns a minio-go Client configured to access remote host described in replication target config.
func (sys *BucketTargetSys) getRemoteTargetClient(tcfg *madmin.BucketTarget) (*TargetClient, error) { func (sys *BucketTargetSys) getRemoteTargetClient(tcfg *madmin.BucketTarget) (*TargetClient, error) {
config := tcfg.Credentials config := tcfg.Credentials
creds := credentials.NewStaticV4(config.AccessKey, config.SecretKey, "") creds := credentials.NewStaticV4(config.AccessKey, config.SecretKey, "")
getRemoteTargetInstanceTransportOnce.Do(func() {
getRemoteTargetInstanceTransport = NewRemoteTargetHTTPTransport()
})
api, err := minio.New(tcfg.Endpoint, &miniogo.Options{ api, err := minio.New(tcfg.Endpoint, &miniogo.Options{
Creds: creds, Creds: creds,
Secure: tcfg.Secure, Secure: tcfg.Secure,
Region: tcfg.Region, Region: tcfg.Region,
Transport: getRemoteTargetInstanceTransport, Transport: globalRemoteTargetTransport,
}) })
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -22,7 +22,6 @@ import (
"context" "context"
"crypto/hmac" "crypto/hmac"
"crypto/rand" "crypto/rand"
"crypto/sha256"
"crypto/subtle" "crypto/subtle"
"encoding/binary" "encoding/binary"
"encoding/hex" "encoding/hex"
@ -38,6 +37,7 @@ import (
"github.com/minio/minio/internal/crypto" "github.com/minio/minio/internal/crypto"
"github.com/minio/minio/internal/etag" "github.com/minio/minio/internal/etag"
"github.com/minio/minio/internal/fips" "github.com/minio/minio/internal/fips"
"github.com/minio/minio/internal/hash/sha256"
xhttp "github.com/minio/minio/internal/http" xhttp "github.com/minio/minio/internal/http"
"github.com/minio/minio/internal/kms" "github.com/minio/minio/internal/kms"
"github.com/minio/minio/internal/logger" "github.com/minio/minio/internal/logger"

View File

@ -338,6 +338,8 @@ var (
globalProxyTransport http.RoundTripper globalProxyTransport http.RoundTripper
globalRemoteTargetTransport http.RoundTripper
globalDNSCache = &dnscache.Resolver{ globalDNSCache = &dnscache.Resolver{
Timeout: 5 * time.Second, Timeout: 5 * time.Second,
} }

View File

@ -68,7 +68,7 @@ func selfSpeedtest(ctx context.Context, size, concurrent int, duration time.Dura
} }
client, err := minio.New(globalLocalNodeName, &minio.Options{ client, err := minio.New(globalLocalNodeName, &minio.Options{
Creds: credentials.NewStaticV4(globalActiveCred.AccessKey, globalActiveCred.SecretKey, ""), Creds: credentials.NewStaticV2(globalActiveCred.AccessKey, globalActiveCred.SecretKey, ""),
Secure: globalIsTLS, Secure: globalIsTLS,
Transport: globalProxyTransport, Transport: globalProxyTransport,
Region: region, Region: region,

View File

@ -217,6 +217,7 @@ func serverHandleCmdArgs(ctx *cli.Context) {
CurvePreferences: fips.TLSCurveIDs(), CurvePreferences: fips.TLSCurveIDs(),
ClientSessionCache: tls.NewLRUClientSessionCache(tlsClientSessionCacheSize), ClientSessionCache: tls.NewLRUClientSessionCache(tlsClientSessionCacheSize),
}, rest.DefaultTimeout)() }, rest.DefaultTimeout)()
globalRemoteTargetTransport = NewRemoteTargetHTTPTransport()()
// On macOS, if a process already listens on LOCALIPADDR:PORT, net.Listen() falls back // On macOS, if a process already listens on LOCALIPADDR:PORT, net.Listen() falls back
// to IPv6 address ie minio will start listening on IPv6 address whereas another // to IPv6 address ie minio will start listening on IPv6 address whereas another

View File

@ -2094,7 +2094,7 @@ func getAdminClient(endpoint, accessKey, secretKey string) (*madmin.AdminClient,
if err != nil { if err != nil {
return nil, err return nil, err
} }
client.SetCustomTransport(NewRemoteTargetHTTPTransport()) client.SetCustomTransport(globalRemoteTargetTransport)
return client, nil return client, nil
} }
@ -2106,7 +2106,7 @@ func getS3Client(pc madmin.PeerSite) (*minioClient.Client, error) {
return minioClient.New(ep.Host, &minioClient.Options{ return minioClient.New(ep.Host, &minioClient.Options{
Creds: credentials.NewStaticV4(pc.AccessKey, pc.SecretKey, ""), Creds: credentials.NewStaticV4(pc.AccessKey, pc.SecretKey, ""),
Secure: ep.Scheme == "https", Secure: ep.Scheme == "https",
Transport: NewRemoteTargetHTTPTransport(), Transport: globalRemoteTargetTransport,
}) })
} }

View File

@ -561,9 +561,8 @@ func newCustomHTTPProxyTransport(tlsConfig *tls.Config, dialTimeout time.Duratio
Proxy: http.ProxyFromEnvironment, Proxy: http.ProxyFromEnvironment,
DialContext: xhttp.DialContextWithDNSCache(globalDNSCache, xhttp.NewInternodeDialContext(dialTimeout)), DialContext: xhttp.DialContextWithDNSCache(globalDNSCache, xhttp.NewInternodeDialContext(dialTimeout)),
MaxIdleConnsPerHost: 1024, MaxIdleConnsPerHost: 1024,
MaxConnsPerHost: 1024, WriteBufferSize: 32 << 10, // 32KiB moving up from 4KiB default
WriteBufferSize: 16 << 10, // 16KiB moving up from 4KiB default ReadBufferSize: 32 << 10, // 32KiB moving up from 4KiB default
ReadBufferSize: 16 << 10, // 16KiB moving up from 4KiB default
IdleConnTimeout: 15 * time.Second, IdleConnTimeout: 15 * time.Second,
ResponseHeaderTimeout: 30 * time.Minute, // Set larger timeouts for proxied requests. ResponseHeaderTimeout: 30 * time.Minute, // Set larger timeouts for proxied requests.
TLSHandshakeTimeout: 10 * time.Second, TLSHandshakeTimeout: 10 * time.Second,
@ -587,10 +586,10 @@ func newCustomHTTPTransport(tlsConfig *tls.Config, dialTimeout time.Duration) fu
Proxy: http.ProxyFromEnvironment, Proxy: http.ProxyFromEnvironment,
DialContext: xhttp.DialContextWithDNSCache(globalDNSCache, xhttp.NewInternodeDialContext(dialTimeout)), DialContext: xhttp.DialContextWithDNSCache(globalDNSCache, xhttp.NewInternodeDialContext(dialTimeout)),
MaxIdleConnsPerHost: 1024, MaxIdleConnsPerHost: 1024,
WriteBufferSize: 16 << 10, // 16KiB moving up from 4KiB default WriteBufferSize: 32 << 10, // 32KiB moving up from 4KiB default
ReadBufferSize: 16 << 10, // 16KiB moving up from 4KiB default ReadBufferSize: 32 << 10, // 32KiB moving up from 4KiB default
IdleConnTimeout: 15 * time.Second, IdleConnTimeout: 15 * time.Second,
ResponseHeaderTimeout: 3 * time.Minute, // Set conservative timeouts for MinIO internode. ResponseHeaderTimeout: 3 * time.Minute,
TLSHandshakeTimeout: 10 * time.Second, TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 10 * time.Second, ExpectContinueTimeout: 10 * time.Second,
TLSClientConfig: tlsConfig, TLSClientConfig: tlsConfig,
@ -666,7 +665,7 @@ func newGatewayHTTPTransport(timeout time.Duration) *http.Transport {
// NewRemoteTargetHTTPTransport returns a new http configuration // NewRemoteTargetHTTPTransport returns a new http configuration
// used while communicating with the remote replication targets. // used while communicating with the remote replication targets.
func NewRemoteTargetHTTPTransport() *http.Transport { func NewRemoteTargetHTTPTransport() func() *http.Transport {
// For more details about various values used here refer // For more details about various values used here refer
// https://golang.org/pkg/net/http/#Transport documentation // https://golang.org/pkg/net/http/#Transport documentation
tr := &http.Transport{ tr := &http.Transport{
@ -676,8 +675,8 @@ func NewRemoteTargetHTTPTransport() *http.Transport {
KeepAlive: 30 * time.Second, KeepAlive: 30 * time.Second,
}).DialContext, }).DialContext,
MaxIdleConnsPerHost: 1024, MaxIdleConnsPerHost: 1024,
WriteBufferSize: 16 << 10, // 16KiB moving up from 4KiB default WriteBufferSize: 32 << 10, // 32KiB moving up from 4KiB default
ReadBufferSize: 16 << 10, // 16KiB moving up from 4KiB default ReadBufferSize: 32 << 10, // 32KiB moving up from 4KiB default
IdleConnTimeout: 15 * time.Second, IdleConnTimeout: 15 * time.Second,
TLSHandshakeTimeout: 5 * time.Second, TLSHandshakeTimeout: 5 * time.Second,
ExpectContinueTimeout: 5 * time.Second, ExpectContinueTimeout: 5 * time.Second,
@ -690,8 +689,10 @@ func NewRemoteTargetHTTPTransport() *http.Transport {
// in raw stream. // in raw stream.
DisableCompression: true, DisableCompression: true,
} }
return func() *http.Transport {
return tr return tr
} }
}
// Load the json (typically from disk file). // Load the json (typically from disk file).
func jsonLoad(r io.ReadSeeker, data interface{}) error { func jsonLoad(r io.ReadSeeker, data interface{}) error {