github.com/m3db/m3@v1.5.1-0.20231129193456-75a402aa583b/src/cmd/services/m3dbnode/config/fs.go (about) 1 // Copyright (c) 2017 Uber Technologies, Inc. 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining a copy 4 // of this software and associated documentation files (the "Software"), to deal 5 // in the Software without restriction, including without limitation the rights 6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 // copies of the Software, and to permit persons to whom the Software is 8 // furnished to do so, subject to the following conditions: 9 // 10 // The above copyright notice and this permission notice shall be included in 11 // all copies or substantial portions of the Software. 12 // 13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 // THE SOFTWARE. 20 21 package config 22 23 import ( 24 "fmt" 25 "os" 26 ) 27 28 const ( 29 // DefaultNewFileMode is the default new file mode. 30 DefaultNewFileMode = os.FileMode(0666) 31 // DefaultNewDirectoryMode is the default new directory mode. 32 DefaultNewDirectoryMode = os.FileMode(0755) 33 34 defaultFilePathPrefix = "/var/lib/m3db" 35 defaultWriteBufferSize = 65536 36 defaultDataReadBufferSize = 65536 37 defaultInfoReadBufferSize = 128 38 defaultSeekReadBufferSize = 4096 39 defaultThroughputLimitMbps = 1000.0 40 defaultThroughputCheckEvery = 128 41 defaultForceIndexSummariesMmapMemory = false 42 defaultForceBloomFilterMmapMemory = false 43 defaultBloomFilterFalsePositivePercent = 0.02 44 ) 45 46 // DefaultMmapConfiguration is the default mmap configuration. 47 func DefaultMmapConfiguration() MmapConfiguration { 48 return MmapConfiguration{ 49 HugeTLB: MmapHugeTLBConfiguration{ 50 Enabled: true, // Enable when on a platform that supports 51 Threshold: 2 << 14, // 32kb and above mappings use huge pages 52 }, 53 } 54 } 55 56 // FilesystemConfiguration is the filesystem configuration. 57 type FilesystemConfiguration struct { 58 // File path prefix for reading/writing TSDB files 59 FilePathPrefix *string `yaml:"filePathPrefix"` 60 61 // Write buffer size 62 WriteBufferSize *int `yaml:"writeBufferSize"` 63 64 // Data read buffer size 65 DataReadBufferSize *int `yaml:"dataReadBufferSize"` 66 67 // Info metadata file read buffer size 68 InfoReadBufferSize *int `yaml:"infoReadBufferSize"` 69 70 // Seek data read buffer size 71 SeekReadBufferSize *int `yaml:"seekReadBufferSize"` 72 73 // Disk flush throughput limit in Mb/s 74 ThroughputLimitMbps *float64 `yaml:"throughputLimitMbps"` 75 76 // Disk flush throughput check interval 77 ThroughputCheckEvery *int `yaml:"throughputCheckEvery"` 78 79 // NewFileMode is the new file permissions mode to use when 80 // creating files - specify as three digits, e.g. 666. 81 NewFileMode *string `yaml:"newFileMode"` 82 83 // NewDirectoryMode is the new file permissions mode to use when 84 // creating directories - specify as three digits, e.g. 755. 85 NewDirectoryMode *string `yaml:"newDirectoryMode"` 86 87 // Mmap is the mmap options which features are primarily platform dependent 88 Mmap *MmapConfiguration `yaml:"mmap"` 89 90 // ForceIndexSummariesMmapMemory forces the mmap that stores the index lookup bytes 91 // to be an anonymous region in memory as opposed to a file-based mmap. 92 ForceIndexSummariesMmapMemory *bool `yaml:"force_index_summaries_mmap_memory"` 93 94 // ForceBloomFilterMmapMemory forces the mmap that stores the index lookup bytes 95 // to be an anonymous region in memory as opposed to a file-based mmap. 96 ForceBloomFilterMmapMemory *bool `yaml:"force_bloom_filter_mmap_memory"` 97 98 // BloomFilterFalsePositivePercent controls the target false positive percentage 99 // for the bloom filters for the fileset files. 100 BloomFilterFalsePositivePercent *float64 `yaml:"bloomFilterFalsePositivePercent"` 101 } 102 103 // Validate validates the Filesystem configuration. We use this method to validate 104 // fields where the validator package falls short. 105 func (f FilesystemConfiguration) Validate() error { 106 if f.WriteBufferSize != nil && *f.WriteBufferSize < 1 { 107 return fmt.Errorf( 108 "fs writeBufferSize is set to: %d, but must be at least 1", 109 *f.WriteBufferSize) 110 } 111 112 if f.DataReadBufferSize != nil && *f.DataReadBufferSize < 1 { 113 return fmt.Errorf( 114 "fs dataReadBufferSize is set to: %d, but must be at least 1", 115 *f.DataReadBufferSize) 116 } 117 118 if f.InfoReadBufferSize != nil && *f.InfoReadBufferSize < 1 { 119 return fmt.Errorf( 120 "fs infoReadBufferSize is set to: %d, but must be at least 1", 121 *f.InfoReadBufferSize) 122 } 123 124 if f.SeekReadBufferSize != nil && *f.SeekReadBufferSize < 1 { 125 return fmt.Errorf( 126 "fs seekReadBufferSize is set to: %d, but must be at least 1", 127 *f.SeekReadBufferSize) 128 } 129 130 if f.ThroughputLimitMbps != nil && *f.ThroughputLimitMbps < 1 { 131 return fmt.Errorf( 132 "fs throughputLimitMbps is set to: %f, but must be at least 1", 133 *f.ThroughputLimitMbps) 134 } 135 136 if f.ThroughputCheckEvery != nil && *f.ThroughputCheckEvery < 1 { 137 return fmt.Errorf( 138 "fs throughputCheckEvery is set to: %d, but must be at least 1", 139 *f.ThroughputCheckEvery) 140 } 141 if f.BloomFilterFalsePositivePercent != nil && 142 (*f.BloomFilterFalsePositivePercent < 0 || *f.BloomFilterFalsePositivePercent > 1) { 143 return fmt.Errorf( 144 "fs bloomFilterFalsePositivePercent is set to: %f, but must be between 0.0 and 1.0", 145 *f.BloomFilterFalsePositivePercent) 146 } 147 148 return nil 149 } 150 151 // FilePathPrefixOrDefault returns the configured file path prefix if configured, or a 152 // default value otherwise. 153 func (f FilesystemConfiguration) FilePathPrefixOrDefault() string { 154 if f.FilePathPrefix != nil { 155 return *f.FilePathPrefix 156 } 157 158 return defaultFilePathPrefix 159 } 160 161 // WriteBufferSizeOrDefault returns the configured write buffer size if configured, or a 162 // default value otherwise. 163 func (f FilesystemConfiguration) WriteBufferSizeOrDefault() int { 164 if f.WriteBufferSize != nil { 165 return *f.WriteBufferSize 166 } 167 168 return defaultWriteBufferSize 169 } 170 171 // DataReadBufferSizeOrDefault returns the configured data read buffer size if configured, or a 172 // default value otherwise. 173 func (f FilesystemConfiguration) DataReadBufferSizeOrDefault() int { 174 if f.DataReadBufferSize != nil { 175 return *f.DataReadBufferSize 176 } 177 178 return defaultDataReadBufferSize 179 } 180 181 // InfoReadBufferSizeOrDefault returns the configured info read buffer size if configured, or a 182 // default value otherwise. 183 func (f FilesystemConfiguration) InfoReadBufferSizeOrDefault() int { 184 if f.InfoReadBufferSize != nil { 185 return *f.InfoReadBufferSize 186 } 187 188 return defaultInfoReadBufferSize 189 } 190 191 // SeekReadBufferSizeOrDefault returns the configured seek read buffer size if configured, or a 192 // default value otherwise. 193 func (f FilesystemConfiguration) SeekReadBufferSizeOrDefault() int { 194 if f.SeekReadBufferSize != nil { 195 return *f.SeekReadBufferSize 196 } 197 198 return defaultSeekReadBufferSize 199 } 200 201 // ThroughputLimitMbpsOrDefault returns the configured throughput limit mbps if configured, or a 202 // default value otherwise. 203 func (f FilesystemConfiguration) ThroughputLimitMbpsOrDefault() float64 { 204 if f.ThroughputLimitMbps != nil { 205 return *f.ThroughputLimitMbps 206 } 207 208 return defaultThroughputLimitMbps 209 } 210 211 // ThroughputCheckEveryOrDefault returns the configured throughput check every value if configured, or a 212 // default value otherwise. 213 func (f FilesystemConfiguration) ThroughputCheckEveryOrDefault() int { 214 if f.ThroughputCheckEvery != nil { 215 return *f.ThroughputCheckEvery 216 } 217 218 return defaultThroughputCheckEvery 219 } 220 221 // MmapConfigurationOrDefault returns the configured mmap configuration if configured, or a 222 // default value otherwise. 223 func (f FilesystemConfiguration) MmapConfigurationOrDefault() MmapConfiguration { 224 if f.Mmap == nil { 225 return DefaultMmapConfiguration() 226 } 227 return *f.Mmap 228 } 229 230 // ForceIndexSummariesMmapMemoryOrDefault returns the configured value for forcing the summaries 231 // mmaps into anonymous region in memory if configured, or a default value otherwise. 232 func (f FilesystemConfiguration) ForceIndexSummariesMmapMemoryOrDefault() bool { 233 if f.ForceIndexSummariesMmapMemory != nil { 234 return *f.ForceIndexSummariesMmapMemory 235 } 236 237 return defaultForceIndexSummariesMmapMemory 238 } 239 240 // ForceBloomFilterMmapMemoryOrDefault returns the configured value for forcing the bloom 241 // filter mmaps into anonymous region in memory if configured, or a default value otherwise. 242 func (f FilesystemConfiguration) ForceBloomFilterMmapMemoryOrDefault() bool { 243 if f.ForceBloomFilterMmapMemory != nil { 244 return *f.ForceBloomFilterMmapMemory 245 } 246 247 return defaultForceBloomFilterMmapMemory 248 } 249 250 // BloomFilterFalsePositivePercentOrDefault returns the configured value for the target 251 // false positive percent for the bloom filter for the fileset files if configured, or a default 252 // value otherwise 253 func (f FilesystemConfiguration) BloomFilterFalsePositivePercentOrDefault() float64 { 254 if f.BloomFilterFalsePositivePercent != nil { 255 return *f.BloomFilterFalsePositivePercent 256 } 257 return defaultBloomFilterFalsePositivePercent 258 } 259 260 // MmapConfiguration is the mmap configuration. 261 type MmapConfiguration struct { 262 // HugeTLB is the huge pages configuration which will only take affect 263 // on platforms that support it, currently just linux 264 HugeTLB MmapHugeTLBConfiguration `yaml:"hugeTLB"` 265 } 266 267 // MmapHugeTLBConfiguration is the mmap huge TLB configuration. 268 type MmapHugeTLBConfiguration struct { 269 // Enabled if true or disabled if false 270 Enabled bool `yaml:"enabled"` 271 272 // Threshold is the threshold on which to use the huge TLB flag if enabled 273 Threshold int64 `yaml:"threshold"` 274 } 275 276 // ParseNewFileMode parses the specified new file mode. 277 func (f FilesystemConfiguration) ParseNewFileMode() (os.FileMode, error) { 278 if f.NewFileMode == nil { 279 return DefaultNewFileMode, nil 280 } 281 282 str := *f.NewFileMode 283 if len(str) != 3 { 284 return 0, fmt.Errorf("file mode must be 3 chars long") 285 } 286 287 str = "0" + str 288 289 var v uint32 290 n, err := fmt.Sscanf(str, "%o", &v) 291 if err != nil { 292 return 0, fmt.Errorf("unable to parse: %v", err) 293 } 294 if n != 1 { 295 return 0, fmt.Errorf("no value to parse") 296 } 297 return os.FileMode(v), nil 298 } 299 300 // ParseNewDirectoryMode parses the specified new directory mode. 301 func (f FilesystemConfiguration) ParseNewDirectoryMode() (os.FileMode, error) { 302 if f.NewDirectoryMode == nil { 303 return DefaultNewDirectoryMode, nil 304 } 305 306 str := *f.NewDirectoryMode 307 if len(str) != 3 { 308 return 0, fmt.Errorf("file mode must be 3 chars long") 309 } 310 311 str = "0" + str 312 313 var v uint32 314 n, err := fmt.Sscanf(str, "%o", &v) 315 if err != nil { 316 return 0, fmt.Errorf("unable to parse: %v", err) 317 } 318 if n != 1 { 319 return 0, fmt.Errorf("no value to parse") 320 } 321 return os.ModeDir | os.FileMode(v), nil 322 }