From 8e67c4f597f42b2b0d76933bbb8a811b23f90a14 Mon Sep 17 00:00:00 2001 From: Chris Lu Date: Tue, 24 May 2016 10:45:28 -0700 Subject: [PATCH] clean up old config only when peers are changed. fix https://github.com/chrislusf/seaweedfs/issues/307 --- go/weed/glide.lock | 22 +---------- go/weed/weed_server/raft_server.go | 60 +++++++++++++++++++++++------- 2 files changed, 47 insertions(+), 35 deletions(-) diff --git a/go/weed/glide.lock b/go/weed/glide.lock index cb22ec8b6..3575d14d5 100644 --- a/go/weed/glide.lock +++ b/go/weed/glide.lock @@ -1,5 +1,5 @@ hash: 97328ff2a0b9e682660bd51e424a7f850388df96bd153fa6f9ee419c993065c1 -updated: 2016-05-23T14:27:00.216163267-07:00 +updated: 2016-05-24T10:27:49.252798956-07:00 imports: - name: bazil.org/fuse version: 5d02b06737b3b3c2e6a44e03348b6f2b44aa6835 @@ -12,26 +12,6 @@ imports: version: 90f631ee823c83f594f27257bab64911190856af subpackages: - protobuf -- name: github.com/chrislusf/seaweedfs - version: dfde029430fabd7fc29b8e4f61d1e80b64d6a4de - subpackages: - - go/filer - - go/glog - - go/operation - - go/security - - go/storage - - go/util - - go/weed/weed_server - - go/filer/cassandra_store - - go/filer/embedded_filer - - go/filer/flat_namespace - - go/filer/redis_store - - go/images - - go/sequence - - go/stats - - go/topology - - go/weed/weed_server/master_ui - - go/weed/weed_server/volume_server_ui - name: github.com/dgrijalva/jwt-go version: 40bd0f3b4891a9d7f121bfb7b8e8b0525625e262 - name: github.com/disintegration/imaging diff --git a/go/weed/weed_server/raft_server.go b/go/weed/weed_server/raft_server.go index 9c8947862..bc0414679 100644 --- a/go/weed/weed_server/raft_server.go +++ b/go/weed/weed_server/raft_server.go @@ -11,6 +11,8 @@ import ( "net/url" "os" "path" + "reflect" + "sort" "strings" "time" @@ -49,8 +51,9 @@ func NewRaftServer(r *mux.Router, peers []string, httpAddr string, dataDir strin transporter.Transport.MaxIdleConnsPerHost = 1024 glog.V(1).Infof("Starting RaftServer with IP:%v:", httpAddr) - // Clear old cluster configurations if peers are set - if len(s.peers) > 0 { + // Clear old cluster configurations if peers are changed + if oldPeers, changed := isPeersChanged(s.dataDir, httpAddr, s.peers); changed { + glog.V(0).Infof("Peers Change: %v => %v", oldPeers, s.peers) os.RemoveAll(path.Join(s.dataDir, "conf")) os.RemoveAll(path.Join(s.dataDir, "log")) os.RemoveAll(path.Join(s.dataDir, "snapshot")) @@ -71,18 +74,23 @@ func NewRaftServer(r *mux.Router, peers []string, httpAddr string, dataDir strin if len(s.peers) > 0 { // Join to leader if specified. - glog.V(0).Infoln("Joining cluster:", strings.Join(s.peers, ",")) - time.Sleep(time.Duration(rand.Intn(1000)) * time.Millisecond) - firstJoinError := s.Join(s.peers) - if firstJoinError != nil { - glog.V(0).Infoln("No existing server found. Starting as leader in the new cluster.") - _, err := s.raftServer.Do(&raft.DefaultJoinCommand{ - Name: s.raftServer.Name(), - ConnectionString: "http://" + s.httpAddr, - }) - if err != nil { - glog.V(0).Infoln(err) - return nil + for { + glog.V(0).Infoln("Joining cluster:", strings.Join(s.peers, ",")) + time.Sleep(time.Duration(rand.Intn(1000)) * time.Millisecond) + firstJoinError := s.Join(s.peers) + if firstJoinError != nil { + glog.V(0).Infoln("No existing server found. Starting as leader in the new cluster.") + _, err := s.raftServer.Do(&raft.DefaultJoinCommand{ + Name: s.raftServer.Name(), + ConnectionString: "http://" + s.httpAddr, + }) + if err != nil { + glog.V(0).Infoln(err) + } else { + break + } + } else { + break } } } else if s.raftServer.IsLogEmpty() { @@ -116,6 +124,30 @@ func (s *RaftServer) Peers() (members []string) { return } +func isPeersChanged(dir string, self string, peers []string) (oldPeers []string, changed bool) { + confPath := path.Join(dir, "conf") + // open conf file + b, err := ioutil.ReadFile(confPath) + if err != nil { + return oldPeers, true + } + conf := &raft.Config{} + if err = json.Unmarshal(b, conf); err != nil { + return oldPeers, true + } + + for _, p := range conf.Peers { + oldPeers = append(oldPeers, strings.TrimPrefix(p.ConnectionString, "http://")) + } + oldPeers = append(oldPeers, self) + + sort.Strings(peers) + sort.Strings(oldPeers) + + return oldPeers, reflect.DeepEqual(peers, oldPeers) + +} + // Join joins an existing cluster. func (s *RaftServer) Join(peers []string) error { command := &raft.DefaultJoinCommand{