redis-sentinel 1.1.3 → 1.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.md +30 -0
- data/CONTRIBUTING.md +12 -0
- data/{LICENSE.txt → MIT-LICENSE} +0 -0
- data/README.md +20 -14
- data/example/test_wait_for_failover_write.rb +21 -0
- data/lib/redis-sentinel/client.rb +8 -3
- data/lib/redis-sentinel/version.rb +1 -1
- data/spec/redis-sentinel/client_spec.rb +33 -0
- metadata +6 -3
data/CHANGELOG.md
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# CHANGELOG
|
2
|
+
|
3
|
+
## 1.1.4
|
4
|
+
|
5
|
+
* Fix discover_master procedure wich failover_reconnect_wait option
|
6
|
+
* Add test_wait_for_failover_write example
|
7
|
+
|
8
|
+
## 1.1.3
|
9
|
+
|
10
|
+
* Cache sentinel connections
|
11
|
+
* Add option failover_reconnect_timeout
|
12
|
+
* Add option failover_reconnect_wait
|
13
|
+
* Add test_wait_for_failover example
|
14
|
+
|
15
|
+
## 1.1.2
|
16
|
+
|
17
|
+
* Ruby 1.8.7 compatibility
|
18
|
+
|
19
|
+
## 1.1.1
|
20
|
+
|
21
|
+
* Fix initialize Redis::ConnectionError
|
22
|
+
|
23
|
+
## 1.1.0
|
24
|
+
|
25
|
+
* Remove background thread, which subscribes switch-master message
|
26
|
+
* Add example
|
27
|
+
|
28
|
+
## 1.0.0
|
29
|
+
|
30
|
+
* First version
|
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
# CONTRIBUTING
|
2
|
+
|
3
|
+
We love pull requests. Here's a quick guide:
|
4
|
+
|
5
|
+
1. Fork it
|
6
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
7
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
8
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
9
|
+
5. Create new Pull Request
|
10
|
+
|
11
|
+
Please make sure you add a test for your change and all tests are passed.
|
12
|
+
(`bundle && rspec spec`)
|
data/{LICENSE.txt → MIT-LICENSE}
RENAMED
File without changes
|
data/README.md
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
# Redis::Sentinel
|
2
2
|
|
3
|
-
|
3
|
+
Another redis automatic master/slave failover solution for ruby by
|
4
4
|
using built-in redis sentinel.
|
5
5
|
|
6
|
-
|
6
|
+
It subscribes message with channel "+switch-master", when message
|
7
7
|
received, it will disconnect current connection and connect to new
|
8
8
|
master server.
|
9
9
|
|
@@ -27,7 +27,7 @@ Specify the sentinel servers and master name
|
|
27
27
|
|
28
28
|
Redis.new(master_name: "master1", sentinels: [{host: "localhost", port: 26379}, {host: "localhost", port: 26380}])
|
29
29
|
|
30
|
-
There are two additional options:
|
30
|
+
There are two additional options:
|
31
31
|
|
32
32
|
1. `:failover_reconnect_timeout` (seconds) will block for that long when
|
33
33
|
redis is unreachable to give failover enough time to take place. Does
|
@@ -38,26 +38,26 @@ There are two additional options:
|
|
38
38
|
|
39
39
|
## Example
|
40
40
|
|
41
|
-
|
41
|
+
Start redis master server, listen on port 16379
|
42
42
|
|
43
43
|
```
|
44
44
|
$ redis-server example/redis-master.conf
|
45
45
|
```
|
46
46
|
|
47
|
-
|
47
|
+
Start redis slave server, listen on port 16380
|
48
48
|
|
49
49
|
```
|
50
50
|
$ redis-server example/redis-slave.conf
|
51
51
|
```
|
52
52
|
|
53
|
-
|
53
|
+
Start 2 sentinel servers
|
54
54
|
|
55
55
|
```
|
56
56
|
$ redis-server example/redis-sentinel1.conf --sentinel
|
57
57
|
$ redis-server example/redis-sentinel2.conf --sentinel
|
58
58
|
```
|
59
59
|
|
60
|
-
|
60
|
+
Run example/test.rb, which will query value of key "foo" every second.
|
61
61
|
|
62
62
|
```
|
63
63
|
$ bundle exec ruby example/test.rb
|
@@ -82,12 +82,18 @@ You will see the stream of "bar" will stop while failover is taking
|
|
82
82
|
place and will resume once it has completed, provided that failover
|
83
83
|
takes less than 30 seconds.
|
84
84
|
|
85
|
-
##
|
85
|
+
## Authors and Contributors
|
86
86
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
87
|
+
* [Richard Huang](https://github.com/flyerhzm) - Creator of the project
|
88
|
+
* [Donald Plummer](https://github.com/dplummer) - Add wait / timeout for
|
89
|
+
redis connection
|
90
|
+
* [Rafał Michalski](https://github.com/royaltm) - Ensure promoted slave
|
91
|
+
become master
|
92
92
|
|
93
|
-
|
93
|
+
Please fork and contribute, any help in making this project better is appreciated!
|
94
|
+
|
95
|
+
This project is a member of the [OSS Manifesto](http://ossmanifesto.org/).
|
96
|
+
|
97
|
+
## Copyright
|
98
|
+
|
99
|
+
Copyright @ 2012 - 2013 Richard Huang. See [MIT-LICENSE](https://github.com/flyerhzm/redis-sentinel/blob/master/MIT-LICENSE) for details
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'redis'
|
2
|
+
require 'redis-sentinel'
|
3
|
+
|
4
|
+
redis = Redis.new(:master_name => "example-test",
|
5
|
+
:sentinels => [
|
6
|
+
{:host => "localhost", :port => 26379},
|
7
|
+
{:host => "localhost", :port => 26380}
|
8
|
+
],
|
9
|
+
:failover_reconnect_timeout => 30,
|
10
|
+
:failover_reconnect_wait => 0.0001)
|
11
|
+
|
12
|
+
redis.set "foo", 1
|
13
|
+
|
14
|
+
while true
|
15
|
+
begin
|
16
|
+
puts redis.incr "foo"
|
17
|
+
rescue Redis::CannotConnectError => e
|
18
|
+
puts "failover took too long to recover", e
|
19
|
+
end
|
20
|
+
sleep 1
|
21
|
+
end
|
@@ -49,7 +49,7 @@ class Redis::Client
|
|
49
49
|
def try_next_sentinel
|
50
50
|
@sentinels << @sentinels.shift
|
51
51
|
if @logger && @logger.debug?
|
52
|
-
@logger.debug
|
52
|
+
@logger.debug "Trying next sentinel: #{@sentinels[0][:host]}:#{@sentinels[0][:port]}"
|
53
53
|
end
|
54
54
|
return @sentinels[0]
|
55
55
|
end
|
@@ -63,13 +63,18 @@ class Redis::Client
|
|
63
63
|
if !host && !port
|
64
64
|
raise Redis::ConnectionError.new("No master named: #{@master_name}")
|
65
65
|
end
|
66
|
-
|
67
|
-
|
66
|
+
is_down, runid = sentinel.sentinel("is-master-down-by-addr", host, port)
|
68
67
|
break
|
69
68
|
rescue Redis::CannotConnectError
|
70
69
|
try_next_sentinel
|
71
70
|
end
|
72
71
|
end
|
72
|
+
|
73
|
+
if is_down == "1" || runid == '?'
|
74
|
+
raise Redis::CannotConnectError.new("The master: #{@master_name} is currently not available.")
|
75
|
+
else
|
76
|
+
@options.merge!(:host => host, :port => port.to_i)
|
77
|
+
end
|
73
78
|
end
|
74
79
|
|
75
80
|
private
|
@@ -37,10 +37,43 @@ describe Redis::Client do
|
|
37
37
|
it "gets the current master" do
|
38
38
|
redis.should_receive(:sentinel).
|
39
39
|
with("get-master-addr-by-name", "master")
|
40
|
+
redis.should_receive(:sentinel).
|
41
|
+
with("is-master-down-by-addr", "remote.server", 8888)
|
40
42
|
subject.discover_master
|
41
43
|
end
|
42
44
|
|
43
45
|
it "should update options" do
|
46
|
+
redis.should_receive(:sentinel).
|
47
|
+
with("is-master-down-by-addr", "remote.server", 8888).once.
|
48
|
+
and_return(["0", "abc"])
|
49
|
+
subject.discover_master
|
50
|
+
expect(subject.host).to eq "remote.server"
|
51
|
+
expect(subject.port).to eq 8888
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should not update options" do
|
55
|
+
redis.should_receive(:sentinel).
|
56
|
+
with("is-master-down-by-addr", "remote.server", 8888).twice.
|
57
|
+
and_return(["1", "abc"], ["0", "?"])
|
58
|
+
2.times do
|
59
|
+
expect do
|
60
|
+
subject.discover_master
|
61
|
+
end.to raise_error(Redis::CannotConnectError, /currently not available/)
|
62
|
+
expect(subject.host).not_to eq "remote.server"
|
63
|
+
expect(subject.port).not_to eq 8888
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should select next sentinel" do
|
68
|
+
Redis.should_receive(:new).with({:host => "localhost", :port => 26379})
|
69
|
+
redis.should_receive(:sentinel).
|
70
|
+
with("get-master-addr-by-name", "master").
|
71
|
+
and_raise(Redis::CannotConnectError)
|
72
|
+
Redis.should_receive(:new).with({:host => "localhost", :port => 26380})
|
73
|
+
redis.should_receive(:sentinel).
|
74
|
+
with("get-master-addr-by-name", "master")
|
75
|
+
redis.should_receive(:sentinel).
|
76
|
+
with("is-master-down-by-addr", "remote.server", 8888)
|
44
77
|
subject.discover_master
|
45
78
|
expect(subject.host).to eq "remote.server"
|
46
79
|
expect(subject.port).to eq 8888
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redis-sentinel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-02-11 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: redis
|
@@ -52,8 +52,10 @@ extensions: []
|
|
52
52
|
extra_rdoc_files: []
|
53
53
|
files:
|
54
54
|
- .gitignore
|
55
|
+
- CHANGELOG.md
|
56
|
+
- CONTRIBUTING.md
|
55
57
|
- Gemfile
|
56
|
-
- LICENSE
|
58
|
+
- MIT-LICENSE
|
57
59
|
- README.md
|
58
60
|
- Rakefile
|
59
61
|
- example/redis-master.conf
|
@@ -62,6 +64,7 @@ files:
|
|
62
64
|
- example/redis-slave.conf
|
63
65
|
- example/test.rb
|
64
66
|
- example/test_wait_for_failover.rb
|
67
|
+
- example/test_wait_for_failover_write.rb
|
65
68
|
- lib/redis-sentinel.rb
|
66
69
|
- lib/redis-sentinel/client.rb
|
67
70
|
- lib/redis-sentinel/version.rb
|