-
Notifications
You must be signed in to change notification settings - Fork 952
Expand file tree
/
Copy pathredis_client_cluster.hpp
More file actions
252 lines (225 loc) · 8.67 KB
/
redis_client_cluster.hpp
File metadata and controls
252 lines (225 loc) · 8.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
#pragma once
#include "../acl_cpp_define.hpp"
#include <vector>
#include <map>
#include "../stdlib/string.hpp"
#include "../connpool/connect_manager.hpp"
#if !defined(ACL_CLIENT_ONLY) && !defined(ACL_REDIS_DISABLE)
namespace acl {
class sslbase_conf;
class redis_client_pool;
/**
* Redis client cluster class. By registering objects of this class into redis
* client command class (redis_command),
* all client commands automatically support cluster version redis commands.
* redis client cluster class. The class's object is set in the redis_command
* using redis_command::set_cluster(redis_cluster*), and all the redis client
* command will support the redis cluster mode.
*/
class ACL_CPP_API redis_client_cluster : public connect_manager {
public:
/**
* Constructor;
* constructor
* @param max_slot {int} Maximum hash slot value;
* the max hash-slot value of keys
*/
explicit redis_client_cluster(int max_slot = 16384);
~redis_client_cluster();
/**
* Get corresponding connection pool based on hash slot value;
* get one connection pool with the given slot
* @param slot {int} Hash slot value;
* the hash-slot value of key
* @return {redis_client_pool*} Returns NULL if corresponding hash slot does
* not exist;
* return the connection pool of the hash-slot, and return NULL
* when the slot not exists
*/
redis_client_pool* peek_slot(int slot);
/**
* Dynamically set redis service address corresponding to hash slot value. When
* this function is called, internally has thread lock protection;
* dynamicly set redis-server addr with one slot, which is protected
* by thread mutex internal, no one will be set if the slot were
* beyyond the max hash-slot
* @param slot {int} Hash slot value;
* the hash-slot
* @param addr {const char*} Redis server address;
* one redis-server addr
*/
void set_slot(int slot, const char* addr);
/**
* Given a node in redis cluster, automatically discover node addresses
* corresponding to all hash slots
* according one node of the cluster, auto find all nodes with all
* slots range
* @param addr {const char*} Address of a service node in cluster, format
* ip:port
* on server node's addr of the cluster, addr format is "ip:port"
* @param max_conns {size_t} Maximum connection limit for connection pool built
* with each node in cluster
* the max connections limit for each connection pool
* @param conn_timeout {int} Connection timeout
* set the connection timeout
* @param rw_timeout {int} IO read/write timeout
* set the network io timeout
*/
void set_all_slot(const char* addr, size_t max_conns,
int conn_timeout = 30, int rw_timeout = 30);
/**
* Dynamically clear redis service address corresponding to hash slot, to
* facilitate recalculating position.
* Internally has thread lock protection mechanism;
* dynamicly remove one slot and redis-server addr mapping, which is
* protected by thread mutex
* @param slot {int} Hash slot value;
* hash-slot value
*/
void clear_slot(int slot);
/**
* Get maximum hash slot value;
* get the max hash-slot
* @return {int}
*/
int get_max_slot() const {
return max_slot_;
}
//////////////////////////////////////////////////////////////////////
/**
* Set threshold for protocol redirect count. Default value is 15;
* set redirect limit for MOVE/ASK, default is 15
* @param max {int} Redirect count threshold. Only effective when this value >
* 0;
* the redirect times limit for MOVE/ASK commands
*/
void set_redirect_max(int max);
/**
* Set threshold for protocol redirect count;
* get redirect limit of MOVE/ASK commands in one redis redirect process
* @return {int}
*/
int get_redirect_max() const {
return redirect_max_;
}
/**
* Allowed sleep time (milliseconds) when redirect count >= 2. Default value is
* 100 milliseconds. Benefit of this is
* when a redis service master node goes offline, it takes time for other slave
* nodes to upgrade to master node (determined
* by cluster-node-timeout configuration item in redis.conf). So to avoid
* errors within redirect count range, need to wait
* for slave nodes to upgrade to master node;
* if redirect happenning more than 2 in one redis command process,
* the process can sleep for a one avoiding redirect too fast, you
* can set the waiting time with microsecond here, default value is
* 100 microseconds; this only happends when redis-server died.
* @param n {int} Rest time during each redirect (milliseconds), default value
* is 100 milliseconds;
* microseonds to sleep when redirect times are more than 2,
* default is 100 ms
*/
void set_redirect_sleep(int n);
/**
* Get time set by set_redirect_sleep or default time;
* get sleep time set by set_redirect_sleep function
* @return {int} Unit is milliseconds;
* return sleep value in microsecond
*/
int get_redirect_sleep() const {
return redirect_sleep_;
}
/**
* Set SSL communication configuration handle. Internal default value is NULL.
* If SSL connection
* configuration object is set, internally switches to SSL communication mode
* set SSL communication with Redis-server if ssl_conf not NULL
* @param ssl_conf {sslbase_conf*}
* @return {redis_client_cluster&}
*/
redis_client_cluster& set_ssl_conf(sslbase_conf* ssl_conf);
/**
* Set connection password for a redis service
* set the password of one redis-server
* @param addr {const char*} Address of a specified redis server. When value of
* this parameter is
* default, sets default connection password for all redis servers in cluster
* the specified redis-server's addr, the default password of all
* redis-server will be set when the addr's value is 'default'
* @param pass {const char*} Connection password of specified redis server
* the password of the specified redis-server
* @return {redis_client_cluster&}
*/
redis_client_cluster& set_password(const char* addr, const char* pass);
/**
* Get mapping table of service nodes and connection passwords in redis cluster
* get all passwords of the redis cluster
* @return {const std::map<string, string>&}
*/
const std::map<string, string>& get_passwords() const {
return passwds_;
}
/**
* Get connection password of redis node at given address. Returns NULL
* indicates not set
* get the connection password of the specified addr for one redis,
* NULL will be returned if password wasn't set
* @param addr {const char*}
* @return {const char*} return the specified node's connection password,
* NULL returned if no password been set
*/
const char* get_password(const char* addr) const;
/**
* Redirect to target redis node
* @param addr {const char*} Target redis service address
* @param max_conns {size_t} Maximum connection count in connection pool
* @return {redis_client*} Get connection communication object with target
* redis node
*/
redis_client* redirect(const char* addr, size_t max_conns);
/**
* Get connection object based on slot number of redis cluster
* @param slot {int} Storage slot number corresponding to redis cluster key
* value
* @return {redis_client*} Get connection communication object with target
* redis node
*/
redis_client* peek_conn(int slot);
protected:
/**
* Base class pure virtual function, used to create connection pool object.
* After this function returns, base class sets network connection and IO
* timeout
* virtual function of base class, which is used to create
* the connection pool
* @param addr {const char*} Server listening address, format: ip:port;
* the server addr for the connection pool, such as ip:port
* @param count {size_t} Size limit of connection pool. When this value is 0,
* there is no limit
* the max connections in one connection pool, if it's 0 there
* is no limit of the connections pool.
* @param idx {size_t} Index position of this connection pool object in
* collection (starts from 0);
* the index of the connection pool in pool array
*/
connect_pool* create_pool(const char* addr, size_t count, size_t idx);
private:
int max_slot_;
const char** slot_addrs_;
std::vector<char*> addrs_;
int redirect_max_;
int redirect_sleep_;
std::map<string, string> passwds_;
sslbase_conf* ssl_conf_;
redis_client* reopen(redis_command& cmd, redis_client* conn);
redis_client* move(redis_command& cd, redis_client* conn,
const char* ptr, int nretried);
redis_client* ask(redis_command& cd, redis_client* conn,
const char* ptr, int nretried);
redis_client* cluster_down(redis_command& cd, redis_client* conn,
const char* ptr, int nretried);
public:
const redis_result* run(redis_command& cmd, size_t nchild, int* timeout = NULL);
};
} // namespace acl
#endif // !defined(ACL_CLIENT_ONLY) && !defined(ACL_REDIS_DISABLE)