config.go 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. package erasure_coding
  2. import (
  3. "fmt"
  4. "github.com/seaweedfs/seaweedfs/weed/admin/config"
  5. "github.com/seaweedfs/seaweedfs/weed/glog"
  6. "github.com/seaweedfs/seaweedfs/weed/pb/worker_pb"
  7. "github.com/seaweedfs/seaweedfs/weed/worker/tasks/base"
  8. )
  9. // Config extends BaseConfig with erasure coding specific settings
  10. type Config struct {
  11. base.BaseConfig
  12. QuietForSeconds int `json:"quiet_for_seconds"`
  13. FullnessRatio float64 `json:"fullness_ratio"`
  14. CollectionFilter string `json:"collection_filter"`
  15. MinSizeMB int `json:"min_size_mb"`
  16. }
  17. // NewDefaultConfig creates a new default erasure coding configuration
  18. func NewDefaultConfig() *Config {
  19. return &Config{
  20. BaseConfig: base.BaseConfig{
  21. Enabled: true,
  22. ScanIntervalSeconds: 60 * 60, // 1 hour
  23. MaxConcurrent: 1,
  24. },
  25. QuietForSeconds: 300, // 5 minutes
  26. FullnessRatio: 0.8, // 80%
  27. CollectionFilter: "",
  28. MinSizeMB: 30, // 30MB (more reasonable than 100MB)
  29. }
  30. }
  31. // GetConfigSpec returns the configuration schema for erasure coding tasks
  32. func GetConfigSpec() base.ConfigSpec {
  33. return base.ConfigSpec{
  34. Fields: []*config.Field{
  35. {
  36. Name: "enabled",
  37. JSONName: "enabled",
  38. Type: config.FieldTypeBool,
  39. DefaultValue: true,
  40. Required: false,
  41. DisplayName: "Enable Erasure Coding Tasks",
  42. Description: "Whether erasure coding tasks should be automatically created",
  43. HelpText: "Toggle this to enable or disable automatic erasure coding task generation",
  44. InputType: "checkbox",
  45. CSSClasses: "form-check-input",
  46. },
  47. {
  48. Name: "scan_interval_seconds",
  49. JSONName: "scan_interval_seconds",
  50. Type: config.FieldTypeInterval,
  51. DefaultValue: 60 * 60,
  52. MinValue: 10 * 60,
  53. MaxValue: 24 * 60 * 60,
  54. Required: true,
  55. DisplayName: "Scan Interval",
  56. Description: "How often to scan for volumes needing erasure coding",
  57. HelpText: "The system will check for volumes that need erasure coding at this interval",
  58. Placeholder: "1",
  59. Unit: config.UnitHours,
  60. InputType: "interval",
  61. CSSClasses: "form-control",
  62. },
  63. {
  64. Name: "max_concurrent",
  65. JSONName: "max_concurrent",
  66. Type: config.FieldTypeInt,
  67. DefaultValue: 1,
  68. MinValue: 1,
  69. MaxValue: 5,
  70. Required: true,
  71. DisplayName: "Max Concurrent Tasks",
  72. Description: "Maximum number of erasure coding tasks that can run simultaneously",
  73. HelpText: "Limits the number of erasure coding operations running at the same time",
  74. Placeholder: "1 (default)",
  75. Unit: config.UnitCount,
  76. InputType: "number",
  77. CSSClasses: "form-control",
  78. },
  79. {
  80. Name: "quiet_for_seconds",
  81. JSONName: "quiet_for_seconds",
  82. Type: config.FieldTypeInterval,
  83. DefaultValue: 300,
  84. MinValue: 60,
  85. MaxValue: 3600,
  86. Required: true,
  87. DisplayName: "Quiet Period",
  88. Description: "Minimum time volume must be quiet before erasure coding",
  89. HelpText: "Volume must not be modified for this duration before erasure coding",
  90. Placeholder: "5",
  91. Unit: config.UnitMinutes,
  92. InputType: "interval",
  93. CSSClasses: "form-control",
  94. },
  95. {
  96. Name: "fullness_ratio",
  97. JSONName: "fullness_ratio",
  98. Type: config.FieldTypeFloat,
  99. DefaultValue: 0.8,
  100. MinValue: 0.1,
  101. MaxValue: 1.0,
  102. Required: true,
  103. DisplayName: "Fullness Ratio",
  104. Description: "Minimum fullness ratio to trigger erasure coding",
  105. HelpText: "Only volumes with this fullness ratio or higher will be erasure coded",
  106. Placeholder: "0.80 (80%)",
  107. Unit: config.UnitNone,
  108. InputType: "number",
  109. CSSClasses: "form-control",
  110. },
  111. {
  112. Name: "collection_filter",
  113. JSONName: "collection_filter",
  114. Type: config.FieldTypeString,
  115. DefaultValue: "",
  116. Required: false,
  117. DisplayName: "Collection Filter",
  118. Description: "Only process volumes from specific collections",
  119. HelpText: "Leave empty to process all collections, or specify collection name",
  120. Placeholder: "my_collection",
  121. InputType: "text",
  122. CSSClasses: "form-control",
  123. },
  124. {
  125. Name: "min_size_mb",
  126. JSONName: "min_size_mb",
  127. Type: config.FieldTypeInt,
  128. DefaultValue: 30,
  129. MinValue: 1,
  130. MaxValue: 1000,
  131. Required: true,
  132. DisplayName: "Minimum Size (MB)",
  133. Description: "Minimum volume size to consider for erasure coding",
  134. HelpText: "Only volumes larger than this size will be considered for erasure coding",
  135. Placeholder: "30",
  136. Unit: config.UnitNone,
  137. InputType: "number",
  138. CSSClasses: "form-control",
  139. },
  140. },
  141. }
  142. }
  143. // ToTaskPolicy converts configuration to a TaskPolicy protobuf message
  144. func (c *Config) ToTaskPolicy() *worker_pb.TaskPolicy {
  145. return &worker_pb.TaskPolicy{
  146. Enabled: c.Enabled,
  147. MaxConcurrent: int32(c.MaxConcurrent),
  148. RepeatIntervalSeconds: int32(c.ScanIntervalSeconds),
  149. CheckIntervalSeconds: int32(c.ScanIntervalSeconds),
  150. TaskConfig: &worker_pb.TaskPolicy_ErasureCodingConfig{
  151. ErasureCodingConfig: &worker_pb.ErasureCodingTaskConfig{
  152. FullnessRatio: float64(c.FullnessRatio),
  153. QuietForSeconds: int32(c.QuietForSeconds),
  154. MinVolumeSizeMb: int32(c.MinSizeMB),
  155. CollectionFilter: c.CollectionFilter,
  156. },
  157. },
  158. }
  159. }
  160. // FromTaskPolicy loads configuration from a TaskPolicy protobuf message
  161. func (c *Config) FromTaskPolicy(policy *worker_pb.TaskPolicy) error {
  162. if policy == nil {
  163. return fmt.Errorf("policy is nil")
  164. }
  165. // Set general TaskPolicy fields
  166. c.Enabled = policy.Enabled
  167. c.MaxConcurrent = int(policy.MaxConcurrent)
  168. c.ScanIntervalSeconds = int(policy.RepeatIntervalSeconds) // Direct seconds-to-seconds mapping
  169. // Set erasure coding-specific fields from the task config
  170. if ecConfig := policy.GetErasureCodingConfig(); ecConfig != nil {
  171. c.FullnessRatio = float64(ecConfig.FullnessRatio)
  172. c.QuietForSeconds = int(ecConfig.QuietForSeconds)
  173. c.MinSizeMB = int(ecConfig.MinVolumeSizeMb)
  174. c.CollectionFilter = ecConfig.CollectionFilter
  175. }
  176. return nil
  177. }
  178. // LoadConfigFromPersistence loads configuration from the persistence layer if available
  179. func LoadConfigFromPersistence(configPersistence interface{}) *Config {
  180. config := NewDefaultConfig()
  181. // Try to load from persistence if available
  182. if persistence, ok := configPersistence.(interface {
  183. LoadErasureCodingTaskPolicy() (*worker_pb.TaskPolicy, error)
  184. }); ok {
  185. if policy, err := persistence.LoadErasureCodingTaskPolicy(); err == nil && policy != nil {
  186. if err := config.FromTaskPolicy(policy); err == nil {
  187. glog.V(1).Infof("Loaded erasure coding configuration from persistence")
  188. return config
  189. }
  190. }
  191. }
  192. glog.V(1).Infof("Using default erasure coding configuration")
  193. return config
  194. }