func main() { buf, err := ioutil.ReadFile("./config.json") if err != nil { log.Fatal(err) } var v Config err = json.Unmarshal(buf, &v) dataDir := v.DataDir os.MkdirAll(dataDir, 0755) if err != nil { log.Fatal(err) } cfg := raft.DefaultConfig() // cfg.EnableSingleNode = true fsm := new(Word) fsm.words = "hahaha" dbStore, err := raftboltdb.NewBoltStore(path.Join(dataDir, "raft_db")) if err != nil { log.Fatal(err) } fileStore, err := raft.NewFileSnapshotStore(dataDir, 1, os.Stdout) if err != nil { log.Fatal(err) } trans, err := raft.NewTCPTransport(v.Bind, nil, 3, 5*time.Second, os.Stdout) if err != nil { log.Fatal(err) } peers := make([]string, 0, 10) peers = raft.AddUniquePeer(peers, "192.168.78.151:12345") peers = raft.AddUniquePeer(peers, "192.168.78.151:12346") peers = raft.AddUniquePeer(peers, "192.168.78.151:12347") peerStore := raft.NewJSONPeers(dataDir, trans) peerStore.SetPeers(peers) r, err := raft.NewRaft(cfg, fsm, dbStore, dbStore, fileStore, peerStore, trans) t := time.NewTicker(time.Duration(1) * time.Second) for { select { case <-t.C: fmt.Println(r.Leader()) } } }
// Open opens the store. If enableSingle is set, and there are no existing peers, // then this node becomes the first node, and therefore leader, of the cluster. func (s *Store) Open(enableSingle bool) error { // Setup Raft configuration. config := raft.DefaultConfig() // Check for any existing peers. peers, err := readPeersJSON(filepath.Join(s.RaftDir, "peers.json")) if err != nil { return err } // Allow the node to entry single-mode, potentially electing itself, if // explicitly enabled and there is only 1 node in the cluster already. if enableSingle && len(peers) <= 1 { s.logger.Println("enabling single-node mode") config.EnableSingleNode = true config.DisableBootstrapAfterElect = false } // Setup Raft communication. addr, err := net.ResolveTCPAddr("tcp", s.RaftBind) if err != nil { return err } transport, err := raft.NewTCPTransport(s.RaftBind, addr, 3, 10*time.Second, os.Stderr) if err != nil { return err } // Create peer storage. peerStore := raft.NewJSONPeers(s.RaftDir, transport) // Create the snapshot store. This allows the Raft to truncate the log. snapshots, err := raft.NewFileSnapshotStore(s.RaftDir, retainSnapshotCount, os.Stderr) if err != nil { return fmt.Errorf("file snapshot store: %s", err) } // Create the log store and stable store. logStore, err := raftboltdb.NewBoltStore(filepath.Join(s.RaftDir, "raft.db")) if err != nil { return fmt.Errorf("new bolt store: %s", err) } // Instantiate the Raft systems. ra, err := raft.NewRaft(config, (*fsm)(s), logStore, logStore, snapshots, peerStore, transport) if err != nil { return fmt.Errorf("new raft: %s", err) } s.raft = ra return nil }
func main() { sstore, err := raftboltdb.NewBoltStore("/tmp/stablestore") if err != nil { fmt.Printf("%v", err) os.Exit(1) } logstore, err := raftboltdb.NewBoltStore("/tmp/logstore") if err != nil { fmt.Printf("Failed to create logstore") os.Exit(1) } snaps, err := raft.NewFileSnapshotStoreWithLogger("/tmp/snapshots", 3, nil) errorOnExit(err) transport, err := raft.NewTCPTransport("127.0.0.1:7000", nil, 10, 10*time.Second, nil) errorOnExit(err) peerstore := raft.NewJSONPeers("/tmp/peers", transport) conf := raft.DefaultConfig() conf.EnableSingleNode = true conf.SnapshotThreshold = 40 conf.SnapshotInterval = 10 * time.Second fsm := NewMyFsm() raftmod, err := raft.NewRaft(conf, fsm, logstore, sstore, snaps, peerstore, transport) time.Sleep(2 * time.Second) fmt.Printf("Leader is %v\n", raftmod.Leader()) future := raftmod.Apply([]byte("hello:value"), 0) raftFutureErrorCheck(future) i := 0 for ; i < 100; i++ { time.Sleep(2 * time.Millisecond) future := raftmod.Apply([]byte(fmt.Sprintf("key%d:value%d", i, i)), 0) raftFutureErrorCheck(future) } fmt.Printf("Do some fun\n") reader := bufio.NewReader(os.Stdin) for { fmt.Printf("Enter 1 to put, 2 to get, 3 to quit: ") text, _ := reader.ReadString('\n') text = strings.Trim(text, "\n") if text == "3" { os.Exit(0) } else if text == "1" { fmt.Printf("Key: ") key, _ := reader.ReadString('\n') key = strings.Trim(key, "\n\b \t\b") if key == "" { fmt.Printf("Empty key, continuing") continue } fmt.Printf("Value: ") value, _ := reader.ReadString('\n') value = strings.Trim(value, "\n") raftmod.Apply([]byte(fmt.Sprintf("%s:%s", key, value)), 0) } else if text == "2" { fmt.Printf("Key: ") key, _ := reader.ReadString('\n') key = strings.Trim(key, "\n\b \t\b") if key == "" { fmt.Printf("Empty key, continuing") continue } val, err := fsm.Get(fmt.Sprintf(key)) if err != nil { fmt.Printf("Failed to get %s\n", key) } else { fmt.Printf("The value for key:%s is %s\n", key, val) } } } }
func newRaft(a *App) (Cluster, error) { r := new(Raft) if len(a.config.Raft.Addr) == 0 { return nil, nil } peers := make([]string, 0, len(a.config.Raft.Cluster)) r.raftAddr = a.config.Raft.Addr addr, err := net.ResolveTCPAddr("tcp", r.raftAddr) if err != nil { return nil, fmt.Errorf("invalid raft addr format %s, must host:port, err:%v", r.raftAddr, err) } peers = raft.AddUniquePeer(peers, addr.String()) for _, cluster := range a.config.Raft.Cluster { addr, err = net.ResolveTCPAddr("tcp", cluster) if err != nil { return nil, fmt.Errorf("invalid cluster format %s, must host:port, err:%v", cluster, err) } peers = raft.AddUniquePeer(peers, addr.String()) } os.MkdirAll(a.config.Raft.DataDir, 0755) cfg := raft.DefaultConfig() if len(a.config.Raft.LogDir) == 0 { r.log = os.Stdout } else { os.MkdirAll(a.config.Raft.LogDir, 0755) logFile := path.Join(a.config.Raft.LogDir, "raft.log") f, err := os.OpenFile(logFile, os.O_CREATE|os.O_APPEND|os.O_RDWR, 0644) if err != nil { return nil, err } r.log = f cfg.LogOutput = r.log } raftDBPath := path.Join(a.config.Raft.DataDir, "raft_db") r.dbStore, err = raftboltdb.NewBoltStore(raftDBPath) if err != nil { return nil, err } fileStore, err := raft.NewFileSnapshotStore(a.config.Raft.DataDir, 1, r.log) if err != nil { return nil, err } r.trans, err = raft.NewTCPTransport(r.raftAddr, nil, 3, 5*time.Second, r.log) if err != nil { return nil, err } r.peerStore = raft.NewJSONPeers(a.config.Raft.DataDir, r.trans) if a.config.Raft.ClusterState == ClusterStateNew { log.Printf("[INFO] cluster state is new, use new cluster config") r.peerStore.SetPeers(peers) } else { log.Printf("[INFO] cluster state is existing, use previous + new cluster config") ps, err := r.peerStore.Peers() if err != nil { log.Printf("[INFO] get store peers error %v", err) return nil, err } for _, peer := range peers { ps = raft.AddUniquePeer(ps, peer) } r.peerStore.SetPeers(ps) } if peers, _ := r.peerStore.Peers(); len(peers) <= 1 { cfg.EnableSingleNode = true log.Println("[INFO] raft will run in single node mode, may only be used in test") } r.r, err = raft.NewRaft(cfg, a.fsm, r.dbStore, r.dbStore, fileStore, r.peerStore, r.trans) return r, err }
func newPeer(c *Config, fsm *fsm) (*peer, error) { r := &peer{} var err error = nil r.addr = c.Raft.Addr os.MkdirAll(c.Raft.DataDir, 0755) cfg := raft.DefaultConfig() raftDBPath := path.Join(c.Raft.DataDir, "raft_db") r.dbStore, err = raftboltdb.NewBoltStore(raftDBPath) if err != nil { return nil, err } fileStore, err := raft.NewFileSnapshotStore(c.Raft.DataDir, 1, os.Stderr) if err != nil { return nil, err } r.trans, err = raft.NewTCPTransport(r.addr, nil, 3, 5*time.Second, os.Stderr) if err != nil { return nil, err } r.peerStore = raft.NewJSONPeers(c.Raft.DataDir, r.trans) if c.Raft.ClusterState == ClusterStateNew { log.Info("cluster state is new, use new cluster config") r.peerStore.SetPeers(c.Raft.Cluster) } else { log.Info("cluster state is existing, use previous + new cluster config") ps, err := r.peerStore.Peers() if err != nil { log.Error("get store peers error %v", err) return nil, err } for _, peer := range c.Raft.Cluster { ps = raft.AddUniquePeer(ps, peer) } r.peerStore.SetPeers(ps) } if peers, _ := r.peerStore.Peers(); len(peers) <= 1 { cfg.EnableSingleNode = true log.Notice("raft running in single node mode") } r.fsm = fsm r.r, err = raft.NewRaft(cfg, fsm, r.dbStore, r.dbStore, fileStore, r.peerStore, r.trans) if err != nil { return nil, err } // watch for leadership changes go func() { for isLeader := range r.r.LeaderCh() { if isLeader { log.Info("new leader http: %v", c.Addr) r.apply(&action{Cmd: CmdNewLeader, Leader: c.Addr}, applyRetries) } } }() return r, nil }
// NewRaft creates a new Raft instance. raft data is stored under the raft dir in prefix. func NewRaft(c RaftConfig, prefix string, logDir string) (r *Raft, err error) { r = new(Raft) config := raft.DefaultConfig() config.EnableSingleNode = c.Single var logOutput *os.File if logDir != "\n" { logFile := path.Join(logDir, "raft.log") logOutput, err = os.OpenFile(logFile, os.O_CREATE|os.O_RDWR|os.O_APPEND, 0666) if err != nil { Fatal("Could not open raft log file: ", err) } config.LogOutput = logOutput } raftDir := path.Join(prefix, "raft") err = os.MkdirAll(raftDir, 0755) if err != nil { Fatal("Could not create raft storage dir: ", err) } fss, err := raft.NewFileSnapshotStore(raftDir, 1, nil) if err != nil { Error("Could not initialize raft snapshot store: ", err) return } // this should be our externally visible address. If not provided in the // config as 'advertise', we use the address of the listen config. if c.Advertise == nil { c.Advertise = &c.Listen } a, err := net.ResolveTCPAddr("tcp", *c.Advertise) if err != nil { Error("Could not lookup raft advertise address: ", err) return } r.transport, err = raft.NewTCPTransport(c.Listen, a, 3, 10*time.Second, nil) if err != nil { Error("Could not create raft transport: ", err) return } peerStore := raft.NewJSONPeers(raftDir, r.transport) if !c.Single { var peers []net.Addr peers, err = peerStore.Peers() if err != nil { return } for _, peerStr := range c.Peers { peer, err := net.ResolveTCPAddr("tcp", peerStr) if err != nil { Fatal("Bad peer:", err) } if !raft.PeerContained(peers, peer) { peerStore.SetPeers(raft.AddUniquePeer(peers, peer)) } } } else { Warn("Running in single node permitted mode. Only use this for testing!") } r.mdb, err = raftmdb.NewMDBStore(raftDir) if err != nil { Error("Could not create raft store:", err) return } storage, err := NewStorage() if err != nil { Error("Could not create storage:", err) return } r.fsm = &FSM{storage} r.raft, err = raft.NewRaft(config, r.fsm, r.mdb, r.mdb, fss, peerStore, r.transport) if err != nil { Error("Could not initialize raft: ", err) return } return }