You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							207 lines
						
					
					
						
							6.8 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							207 lines
						
					
					
						
							6.8 KiB
						
					
					
				| package erasure_coding | |
| 
 | |
| import ( | |
| 	"fmt" | |
| 
 | |
| 	"github.com/seaweedfs/seaweedfs/weed/admin/config" | |
| 	"github.com/seaweedfs/seaweedfs/weed/glog" | |
| 	"github.com/seaweedfs/seaweedfs/weed/pb/worker_pb" | |
| 	"github.com/seaweedfs/seaweedfs/weed/worker/tasks/base" | |
| ) | |
| 
 | |
| // Config extends BaseConfig with erasure coding specific settings | |
| type Config struct { | |
| 	base.BaseConfig | |
| 	QuietForSeconds  int     `json:"quiet_for_seconds"` | |
| 	FullnessRatio    float64 `json:"fullness_ratio"` | |
| 	CollectionFilter string  `json:"collection_filter"` | |
| 	MinSizeMB        int     `json:"min_size_mb"` | |
| } | |
| 
 | |
| // NewDefaultConfig creates a new default erasure coding configuration | |
| func NewDefaultConfig() *Config { | |
| 	return &Config{ | |
| 		BaseConfig: base.BaseConfig{ | |
| 			Enabled:             true, | |
| 			ScanIntervalSeconds: 60 * 60, // 1 hour | |
| 			MaxConcurrent:       1, | |
| 		}, | |
| 		QuietForSeconds:  300, // 5 minutes | |
| 		FullnessRatio:    0.8, // 80% | |
| 		CollectionFilter: "", | |
| 		MinSizeMB:        30, // 30MB (more reasonable than 100MB) | |
| 	} | |
| } | |
| 
 | |
| // GetConfigSpec returns the configuration schema for erasure coding tasks | |
| func GetConfigSpec() base.ConfigSpec { | |
| 	return base.ConfigSpec{ | |
| 		Fields: []*config.Field{ | |
| 			{ | |
| 				Name:         "enabled", | |
| 				JSONName:     "enabled", | |
| 				Type:         config.FieldTypeBool, | |
| 				DefaultValue: true, | |
| 				Required:     false, | |
| 				DisplayName:  "Enable Erasure Coding Tasks", | |
| 				Description:  "Whether erasure coding tasks should be automatically created", | |
| 				HelpText:     "Toggle this to enable or disable automatic erasure coding task generation", | |
| 				InputType:    "checkbox", | |
| 				CSSClasses:   "form-check-input", | |
| 			}, | |
| 			{ | |
| 				Name:         "scan_interval_seconds", | |
| 				JSONName:     "scan_interval_seconds", | |
| 				Type:         config.FieldTypeInterval, | |
| 				DefaultValue: 60 * 60, | |
| 				MinValue:     10 * 60, | |
| 				MaxValue:     24 * 60 * 60, | |
| 				Required:     true, | |
| 				DisplayName:  "Scan Interval", | |
| 				Description:  "How often to scan for volumes needing erasure coding", | |
| 				HelpText:     "The system will check for volumes that need erasure coding at this interval", | |
| 				Placeholder:  "1", | |
| 				Unit:         config.UnitHours, | |
| 				InputType:    "interval", | |
| 				CSSClasses:   "form-control", | |
| 			}, | |
| 			{ | |
| 				Name:         "max_concurrent", | |
| 				JSONName:     "max_concurrent", | |
| 				Type:         config.FieldTypeInt, | |
| 				DefaultValue: 1, | |
| 				MinValue:     1, | |
| 				MaxValue:     5, | |
| 				Required:     true, | |
| 				DisplayName:  "Max Concurrent Tasks", | |
| 				Description:  "Maximum number of erasure coding tasks that can run simultaneously", | |
| 				HelpText:     "Limits the number of erasure coding operations running at the same time", | |
| 				Placeholder:  "1 (default)", | |
| 				Unit:         config.UnitCount, | |
| 				InputType:    "number", | |
| 				CSSClasses:   "form-control", | |
| 			}, | |
| 			{ | |
| 				Name:         "quiet_for_seconds", | |
| 				JSONName:     "quiet_for_seconds", | |
| 				Type:         config.FieldTypeInterval, | |
| 				DefaultValue: 300, | |
| 				MinValue:     60, | |
| 				MaxValue:     3600, | |
| 				Required:     true, | |
| 				DisplayName:  "Quiet Period", | |
| 				Description:  "Minimum time volume must be quiet before erasure coding", | |
| 				HelpText:     "Volume must not be modified for this duration before erasure coding", | |
| 				Placeholder:  "5", | |
| 				Unit:         config.UnitMinutes, | |
| 				InputType:    "interval", | |
| 				CSSClasses:   "form-control", | |
| 			}, | |
| 			{ | |
| 				Name:         "fullness_ratio", | |
| 				JSONName:     "fullness_ratio", | |
| 				Type:         config.FieldTypeFloat, | |
| 				DefaultValue: 0.8, | |
| 				MinValue:     0.1, | |
| 				MaxValue:     1.0, | |
| 				Required:     true, | |
| 				DisplayName:  "Fullness Ratio", | |
| 				Description:  "Minimum fullness ratio to trigger erasure coding", | |
| 				HelpText:     "Only volumes with this fullness ratio or higher will be erasure coded", | |
| 				Placeholder:  "0.80 (80%)", | |
| 				Unit:         config.UnitNone, | |
| 				InputType:    "number", | |
| 				CSSClasses:   "form-control", | |
| 			}, | |
| 			{ | |
| 				Name:         "collection_filter", | |
| 				JSONName:     "collection_filter", | |
| 				Type:         config.FieldTypeString, | |
| 				DefaultValue: "", | |
| 				Required:     false, | |
| 				DisplayName:  "Collection Filter", | |
| 				Description:  "Only process volumes from specific collections", | |
| 				HelpText:     "Leave empty to process all collections, or specify collection name", | |
| 				Placeholder:  "my_collection", | |
| 				InputType:    "text", | |
| 				CSSClasses:   "form-control", | |
| 			}, | |
| 			{ | |
| 				Name:         "min_size_mb", | |
| 				JSONName:     "min_size_mb", | |
| 				Type:         config.FieldTypeInt, | |
| 				DefaultValue: 30, | |
| 				MinValue:     1, | |
| 				MaxValue:     1000, | |
| 				Required:     true, | |
| 				DisplayName:  "Minimum Size (MB)", | |
| 				Description:  "Minimum volume size to consider for erasure coding", | |
| 				HelpText:     "Only volumes larger than this size will be considered for erasure coding", | |
| 				Placeholder:  "30", | |
| 				Unit:         config.UnitNone, | |
| 				InputType:    "number", | |
| 				CSSClasses:   "form-control", | |
| 			}, | |
| 		}, | |
| 	} | |
| } | |
| 
 | |
