All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
as_cluster.h
Go to the documentation of this file.
1 /*
2  * Copyright 2008-2017 Aerospike, Inc.
3  *
4  * Portions may be licensed to Aerospike, Inc. under one or more contributor
5  * license agreements.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
8  * use this file except in compliance with the License. You may obtain a copy of
9  * the License at http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14  * License for the specific language governing permissions and limitations under
15  * the License.
16  */
17 #pragma once
18 
19 #include <aerospike/as_config.h>
20 #include <aerospike/as_node.h>
21 #include <aerospike/as_partition.h>
22 #include <aerospike/as_policy.h>
24 
25 #ifdef __cplusplus
26 extern "C" {
27 #endif
28 
29 // Concurrency kit needs to be under extern "C" when compiling C++.
30 #include <aerospike/ck/ck_pr.h>
31 
32 /******************************************************************************
33  * TYPES
34  *****************************************************************************/
35 
36 /**
37  * @private
38  * Reference counted array of server node pointers.
39  */
40 typedef struct as_nodes_s {
41  /**
42  * @private
43  * Reference count of node array.
44  */
45  uint32_t ref_count;
46 
47  /**
48  * @private
49  * Length of node array.
50  */
51  uint32_t size;
52 
53  /**
54  * @private
55  * Server node array.
56  */
57  as_node* array[];
58 } as_nodes;
59 
60 /**
61  * @private
62  * Reference counted release function definition.
63  */
64 typedef void (*as_release_fn) (void* value);
65 
66 /**
67  * @private
68  * Reference counted data to be garbage collected.
69  */
70 typedef struct as_gc_item_s {
71  /**
72  * @private
73  * Reference counted data to be garbage collected.
74  */
75  void* data;
76 
77  /**
78  * @private
79  * Release function.
80  */
82 } as_gc_item;
83 
84 /**
85  * Cluster of server nodes.
86  */
87 typedef struct as_cluster_s {
88  /**
89  * @private
90  * Active nodes in cluster.
91  */
93 
94  /**
95  * @private
96  * Hints for best node for a partition.
97  */
99 
100  /**
101  * @private
102  * Nodes to be garbage collected.
103  */
104  as_vector* /* <as_gc_item> */ gc;
105 
106  /**
107  * @private
108  * Shared memory implementation of cluster.
109  */
110  struct as_shm_info_s* shm_info;
111 
112  /**
113  * @private
114  * User name in UTF-8 encoded bytes.
115  */
116  char* user;
117 
118  /**
119  * @private
120  * Password in hashed format in bytes.
121  */
122  char* password;
123 
124  /**
125  * @private
126  * Expected cluster name for all nodes. May be null.
127  */
129 
130  /**
131  * Cluster event function that will be called when nodes are added/removed from the cluster.
132  */
134 
135  /**
136  * Cluster event user data that will be passed back to event_callback.
137  */
139 
140  /**
141  * @private
142  * Initial seed hosts specified by user.
143  */
144  as_vector* /* <as_host> */ seeds;
145 
146  /**
147  * @private
148  * A IP translation table is used in cases where different clients use different server
149  * IP addresses. This may be necessary when using clients from both inside and outside
150  * a local area network. Default is no translation.
151  *
152  * The key is the IP address returned from friend info requests to other servers. The
153  * value is the real IP address used to connect to the server.
154  */
155  as_vector* /* <as_addr_map> */ ip_map;
156 
157  /**
158  * @private
159  * TLS parameters
160  */
162 
163  /**
164  * @private
165  * Pool of threads used to query server nodes in parallel for batch, scan and query.
166  */
168 
169  /**
170  * @private
171  * Cluster tend thread.
172  */
173  pthread_t tend_thread;
174 
175  /**
176  * @private
177  * Lock for adding/removing seeds.
178  */
179  pthread_mutex_t seed_lock;
180 
181  /**
182  * @private
183  * Lock for the tend thread to wait on with the tend interval as timeout.
184  * Normally locked, resulting in waiting a full interval between
185  * tend iterations. Upon cluster shutdown, unlocked by the main
186  * thread, allowing a fast termination of the tend thread.
187  */
188  pthread_mutex_t tend_lock;
189 
190  /**
191  * @private
192  * Tend thread identifier to be used with tend_lock.
193  */
194  pthread_cond_t tend_cond;
195 
196  /**
197  * @private
198  * Milliseconds between cluster tends.
199  */
200  uint32_t tend_interval;
201 
202  /**
203  * @private
204  * Maximum number of synchronous connections allowed per server node.
205  */
207 
208  /**
209  * @private
210  * Maximum number of asynchronous (non-pipeline) connections allowed for each node.
211  * Async transactions will be rejected if the maximum async node connections would be exceeded.
212  * This variable is ignored if asynchronous event loops are not created.
213  */
215 
216  /**
217  * @private
218  * Maximum number of pipeline connections allowed for each node.
219  * Pipeline transactions will be rejected if the maximum pipeline node connections would be exceeded.
220  * This variable is ignored if asynchronous event loops are not created.
221  */
223 
224  /**
225  * @private
226  * Number of synchronous connection pools used for each node.
227  */
229 
230  /**
231  * @private
232  * Number of pending async commands (i.e., commands with an outstanding reply).
233  */
234  uint32_t async_pending;
235 
236  /**
237  * @private
238  * Number of active async pipeline and non-pipeline connections combined.
239  */
241 
242  /**
243  * @private
244  * Number of async connections in the pools.
245  */
246  uint32_t async_conn_pool;
247 
248  /**
249  * @private
250  * Initial connection timeout in milliseconds.
251  */
252  uint32_t conn_timeout_ms;
253 
254  /**
255  * @private
256  * Maximum socket idle in seconds.
257  */
258  uint32_t max_socket_idle;
259 
260  /**
261  * @private
262  * Random node index.
263  */
264  uint32_t node_index;
265 
266  /**
267  * @private
268  * Total number of data partitions used by cluster.
269  */
270  uint16_t n_partitions;
271 
272  /**
273  * @private
274  * If "services-alternate" should be used instead of "services"
275  */
277 
278  /**
279  * @private
280  * Should continue to tend cluster.
281  */
282  volatile bool valid;
283 } as_cluster;
284 
285 /******************************************************************************
286  * FUNCTIONS
287  ******************************************************************************/
288 
289 /**
290  * Create and initialize cluster.
291  */
292 as_status
293 as_cluster_create(as_config* config, as_error* err, as_cluster** cluster);
294 
295 /**
296  * Close all connections and release memory associated with cluster.
297  */
298 void
300 
301 /**
302  * Is cluster connected to any server nodes.
303  */
304 bool
306 
307 /**
308  * Get all node names in cluster.
309  */
310 void
311 as_cluster_get_node_names(as_cluster* cluster, int* n_nodes, char** node_names);
312 
313 /**
314  * Reserve reference counted access to cluster nodes.
315  */
316 static inline as_nodes*
318 {
319  as_nodes* nodes = (as_nodes *)ck_pr_load_ptr(&cluster->nodes);
320  //ck_pr_fence_acquire();
321  ck_pr_inc_32(&nodes->ref_count);
322  return nodes;
323 }
324 
325 /**
326  * Release reference counted access to cluster nodes.
327  */
328 static inline void
330 {
331  //ck_pr_fence_release();
332 
333  bool destroy;
334  ck_pr_dec_32_zero(&nodes->ref_count, &destroy);
335 
336  if (destroy) {
337  cf_free(nodes);
338  }
339 }
340 
341 /**
342  * Add seed to cluster.
343  */
344 void
345 as_cluster_add_seed(as_cluster* cluster, const char* hostname, const char* tls_name, uint16_t port);
346 
347 /**
348  * Remove seed from cluster.
349  */
350 void
351 as_cluster_remove_seed(as_cluster* cluster, const char* hostname, uint16_t port);
352 
353 /**
354  * @private
355  * Change user and password that is used to authenticate with cluster servers.
356  */
357 void
358 as_cluster_change_password(as_cluster* cluster, const char* user, const char* password);
359 
360 /**
361  * @private
362  * Get random node in the cluster.
363  * as_nodes_release() must be called when done with node.
364  */
365 as_node*
367 
368 /**
369  * @private
370  * Get node given node name.
371  * as_nodes_release() must be called when done with node.
372  */
373 as_node*
374 as_node_get_by_name(as_cluster* cluster, const char* name);
375 
376 /**
377  * @private
378  * Reserve reference counted access to partition tables.
379  * as_partition_tables_release() must be called when done with tables.
380  */
381 static inline as_partition_tables*
383 {
384  as_partition_tables* tables = (as_partition_tables *)ck_pr_load_ptr(&cluster->partition_tables);
385  ck_pr_inc_32(&tables->ref_count);
386  return tables;
387 }
388 
389 /**
390  * @private
391  * Release reference counted access to partition tables.
392  */
393 static inline void
395 {
396  bool destroy;
397  ck_pr_dec_32_zero(&tables->ref_count, &destroy);
398 
399  if (destroy) {
400  cf_free(tables);
401  }
402 }
403 
404 /**
405  * @private
406  * Get partition table given namespace.
407  */
408 static inline as_partition_table*
410 {
411  // Partition tables array size does not currently change after first cluster tend.
412  // Also, there is a one second delayed garbage collection coupled with as_partition_tables_get()
413  // being very fast. Reference counting the tables array is not currently necessary, but do it
414  // anyway in case the server starts supporting dynamic namespaces.
416  as_partition_table* table = as_partition_tables_get(tables, ns);
418  return table;
419 }
420 
421 /**
422  * @private
423  * Get mapped node given digest key and partition table. If there is no mapped node, a random
424  * node is used instead.
425  * as_nodes_release() must be called when done with node.
426  */
427 as_node*
428 as_partition_table_get_node(as_cluster* cluster, as_partition_table* table, const uint8_t* digest, as_policy_replica replica, bool master);
429 
430 /**
431  * @private
432  * Get shared memory mapped node given digest key. If there is no mapped node, a random node is used instead.
433  * as_nodes_release() must be called when done with node.
434  */
435 as_node*
436 as_shm_node_get(as_cluster* cluster, const char* ns, const uint8_t* digest, as_policy_replica replica, bool master);
437 
438 /**
439  * @private
440  * Get mapped node given digest key. If there is no mapped node, a random node is used instead.
441  * as_nodes_release() must be called when done with node.
442  */
443 static inline as_node*
444 as_node_get(as_cluster* cluster, const char* ns, const uint8_t* digest, as_policy_replica replica, bool master)
445 {
446 #ifdef AS_TEST_PROXY
447  return as_node_get_random(cluster);
448 #else
449  if (cluster->shm_info) {
450  return as_shm_node_get(cluster, ns, digest, replica, master);
451  }
452  else {
454  return as_partition_table_get_node(cluster, table, digest, replica, master);
455  }
456 #endif
457 }
458 
459 #ifdef __cplusplus
460 } // end extern "C"
461 #endif
as_thread_pool thread_pool
Definition: as_cluster.h:167
uint32_t conn_pools_per_node
Definition: as_cluster.h:228
pthread_mutex_t tend_lock
Definition: as_cluster.h:188
as_node * as_partition_table_get_node(as_cluster *cluster, as_partition_table *table, const uint8_t *digest, as_policy_replica replica, bool master)
uint32_t ref_count
Definition: as_cluster.h:45
as_namespace ns
Definition: as_scan.h:394
as_policy_replica
Definition: as_policy.h:270
as_nodes * nodes
Definition: as_cluster.h:92
as_status
Definition: as_status.h:30
static void as_partition_tables_release(as_partition_tables *tables)
Definition: as_cluster.h:394
void(* as_release_fn)(void *value)
Definition: as_cluster.h:64
void as_cluster_change_password(as_cluster *cluster, const char *user, const char *password)
as_status as_cluster_create(as_config *config, as_error *err, as_cluster **cluster)
void * data
Definition: as_cluster.h:75
static as_partition_tables * as_partition_tables_reserve(as_cluster *cluster)
Definition: as_cluster.h:382
as_partition_tables * partition_tables
Definition: as_cluster.h:98
uint32_t conn_timeout_ms
Definition: as_cluster.h:252
char * password
Definition: as_cluster.h:122
as_release_fn release_fn
Definition: as_cluster.h:81
pthread_t tend_thread
Definition: as_cluster.h:173
bool use_services_alternate
Definition: as_cluster.h:276
uint32_t async_max_conns_per_node
Definition: as_cluster.h:214
uint32_t max_socket_idle
Definition: as_cluster.h:258
as_vector * seeds
Definition: as_cluster.h:144
uint32_t max_conns_per_node
Definition: as_cluster.h:206
void as_cluster_get_node_names(as_cluster *cluster, int *n_nodes, char **node_names)
uint32_t async_conn_pool
Definition: as_cluster.h:246
void as_cluster_remove_seed(as_cluster *cluster, const char *hostname, uint16_t port)
char * user
Definition: as_cluster.h:116
as_vector * ip_map
Definition: as_cluster.h:155
static as_node * as_node_get(as_cluster *cluster, const char *ns, const uint8_t *digest, as_policy_replica replica, bool master)
Definition: as_cluster.h:444
as_cluster_event_callback event_callback
Definition: as_cluster.h:133
uint32_t node_index
Definition: as_cluster.h:264
pthread_cond_t tend_cond
Definition: as_cluster.h:194
uint32_t tend_interval
Definition: as_cluster.h:200
char * cluster_name
Definition: as_cluster.h:128
static as_partition_table * as_cluster_get_partition_table(as_cluster *cluster, const char *ns)
Definition: as_cluster.h:409
uint32_t size
Definition: as_cluster.h:51
uint16_t n_partitions
Definition: as_cluster.h:270
uint32_t pipe_max_conns_per_node
Definition: as_cluster.h:222
struct as_shm_info_s * shm_info
Definition: as_cluster.h:110
void(* as_cluster_event_callback)(as_cluster_event *event)
Definition: as_config.h:146
pthread_mutex_t seed_lock
Definition: as_cluster.h:179
void as_cluster_add_seed(as_cluster *cluster, const char *hostname, const char *tls_name, uint16_t port)
uint32_t async_pending
Definition: as_cluster.h:234
volatile bool valid
Definition: as_cluster.h:282
uint32_t async_conn_count
Definition: as_cluster.h:240
void as_cluster_destroy(as_cluster *cluster)
as_node * as_node_get_by_name(as_cluster *cluster, const char *name)
as_vector * gc
Definition: as_cluster.h:104
as_partition_table * as_partition_tables_get(as_partition_tables *tables, const char *ns)
static as_nodes * as_nodes_reserve(as_cluster *cluster)
Definition: as_cluster.h:317
bool as_cluster_is_connected(as_cluster *cluster)
as_node * as_shm_node_get(as_cluster *cluster, const char *ns, const uint8_t *digest, as_policy_replica replica, bool master)
void * event_callback_udata
Definition: as_cluster.h:138
static void as_nodes_release(as_nodes *nodes)
Definition: as_cluster.h:329
as_tls_context tls_ctx
Definition: as_cluster.h:161
as_node * as_node_get_random(as_cluster *cluster)