Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions a.fio
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[global]
ioengine=libaio
direct=0
verify=0
bs=1m
iodepth=2
runtime=60s
time_based=0
fadvise_hint=0
nrfiles=10
thread=1
openfiles=1
group_reporting=1
filename_format=test.$jobnum.$filenum

[test]
rw=read
filesize=1g
directory=/home/princer_google_com/gcs1/1g
numjobs=96
59 changes: 58 additions & 1 deletion cfg/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,14 @@ import (
)

// AllFlagOptimizationRules is the generated map from a flag's config-path to its specific rules.
var AllFlagOptimizationRules = map[string]shared.OptimizationRules{"file-system.enable-kernel-reader": {
var AllFlagOptimizationRules = map[string]shared.OptimizationRules{"file-system.congestion-threshold": {
BucketTypeOptimization: []shared.BucketTypeOptimization{
{
BucketType: "zonal",
Value: int64(DefaultCongestionThreshold()),
},
},
}, "file-system.enable-kernel-reader": {
BucketTypeOptimization: []shared.BucketTypeOptimization{
{
BucketType: "zonal",
Expand Down Expand Up @@ -71,6 +78,20 @@ var AllFlagOptimizationRules = map[string]shared.OptimizationRules{"file-system.
Value: int64(-1),
},
},
}, "file-system.max-background": {
BucketTypeOptimization: []shared.BucketTypeOptimization{
{
BucketType: "zonal",
Value: int64(DefaultMaxBackground()),
},
},
}, "file-system.max-read-ahead-kb": {
BucketTypeOptimization: []shared.BucketTypeOptimization{
{
BucketType: "zonal",
Value: int64(16384),
},
},
}, "metadata-cache.negative-ttl-secs": {
MachineBasedOptimization: []shared.MachineBasedOptimization{
{
Expand Down Expand Up @@ -224,6 +245,18 @@ func (c *Config) ApplyOptimizations(isSet IsValueSet, input *OptimizationInput)
c.MachineType = machineType

// Apply optimizations for each flag that has rules defined.
if !isSet.IsSet("congestion-threshold") {
rules := AllFlagOptimizationRules["file-system.congestion-threshold"]
result := getOptimizedValue(&rules, c.FileSystem.CongestionThreshold, profileName, machineType, input, machineTypeToGroupMap)
if result.Optimized {
if val, ok := result.FinalValue.(int64); ok {
if c.FileSystem.CongestionThreshold != val {
c.FileSystem.CongestionThreshold = val
optimizedFlags["file-system.congestion-threshold"] = result
}
}
}
}
if !isSet.IsSet("enable-kernel-reader") {
rules := AllFlagOptimizationRules["file-system.enable-kernel-reader"]
result := getOptimizedValue(&rules, c.FileSystem.EnableKernelReader, profileName, machineType, input, machineTypeToGroupMap)
Expand Down Expand Up @@ -272,6 +305,30 @@ func (c *Config) ApplyOptimizations(isSet IsValueSet, input *OptimizationInput)
}
}
}
if !isSet.IsSet("max-background") {
rules := AllFlagOptimizationRules["file-system.max-background"]
result := getOptimizedValue(&rules, c.FileSystem.MaxBackground, profileName, machineType, input, machineTypeToGroupMap)
if result.Optimized {
if val, ok := result.FinalValue.(int64); ok {
if c.FileSystem.MaxBackground != val {
c.FileSystem.MaxBackground = val
optimizedFlags["file-system.max-background"] = result
}
}
}
}
if !isSet.IsSet("max-read-ahead-kb") {
rules := AllFlagOptimizationRules["file-system.max-read-ahead-kb"]
result := getOptimizedValue(&rules, c.FileSystem.MaxReadAheadKb, profileName, machineType, input, machineTypeToGroupMap)
if result.Optimized {
if val, ok := result.FinalValue.(int64); ok {
if c.FileSystem.MaxReadAheadKb != val {
c.FileSystem.MaxReadAheadKb = val
optimizedFlags["file-system.max-read-ahead-kb"] = result
}
}
}
}
if !isSet.IsSet("metadata-cache-negative-ttl-secs") {
rules := AllFlagOptimizationRules["metadata-cache.negative-ttl-secs"]
result := getOptimizedValue(&rules, c.MetadataCache.NegativeTtlSecs, profileName, machineType, input, machineTypeToGroupMap)
Expand Down
207 changes: 207 additions & 0 deletions cfg/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,75 @@ import (
)

func TestApplyOptimizations(t *testing.T) {
// Tests for file-system.congestion-threshold
t.Run("file-system.congestion-threshold", func(t *testing.T) {
testCases := []struct {
name string
config Config
isSet *mockIsValueSet
input *OptimizationInput
expectOptimized bool
expectedValue any
}{
{
name: "user_set",
config: Config{},
isSet: &mockIsValueSet{
setFlags: map[string]bool{
"congestion-threshold": true,
"machine-type": true,
},
},
input: &OptimizationInput{BucketType: BucketTypeZonal},
expectOptimized: false,
expectedValue: int64(98765),
},
{
name: "no_optimization",
config: Config{Profile: "non_existent_profile"},
isSet: &mockIsValueSet{
setFlags: map[string]bool{"machine-type": true},
stringFlags: map[string]string{"machine-type": "low-end-machine"},
},
input: nil,
expectOptimized: false,
expectedValue: 0,
},
{
name: "bucket_type_zonal",
config: Config{Profile: ""},
isSet: &mockIsValueSet{
setFlags: map[string]bool{},
},
input: &OptimizationInput{BucketType: BucketTypeZonal},
expectOptimized: true,
expectedValue: DefaultCongestionThreshold(),
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
// We need a copy of the config for each test case.
c := tc.config
// Set the default or non-default value on the config object.
if tc.name == "user_set" {
c.FileSystem.CongestionThreshold = tc.expectedValue.(int64)
} else {
c.FileSystem.CongestionThreshold = 0
}

optimizedFlags := c.ApplyOptimizations(tc.isSet, tc.input)

if tc.expectOptimized {
assert.Contains(t, optimizedFlags, "file-system.congestion-threshold")
} else {
assert.NotContains(t, optimizedFlags, "file-system.congestion-threshold")
}
// Use EqualValues to handle the int vs int64 type mismatch for default values.
assert.EqualValues(t, tc.expectedValue, c.FileSystem.CongestionThreshold)
})
}
})
// Tests for file-system.enable-kernel-reader
t.Run("file-system.enable-kernel-reader", func(t *testing.T) {
testCases := []struct {
Expand Down Expand Up @@ -358,6 +427,144 @@ func TestApplyOptimizations(t *testing.T) {
})
}
})
// Tests for file-system.max-background
t.Run("file-system.max-background", func(t *testing.T) {
testCases := []struct {
name string
config Config
isSet *mockIsValueSet
input *OptimizationInput
expectOptimized bool
expectedValue any
}{
{
name: "user_set",
config: Config{},
isSet: &mockIsValueSet{
setFlags: map[string]bool{
"max-background": true,
"machine-type": true,
},
},
input: &OptimizationInput{BucketType: BucketTypeZonal},
expectOptimized: false,
expectedValue: int64(98765),
},
{
name: "no_optimization",
config: Config{Profile: "non_existent_profile"},
isSet: &mockIsValueSet{
setFlags: map[string]bool{"machine-type": true},
stringFlags: map[string]string{"machine-type": "low-end-machine"},
},
input: nil,
expectOptimized: false,
expectedValue: 0,
},
{
name: "bucket_type_zonal",
config: Config{Profile: ""},
isSet: &mockIsValueSet{
setFlags: map[string]bool{},
},
input: &OptimizationInput{BucketType: BucketTypeZonal},
expectOptimized: true,
expectedValue: DefaultMaxBackground(),
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
// We need a copy of the config for each test case.
c := tc.config
// Set the default or non-default value on the config object.
if tc.name == "user_set" {
c.FileSystem.MaxBackground = tc.expectedValue.(int64)
} else {
c.FileSystem.MaxBackground = 0
}

optimizedFlags := c.ApplyOptimizations(tc.isSet, tc.input)

if tc.expectOptimized {
assert.Contains(t, optimizedFlags, "file-system.max-background")
} else {
assert.NotContains(t, optimizedFlags, "file-system.max-background")
}
// Use EqualValues to handle the int vs int64 type mismatch for default values.
assert.EqualValues(t, tc.expectedValue, c.FileSystem.MaxBackground)
})
}
})
// Tests for file-system.max-read-ahead-kb
t.Run("file-system.max-read-ahead-kb", func(t *testing.T) {
testCases := []struct {
name string
config Config
isSet *mockIsValueSet
input *OptimizationInput
expectOptimized bool
expectedValue any
}{
{
name: "user_set",
config: Config{},
isSet: &mockIsValueSet{
setFlags: map[string]bool{
"max-read-ahead-kb": true,
"machine-type": true,
},
},
input: &OptimizationInput{BucketType: BucketTypeZonal},
expectOptimized: false,
expectedValue: int64(98765),
},
{
name: "no_optimization",
config: Config{Profile: "non_existent_profile"},
isSet: &mockIsValueSet{
setFlags: map[string]bool{"machine-type": true},
stringFlags: map[string]string{"machine-type": "low-end-machine"},
},
input: nil,
expectOptimized: false,
expectedValue: 0,
},
{
name: "bucket_type_zonal",
config: Config{Profile: ""},
isSet: &mockIsValueSet{
setFlags: map[string]bool{},
},
input: &OptimizationInput{BucketType: BucketTypeZonal},
expectOptimized: true,
expectedValue: 16384,
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
// We need a copy of the config for each test case.
c := tc.config
// Set the default or non-default value on the config object.
if tc.name == "user_set" {
c.FileSystem.MaxReadAheadKb = tc.expectedValue.(int64)
} else {
c.FileSystem.MaxReadAheadKb = 0
}

optimizedFlags := c.ApplyOptimizations(tc.isSet, tc.input)

if tc.expectOptimized {
assert.Contains(t, optimizedFlags, "file-system.max-read-ahead-kb")
} else {
assert.NotContains(t, optimizedFlags, "file-system.max-read-ahead-kb")
}
// Use EqualValues to handle the int vs int64 type mismatch for default values.
assert.EqualValues(t, tc.expectedValue, c.FileSystem.MaxReadAheadKb)
})
}
})
// Tests for metadata-cache.negative-ttl-secs
t.Run("metadata-cache.negative-ttl-secs", func(t *testing.T) {
testCases := []struct {
Expand Down
9 changes: 9 additions & 0 deletions cfg/config_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,15 @@ func DefaultMaxParallelDownloads() int {
return max(16, 2*runtime.NumCPU())
}

func DefaultMaxBackground() int {
return max(12, 4*runtime.NumCPU())
}

func DefaultCongestionThreshold() int {
// 75 % of DefaultMaxBackground
return (4 * DefaultMaxBackground()) / 4
}

func IsFileCacheEnabled(mountConfig *Config) bool {
return mountConfig.FileCache.MaxSizeMb != 0 && string(mountConfig.CacheDir) != ""
}
Expand Down
8 changes: 8 additions & 0 deletions cfg/config_util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,14 @@ func Test_DefaultMaxParallelDownloads(t *testing.T) {
assert.GreaterOrEqual(t, DefaultMaxParallelDownloads(), 16)
}

func Test_DefaultMaxBackground(t *testing.T) {
assert.GreaterOrEqual(t, DefaultMaxBackground(), 12)
}

func Test_DefaultCongestionThreshold(t *testing.T) {
assert.GreaterOrEqual(t, DefaultMaxBackground(), 9)
}

func TestIsFileCacheEnabled(t *testing.T) {
testCases := []struct {
name string
Expand Down
12 changes: 12 additions & 0 deletions cfg/params.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,10 @@ params:
new requests. 0 means system default (typically 75% of max-background; 9).
default: "0"
hide-flag: true
optimizations:
bucket-type-optimization:
- bucket-type: "zonal"
value: "DefaultCongestionThreshold()"

- config-path: "file-system.dir-mode"
flag-name: "dir-mode"
Expand Down Expand Up @@ -453,6 +457,10 @@ params:
(typically 12).
default: "0"
hide-flag: true
optimizations:
bucket-type-optimization:
- bucket-type: "zonal"
value: "DefaultMaxBackground()"

- config-path: "file-system.max-read-ahead-kb"
flag-name: "max-read-ahead-kb"
Expand All @@ -463,6 +471,10 @@ params:
and system default will be used.
default: "0"
hide-flag: true
optimizations:
bucket-type-optimization:
- bucket-type: "zonal"
value: 16384 # 16 MiB

- config-path: "file-system.precondition-errors"
flag-name: "precondition-errors"
Expand Down
Loading
Loading