| // ToTaskPolicy converts configuration to a TaskPolicy protobuf message | |
| func (c *Config) ToTaskPolicy() *worker_pb.TaskPolicy { | |
| 	return &worker_pb.TaskPolicy{ | |
| 		Enabled:               c.Enabled, | |
| 		MaxConcurrent:         int32(c.MaxConcurrent), | |
| 		RepeatIntervalSeconds: int32(c.ScanIntervalSeconds), | |
| 		CheckIntervalSeconds:  int32(c.ScanIntervalSeconds), | |
| 		TaskConfig: &worker_pb.TaskPolicy_ErasureCodingConfig{ | |
| 			ErasureCodingConfig: &worker_pb.ErasureCodingTaskConfig{ | |
| 				FullnessRatio:    float64(c.FullnessRatio), | |
| 				QuietForSeconds:  int32(c.QuietForSeconds), | |
| 				MinVolumeSizeMb:  int32(c.MinSizeMB), | |
| 				CollectionFilter: c.CollectionFilter, | |
| 			}, | |
| 		}, | |
| 	} | |
| } | |
| 
 | |
| // FromTaskPolicy loads configuration from a TaskPolicy protobuf message | |
| func (c *Config) FromTaskPolicy(policy *worker_pb.TaskPolicy) error { | |
| 	if policy == nil { | |
| 		return fmt.Errorf("policy is nil") | |
| 	} | |
| 
 | |
| 	// Set general TaskPolicy fields | |
| 	c.Enabled = policy.Enabled | |
| 	c.MaxConcurrent = int(policy.MaxConcurrent) | |
| 	c.ScanIntervalSeconds = int(policy.RepeatIntervalSeconds) // Direct seconds-to-seconds mapping | |
|  | |
| 	// Set erasure coding-specific fields from the task config | |
| 	if ecConfig := policy.GetErasureCodingConfig(); ecConfig != nil { | |
| 		c.FullnessRatio = float64(ecConfig.FullnessRatio) | |
| 		c.QuietForSeconds = int(ecConfig.QuietForSeconds) | |
| 		c.MinSizeMB = int(ecConfig.MinVolumeSizeMb) | |
| 		c.CollectionFilter = ecConfig.CollectionFilter | |
| 	} | |
| 
 | |
| 	return nil | |
| } | |
| 
 | |
| // LoadConfigFromPersistence loads configuration from the persistence layer if available | |
| func LoadConfigFromPersistence(configPersistence interface{}) *Config { | |
| 	config := NewDefaultConfig() | |
| 
 | |
| 	// Try to load from persistence if available | |
| 	if persistence, ok := configPersistence.(interface { | |
| 		LoadErasureCodingTaskPolicy() (*worker_pb.TaskPolicy, error) | |
| 	}); ok { | |
| 		if policy, err := persistence.LoadErasureCodingTaskPolicy(); err == nil && policy != nil { | |
| 			if err := config.FromTaskPolicy(policy); err == nil { | |
| 				glog.V(1).Infof("Loaded erasure coding configuration from persistence") | |
| 				return config | |
| 			} | |
| 		} | |
| 	} | |
| 
 | |
| 	glog.V(1).Infof("Using default erasure coding configuration") | |
| 	return config | |
| }
 |