1
0
Fork 0

Don't join unless actually necessary

master
Philip O'Toole 9 years ago
parent 7d5c79a61d
commit e8c92e088c

@ -1,3 +1,6 @@
## 2.2.3 (unreleased)
- [PR #104](https://github.com/otoolep/rqlite/pull/104): Handle the `-join` option sensibly when already member of cluster.
## 2.2.2 (April 24th 2016)
- [PR #96](https://github.com/otoolep/rqlite/pull/96): Add build time to status output.
- [PR #101](https://github.com/otoolep/rqlite/pull/101): Fix restore to in-memory databases.

@ -39,14 +39,7 @@ rqlited -http localhost:4005 -raft :4006 -join http://localhost:4001 ~/node.3
Under each node will be an SQLite file, which should remain in consensus. You can create clusters of any size, but clusters of 3, 5, and 7 nodes are most practical. Clusters larger than this become impractical, due to the number of nodes that must be contacted before a change can take place.
### Restarting a node
If a node needs to be restarted, perhaps because of failure, don't pass the `-join` option. Using the example nodes above, if node 2 needed to be restarted, do so as follows:
```bash
rqlited -http localhost:4005 -raft :4006 ~/node.3
```
On restart it will rejoin the cluster and apply any changes to the local SQLite database that took place while it was down. Depending on the number of changes in the Raft log, restarts may take a little while.
When restarting a node, there is no further need to pass `-join`. It will be ignored if a node is already a member of a cluster.
## Data API
rqlite exposes an HTTP API allowing the database to be modified such that the changes are replicated. Queries are also executed using the HTTP API, though the SQLite database could be queried directly. Modifications go through the Raft log, ensuring only changes committed by a quorum of rqlite nodes are actually executed against the SQLite database. Queries do not __necessarily__ go through the Raft log, however, since they do not change the state of the database, and therefore do not need to be captured in the log. More on this later.

@ -150,10 +150,14 @@ func main() {
// If join was specified, make the join request.
if joinAddr != "" {
if err := join(joinAddr, noVerify, raftAddr); err != nil {
log.Fatalf("failed to join node at %s: %s", joinAddr, err.Error())
if !store.JoinRequired() {
log.Println("node is already member of cluster, ignoring join request")
} else {
if err := join(joinAddr, noVerify, raftAddr); err != nil {
log.Fatalf("failed to join node at %s: %s", joinAddr, err.Error())
}
log.Println("successfully joined node at", joinAddr)
}
log.Println("successfully joined node at", joinAddr)
}
// Create HTTP server and load authentication information, if supplied.

@ -119,11 +119,12 @@ type Store struct {
mu sync.RWMutex // Sync access between queries and snapshots.
ln *networkLayer // Raft network between nodes.
raft *raft.Raft // The consensus mechanism.
dbConf *DBConfig // SQLite database config.
dbPath string // Path to underlying SQLite file, if not in-memory.
db *sql.DB // The underlying SQLite store.
ln *networkLayer // Raft network between nodes.
raft *raft.Raft // The consensus mechanism.
dbConf *DBConfig // SQLite database config.
dbPath string // Path to underlying SQLite file, if not in-memory.
db *sql.DB // The underlying SQLite store.
joinRequired bool // Whether an explicit join is required.
metaMu sync.RWMutex
meta *clusterMeta
@ -181,6 +182,7 @@ func (s *Store) Open(enableSingle bool) error {
if err != nil {
return err
}
s.joinRequired = len(peers) <= 1
// Allow the node to entry single-mode, potentially electing itself, if
// explicitly enabled and there is only 1 node in the cluster already.
@ -240,6 +242,11 @@ func (s *Store) Close(wait bool) error {
return nil
}
// JoinRequired returns whether the node needs to join a cluster after being opened.
func (s *Store) JoinRequired() bool {
return s.joinRequired
}
// Path returns the path to the store's storage directory.
func (s *Store) Path() string {
return s.raftDir

Loading…
Cancel
Save