aboutsummaryrefslogtreecommitdiff
path: root/weed/command/master.go
diff options
context:
space:
mode:
authorChris Lu <chrislusf@users.noreply.github.com>2025-10-31 18:29:16 -0700
committerGitHub <noreply@github.com>2025-10-31 18:29:16 -0700
commitf096b067fd2171919810d6e9536e9068b899f7db (patch)
treee0ef0f0da07faa130cd4e230d37e143986041097 /weed/command/master.go
parent5ab49e29712a8ef9fed723c64b668d7e58675566 (diff)
downloadseaweedfs-f096b067fd2171919810d6e9536e9068b899f7db.tar.xz
seaweedfs-f096b067fd2171919810d6e9536e9068b899f7db.zip
weed master add peers=none option for faster startup (#7419)
* weed master -peers=none * single master mode only when peers is none * refactoring * revert duplicated code * revert * Update weed/command/master.go Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> * preventing "none" passed to other components if master is not started --------- Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Diffstat (limited to 'weed/command/master.go')
-rw-r--r--weed/command/master.go38
1 files changed, 34 insertions, 4 deletions
diff --git a/weed/command/master.go b/weed/command/master.go
index 7721c0634..11c57701b 100644
--- a/weed/command/master.go
+++ b/weed/command/master.go
@@ -38,6 +38,10 @@ var (
m MasterOptions
)
+const (
+ raftJoinCheckDelay = 1500 * time.Millisecond // delay before checking if we should join a raft cluster
+)
+
type MasterOptions struct {
port *int
portGrpc *int
@@ -74,7 +78,7 @@ func init() {
m.ip = cmdMaster.Flag.String("ip", util.DetectedHostAddress(), "master <ip>|<server> address, also used as identifier")
m.ipBind = cmdMaster.Flag.String("ip.bind", "", "ip address to bind to. If empty, default to same as -ip option.")
m.metaFolder = cmdMaster.Flag.String("mdir", os.TempDir(), "data directory to store meta data")
- m.peers = cmdMaster.Flag.String("peers", "", "all master nodes in comma separated ip:port list, example: 127.0.0.1:9093,127.0.0.1:9094,127.0.0.1:9095")
+ m.peers = cmdMaster.Flag.String("peers", "", "all master nodes in comma separated ip:port list, example: 127.0.0.1:9093,127.0.0.1:9094,127.0.0.1:9095; use 'none' for single-master mode")
m.volumeSizeLimitMB = cmdMaster.Flag.Uint("volumeSizeLimitMB", 30*1000, "Master stops directing writes to oversized volumes.")
m.volumePreallocate = cmdMaster.Flag.Bool("volumePreallocate", false, "Preallocate disk space for volumes.")
m.maxParallelVacuumPerServer = cmdMaster.Flag.Int("maxParallelVacuumPerServer", 1, "maximum number of volumes to vacuum in parallel per volume server")
@@ -105,6 +109,9 @@ var cmdMaster = &Command{
The example security.toml configuration file can be generated by "weed scaffold -config=security"
+ For single-master setups, use -peers=none to skip Raft quorum wait and enable instant startup.
+ This is ideal for development or standalone deployments.
+
`,
}
@@ -181,6 +188,9 @@ func startMaster(masterOption MasterOptions, masterWhiteList []string) {
// start raftServer
metaDir := path.Join(*masterOption.metaFolder, fmt.Sprintf("m%d", *masterOption.port))
+
+ isSingleMaster := isSingleMasterMode(*masterOption.peers)
+
raftServerOption := &weed_server.RaftServerOption{
GrpcDialOption: security.LoadClientTLS(util.GetViper(), "grpc.master"),
Peers: masterPeers,
@@ -203,6 +213,11 @@ func startMaster(masterOption MasterOptions, masterWhiteList []string) {
if raftServer == nil {
glog.Fatalf("please verify %s is writable, see https://github.com/seaweedfs/seaweedfs/issues/717: %s", *masterOption.metaFolder, err)
}
+ // For single-master mode, initialize cluster immediately without waiting
+ if isSingleMaster {
+ glog.V(0).Infof("Single-master mode: initializing cluster immediately")
+ raftServer.DoJoinCommand()
+ }
}
ms.SetRaftServer(raftServer)
r.HandleFunc("/cluster/status", raftServer.StatusHandler).Methods(http.MethodGet, http.MethodHead)
@@ -230,10 +245,10 @@ func startMaster(masterOption MasterOptions, masterWhiteList []string) {
}
go grpcS.Serve(grpcL)
- timeSleep := 1500 * time.Millisecond
- if !*masterOption.raftHashicorp {
+ // For multi-master mode with non-Hashicorp raft, wait and check if we should join
+ if !*masterOption.raftHashicorp && !isSingleMaster {
go func() {
- time.Sleep(timeSleep)
+ time.Sleep(raftJoinCheckDelay)
ms.Topo.RaftServerAccessLock.RLock()
isEmptyMaster := ms.Topo.RaftServer.Leader() == "" && ms.Topo.RaftServer.IsLogEmpty()
@@ -292,9 +307,24 @@ func startMaster(masterOption MasterOptions, masterWhiteList []string) {
select {}
}
+func isSingleMasterMode(peers string) bool {
+ p := strings.ToLower(strings.TrimSpace(peers))
+ return p == "none"
+}
+
func checkPeers(masterIp string, masterPort int, masterGrpcPort int, peers string) (masterAddress pb.ServerAddress, cleanedPeers []pb.ServerAddress) {
glog.V(0).Infof("current: %s:%d peers:%s", masterIp, masterPort, peers)
masterAddress = pb.NewServerAddress(masterIp, masterPort, masterGrpcPort)
+
+ // Handle special case: -peers=none for single-master setup
+ if isSingleMasterMode(peers) {
+ glog.V(0).Infof("Running in single-master mode (peers=none), no quorum required")
+ cleanedPeers = []pb.ServerAddress{masterAddress}
+ return
+ }
+
+ peers = strings.TrimSpace(peers)
+
cleanedPeers = pb.ServerAddresses(peers).ToAddresses()
hasSelf := false