redis-cluster 0.0.7 → 0.0.8
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.
- checksums.yaml +4 -4
- data/README.md +83 -17
- data/lib/redis-cluster.rb +6 -1
- data/lib/redis_cluster/cluster.rb +28 -12
- data/lib/redis_cluster/function/set.rb +65 -2
- data/lib/redis_cluster/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: aef27de1754b1b2a7106672eeec3073a431d0d8a
|
4
|
+
data.tar.gz: 8762651a0de67037a3118a0b4fbf87fb95d85b36
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a23e10568bcf5058159a96a5e838f2b89c74909ae8bf9930f09906f3d4526322415cca104899a164b143af4ce7cb1f1e31e8afcd8c142dc25122521814287682
|
7
|
+
data.tar.gz: 020d80d301681e521ec0aec29031bf1451197c12406b6597a58d404acb92456b95f7895600477cec0c388a396300475a3fd29b6f87dff76e8bf7845b64dcb6a2
|
data/README.md
CHANGED
@@ -2,35 +2,101 @@
|
|
2
2
|
[](https://circleci.com/gh/bukalapak/redis-cluster)
|
3
3
|
[](https://codecov.io/gh/bukalapak/redis-cluster)
|
4
4
|
|
5
|
-
##
|
5
|
+
## Description
|
6
6
|
|
7
|
-
|
8
|
-
````ruby
|
9
|
-
gem install 'redis-cluster'
|
10
|
-
````
|
7
|
+
redis-cluster is redis cluster client for ruby that support pipelining.
|
11
8
|
|
12
|
-
|
13
|
-
````ruby
|
14
|
-
seed = ['127.0.0.1:7001', '127.0.0.1:7002']
|
15
|
-
redis = RedisCluster.new(seed, redis_opts: { timeout: 5, connect_timeout: 1 }, cluster_opts: { read_mode: :master_slave, silent: true, logger: Logger.new })
|
16
|
-
````
|
9
|
+
## Owner
|
17
10
|
|
18
|
-
|
11
|
+
SRE Bukalapak
|
12
|
+
|
13
|
+
## Contact
|
14
|
+
|
15
|
+
[Contributors](https://github.com/bukalapak/redis-cluster/graphs/contributors)
|
16
|
+
|
17
|
+
## Onboarding and Development Guide
|
18
|
+
|
19
|
+
### Getting started
|
20
|
+
|
21
|
+
1. Install redis-cluster
|
22
|
+
|
23
|
+
````ruby
|
24
|
+
gem install 'redis-cluster'
|
25
|
+
````
|
26
|
+
|
27
|
+
2. Start `irb`. This command will start a redis-cluster client from seed servers.
|
28
|
+
|
29
|
+
````ruby
|
30
|
+
seed = ['127.0.0.1:7001', '127.0.0.1:7002']
|
31
|
+
redis = RedisCluster.new(
|
32
|
+
seed,
|
33
|
+
redis_opts: { timeout: 5, connect_timeout: 1 },
|
34
|
+
cluster_opts: { force_cluster: false, read_mode: :master_slave, silent: true, logger: Logger.new }
|
35
|
+
)
|
36
|
+
````
|
37
|
+
|
38
|
+
### Development Guide
|
39
|
+
|
40
|
+
1. You need [rvm](https://rvm.io) and [bundler](http://bundler.io/) to test.
|
41
|
+
See [here](https://rvm.io/rvm/install) to install `rvm`.
|
42
|
+
And run these commands to install `bundler` and other dependencies
|
43
|
+
|
44
|
+
````
|
45
|
+
gem install bundler
|
46
|
+
bundle install
|
47
|
+
````
|
48
|
+
|
49
|
+
2. You also need redis binary.
|
50
|
+
See [here](https://redis.io/download) to install `redis`
|
51
|
+
|
52
|
+
3. Fork this repo
|
53
|
+
|
54
|
+
4. Make your change and it's test.
|
55
|
+
|
56
|
+
````
|
57
|
+
vim lib/**.rb
|
58
|
+
vim spec/**_spec.rb
|
59
|
+
````
|
60
|
+
|
61
|
+
5. Optionally, run the test in your local
|
62
|
+
|
63
|
+
````
|
64
|
+
rake # run all test and lint
|
65
|
+
````
|
66
|
+
|
67
|
+
6. Commit and push your change to upstream
|
68
|
+
|
69
|
+
````
|
70
|
+
git commit -m "message"
|
71
|
+
git push # add "--set-upstream branch_name" after "git push" if you haven't set the upstream
|
72
|
+
````
|
73
|
+
|
74
|
+
7. Open pull request in `Github`
|
75
|
+
|
76
|
+
8. If test in CI is success, ask someone to review your code.
|
77
|
+
|
78
|
+
9. If review is passed, your pull request can be merged.
|
79
|
+
|
80
|
+
### Configuration
|
81
|
+
|
82
|
+
#### redis_opts
|
19
83
|
|
20
|
-
### redis_opts
|
21
84
|
Option for Redis::Client instance. Set timeout, ssl, etc here.
|
22
85
|
|
23
|
-
|
86
|
+
#### cluster_opts
|
87
|
+
|
24
88
|
Option for RedisCluster.
|
89
|
+
- `force_cluster`: if true, RedisCluster will only work on clustered Redis or otherwise can also work on standalone Redis. The default value is `false`.
|
25
90
|
- `read_mode`: for read command, RedisClient can try to read from slave if specified. Supported option is `:master`(default), `:slave`, and `:master_slave`.
|
26
91
|
- `silent`: whether or not RedisCluster will raise error.
|
27
92
|
- `logger`: if specified. RedisCluster will log all of RedisCluster errors here.
|
28
93
|
|
29
|
-
|
94
|
+
### Limitation
|
95
|
+
|
30
96
|
All multi keys operation, cluster command, multi-exec, and some commands are not supported.
|
31
97
|
|
32
|
-
|
98
|
+
### Pipeline
|
99
|
+
|
33
100
|
Can be used with same interface as standalone redis client. See [redis pipeline](https://github.com/redis/redis-rb#pipelining)
|
34
101
|
|
35
|
-
##
|
36
|
-
[Fork the project](https://github.com/bukalapak/redis-cluster) and send pull requests.
|
102
|
+
## FAQ
|
data/lib/redis-cluster.rb
CHANGED
@@ -15,7 +15,8 @@ class RedisCluster
|
|
15
15
|
|
16
16
|
def initialize(seeds, redis_opts: nil, cluster_opts: nil)
|
17
17
|
@options = cluster_opts || {}
|
18
|
-
|
18
|
+
cluster_options = redis_opts || {}
|
19
|
+
@cluster = Cluster.new(seeds, cluster_options.merge(force_cluster: force_cluster?))
|
19
20
|
|
20
21
|
super()
|
21
22
|
end
|
@@ -32,6 +33,10 @@ class RedisCluster
|
|
32
33
|
options[:read_mode] || :master
|
33
34
|
end
|
34
35
|
|
36
|
+
def force_cluster?
|
37
|
+
options[:force_cluster]
|
38
|
+
end
|
39
|
+
|
35
40
|
def connected?
|
36
41
|
cluster.connected?
|
37
42
|
end
|
@@ -18,6 +18,10 @@ class RedisCluster
|
|
18
18
|
init_client(seeds)
|
19
19
|
end
|
20
20
|
|
21
|
+
def force_cluster?
|
22
|
+
options[:force_cluster]
|
23
|
+
end
|
24
|
+
|
21
25
|
# Return Redis::Client for a given key.
|
22
26
|
# Modified from https://github.com/antirez/redis-rb-cluster/blob/master/cluster.rb#L104-L117
|
23
27
|
def slot_for(key)
|
@@ -75,17 +79,26 @@ class RedisCluster
|
|
75
79
|
def slots_and_clients(client)
|
76
80
|
replicas = ::Hash.new{ |h, k| h[k] = [] }
|
77
81
|
|
78
|
-
client.call([:cluster, :slots])
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
82
|
+
result = client.call([:cluster, :slots])
|
83
|
+
if result.is_a?(StandardError)
|
84
|
+
if result.message.eql?('ERR This instance has cluster support disabled') &&
|
85
|
+
!force_cluster?
|
86
|
+
host, port = client.url.split(':', 2)
|
87
|
+
result = [[0, HASH_SLOTS - 1, [host, port, nil], [host, port, nil]]]
|
88
|
+
else
|
89
|
+
raise result
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
result.each do |arr|
|
94
|
+
arr[2..-1].each_with_index do |a, i|
|
95
|
+
cli = self["#{a[0]}:#{a[1]}"]
|
96
|
+
replicas[arr[0]] << cli
|
97
|
+
cli.call([:readonly]) if i.nonzero?
|
98
|
+
end
|
99
|
+
|
100
|
+
(arr[0]..arr[1]).each do |slot|
|
101
|
+
slots[slot] = replicas[arr[0]]
|
89
102
|
end
|
90
103
|
end
|
91
104
|
|
@@ -112,7 +125,10 @@ class RedisCluster
|
|
112
125
|
|
113
126
|
def create_client(url)
|
114
127
|
host, port = url.split(':', 2)
|
115
|
-
|
128
|
+
client_options = options.clone.tap do |opts|
|
129
|
+
opts.delete(:force_update)
|
130
|
+
end
|
131
|
+
Client.new(client_options.merge(host: host, port: port))
|
116
132
|
end
|
117
133
|
|
118
134
|
# -----------------------------------------------------------------------------
|
@@ -8,8 +8,8 @@ class RedisCluster
|
|
8
8
|
# see https://redis.io/commands#set. Most of the code are copied from
|
9
9
|
# https://github.com/redis/redis-rb/blob/master/lib/redis.rb.
|
10
10
|
#
|
11
|
-
# SETTER = [:sadd, :spop, :srem]
|
12
|
-
# GETTER = [:scard, :
|
11
|
+
# SETTER = [:sadd, :spop, :srem, :sdiffstore, :sinterstore, :smove, :sunionstore]
|
12
|
+
# GETTER = [:scard, :sismember, :smembers, :srandmember, :sscan, :sdiff, :sinter, :sunion]
|
13
13
|
module Set
|
14
14
|
|
15
15
|
# Get the number of members in a set.
|
@@ -78,6 +78,69 @@ class RedisCluster
|
|
78
78
|
def smembers(key)
|
79
79
|
call(key, [:smembers, key], read: true)
|
80
80
|
end
|
81
|
+
|
82
|
+
# Subtract multiple sets.
|
83
|
+
#
|
84
|
+
# @param [String, Array<String>] keys keys pointing to sets to subtract
|
85
|
+
# @return [Array<String>] members in the difference
|
86
|
+
def sdiff(*keys)
|
87
|
+
call(keys, [:sdiff] + keys, read: true)
|
88
|
+
end
|
89
|
+
|
90
|
+
# Subtract multiple sets and store the resulting set in a key.
|
91
|
+
#
|
92
|
+
# @param [String] destination destination key
|
93
|
+
# @param [String, Array<String>] keys keys pointing to sets to subtract
|
94
|
+
# @return [Fixnum] number of elements in the resulting set
|
95
|
+
def sdiffstore(destination, *keys)
|
96
|
+
call([keys, destination], [:sdiffstore, destination] + keys)
|
97
|
+
end
|
98
|
+
|
99
|
+
# Intersect multiple sets.
|
100
|
+
#
|
101
|
+
# @param [String, Array<String>] keys keys pointing to sets to intersect
|
102
|
+
# @return [Array<String>] members in the intersection
|
103
|
+
def sinter(*keys)
|
104
|
+
call(keys, [:sinter] + keys, read: true)
|
105
|
+
end
|
106
|
+
|
107
|
+
# Intersect multiple sets and store the resulting set in a key.
|
108
|
+
#
|
109
|
+
# @param [String] destination destination key
|
110
|
+
# @param [String, Array<String>] keys keys pointing to sets to intersect
|
111
|
+
# @return [Fixnum] number of elements in the resulting set
|
112
|
+
def sinterstore(destination, *keys)
|
113
|
+
call([keys, destination], [:sinterstore, destination] + keys)
|
114
|
+
end
|
115
|
+
|
116
|
+
# Move a member from one set to another.
|
117
|
+
#
|
118
|
+
# @param [String] source source key
|
119
|
+
# @param [String] destination destination key
|
120
|
+
# @param [String] member member to move from `source` to `destination`
|
121
|
+
# @return [Boolean]
|
122
|
+
def smove(source, destination, member)
|
123
|
+
call([source, destination],
|
124
|
+
[:smove, source, destination, member],
|
125
|
+
transform: Redis::Boolify)
|
126
|
+
end
|
127
|
+
|
128
|
+
# Add multiple sets.
|
129
|
+
#
|
130
|
+
# @param [String, Array<String>] keys keys pointing to sets to unify
|
131
|
+
# @return [Array<String>] members in the union
|
132
|
+
def sunion(*keys)
|
133
|
+
call(keys, [:sunion] + keys, read: true)
|
134
|
+
end
|
135
|
+
|
136
|
+
# Add multiple sets and store the resulting set in a key.
|
137
|
+
#
|
138
|
+
# @param [String] destination destination key
|
139
|
+
# @param [String, Array<String>] keys keys pointing to sets to unify
|
140
|
+
# @return [Fixnum] number of elements in the resulting set
|
141
|
+
def sunionstore(destination, *keys)
|
142
|
+
call([keys, destination], [:sunionstore, destination] + keys)
|
143
|
+
end
|
81
144
|
end
|
82
145
|
end
|
83
146
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redis-cluster
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bukalapak
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-08-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redis
|