Skip to content

Commit f2c51bf

Browse files
committed
cloud/azure: add optional azure client caching
This adds a signle-slot, process-wide in-memory cache of the most recently used azure SDK storage client allowing subsequent attempts to open clients with the same configuration to reuse the already open client. This can allow the SDK's internal caching of things like IMDS tokens to be used across separate CRDB operations on separate files which currently each open their own client. This can be particularly impactful for avoiding hitting the IMDS rate limit. Release note: none. Epic: none.
1 parent 3b4cf41 commit f2c51bf

File tree

2 files changed

+49
-0
lines changed

2 files changed

+49
-0
lines changed

pkg/cloud/azure/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ go_library(
2424
"//pkg/util/envutil",
2525
"//pkg/util/ioctx",
2626
"//pkg/util/log",
27+
"//pkg/util/syncutil",
2728
"//pkg/util/timeutil",
2829
"//pkg/util/tracing",
2930
"@com_github_azure_azure_sdk_for_go_sdk_azcore//:azcore",

pkg/cloud/azure/azure_storage.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import (
2929
"github.com/cockroachdb/cockroach/pkg/settings"
3030
"github.com/cockroachdb/cockroach/pkg/settings/cluster"
3131
"github.com/cockroachdb/cockroach/pkg/util/ioctx"
32+
"github.com/cockroachdb/cockroach/pkg/util/syncutil"
3233
"github.com/cockroachdb/cockroach/pkg/util/timeutil"
3334
"github.com/cockroachdb/cockroach/pkg/util/tracing"
3435
"github.com/cockroachdb/errors"
@@ -55,6 +56,13 @@ var tryTimeout = settings.RegisterDurationSetting(
5556
"the timeout for individual retry attempts in Azure operations",
5657
60*time.Second)
5758

59+
var reuseSession = settings.RegisterBoolSetting(
60+
settings.ApplicationLevel,
61+
"cloudstorage.azure.session_reuse.enabled",
62+
"persist the last opened azure client and re-use it when opening a new client with the same argument (some settings may take 2mins to take effect)",
63+
false,
64+
)
65+
5866
// A note on Azure authentication:
5967
//
6068
// The standardized way to authenticate a third-party identity to the Azure
@@ -214,6 +222,14 @@ type azureStorage struct {
214222
settings *cluster.Settings
215223
}
216224

225+
var azClientCache struct {
226+
syncutil.Mutex
227+
// TODO(dt): make this an >1 item cache e.g. add a FIFO ring.
228+
key cloudpb.ExternalStorage_Azure
229+
set time.Time
230+
client *service.Client
231+
}
232+
217233
var _ cloud.ExternalStorage = &azureStorage{}
218234

219235
func makeAzureStorage(
@@ -224,6 +240,7 @@ func makeAzureStorage(
224240
if conf == nil {
225241
return nil, errors.Errorf("azure upload requested but info missing")
226242
}
243+
227244
env, err := azure.EnvironmentFromName(conf.Environment)
228245
if err != nil {
229246
return nil, errors.Wrap(err, "azure environment")
@@ -256,6 +273,29 @@ func makeAzureStorage(
256273
opts.Retry.TryTimeout = tryTimeout.Get(&args.Settings.SV)
257274

258275
var azClient *service.Client
276+
277+
clientConf := *conf
278+
clientConf.Prefix = "" // Prefix is not part of the client identity.
279+
280+
if reuseSession.Get(&args.Settings.SV) {
281+
func() {
282+
azClientCache.Lock()
283+
defer azClientCache.Unlock()
284+
if cached := azClientCache.client; cached != nil && azClientCache.key == clientConf && timeutil.Since(azClientCache.set) < 2*time.Minute {
285+
azClient = cached
286+
}
287+
}()
288+
if azClient != nil {
289+
return &azureStorage{
290+
conf: conf,
291+
ioConf: args.IOConf,
292+
container: azClient.NewContainerClient(conf.Container),
293+
prefix: conf.Prefix,
294+
settings: args.Settings,
295+
}, nil
296+
}
297+
}
298+
259299
switch conf.Auth {
260300
case cloudpb.AzureAuth_LEGACY:
261301
credential, err := azblob.NewSharedKeyCredential(conf.AccountName, conf.AccountKey)
@@ -299,6 +339,14 @@ func makeAzureStorage(
299339
return nil, errors.Errorf("unsupported value %s for %s", conf.Auth, cloud.AuthParam)
300340
}
301341

342+
if reuseSession.Get(&args.Settings.SV) {
343+
azClientCache.Lock()
344+
defer azClientCache.Unlock()
345+
azClientCache.key = clientConf
346+
azClientCache.client = azClient
347+
azClientCache.set = timeutil.Now()
348+
}
349+
302350
return &azureStorage{
303351
conf: conf,
304352
ioConf: args.IOConf,

0 commit comments

Comments
 (0)