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-2016 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 seed hosts.
39  */
40 typedef struct as_seeds_s {
41  /**
42  * @private
43  * Reference count.
44  */
45  uint32_t ref_count;
46 
47  /*
48  * @private
49  * Length of seed array.
50  */
51  uint32_t size;
52 
53  /**
54  * @private
55  * Seed array.
56  */
57  as_host array[];
58 } as_seeds;
59 
60 /**
61  * @private
62  * Reference counted array of server node pointers.
63  */
64 typedef struct as_nodes_s {
65  /**
66  * @private
67  * Reference count of node array.
68  */
69  uint32_t ref_count;
70 
71  /**
72  * @private
73  * Length of node array.
74  */
75  uint32_t size;
76 
77  /**
78  * @private
79  * Server node array.
80  */
81  as_node* array[];
82 } as_nodes;
83 
84 /**
85  * @private
86  * Reference counted array of address maps.
87  */
88 typedef struct as_addr_maps_s {
89  /**
90  * @private
91  * Reference count.
92  */
93  uint32_t ref_count;
94 
95  /*
96  * @private
97  * Length of address map array.
98  */
99  uint32_t size;
100 
101  /**
102  * @private
103  * tAddress map array.
104  */
105  as_addr_map array[];
106 } as_addr_maps;
107 
108 /**
109  * @private
110  * Reference counted release function definition.
111  */
112 typedef void (*as_release_fn) (void* value);
113 
114 /**
115  * @private
116  * Reference counted data to be garbage collected.
117  */
118 typedef struct as_gc_item_s {
119  /**
120  * @private
121  * Reference counted data to be garbage collected.
122  */
123  void* data;
124 
125  /**
126  * @private
127  * Release function.
128  */
130 } as_gc_item;
131 
132 /**
133  * Cluster of server nodes.
134  */
135 typedef struct as_cluster_s {
136  /**
137  * @private
138  * Active nodes in cluster.
139  */
141 
142  /**
143  * @private
144  * Hints for best node for a partition.
145  */
147 
148  /**
149  * @private
150  * Nodes to be garbage collected.
151  */
152  as_vector* /* <as_gc_item> */ gc;
153 
154  /**
155  * @private
156  * Shared memory implementation of cluster.
157  */
158  struct as_shm_info_s* shm_info;
159 
160  /**
161  * @private
162  * User name in UTF-8 encoded bytes.
163  */
164  char* user;
165 
166  /**
167  * @private
168  * Password in hashed format in bytes.
169  */
170  char* password;
171 
172  /**
173  * @private
174  * Expected cluster name for all nodes. May be null.
175  */
177 
178  /**
179  * @private
180  * Initial seed nodes specified by user.
181  */
183 
184  /**
185  * @private
186  * A IP translation table is used in cases where different clients use different server
187  * IP addresses. This may be necessary when using clients from both inside and outside
188  * a local area network. Default is no translation.
189  *
190  * The key is the IP address returned from friend info requests to other servers. The
191  * value is the real IP address used to connect to the server.
192  */
194 
195  /**
196  * @private
197  * TLS parameters
198  */
200 
201  /**
202  * @private
203  * Pool of threads used to query server nodes in parallel for batch, scan and query.
204  */
206 
207  /**
208  * @private
209  * Cluster tend thread.
210  */
211  pthread_t tend_thread;
212 
213  /**
214  * @private
215  * Lock for the tend thread to wait on with the tend interval as timeout.
216  * Normally locked, resulting in waiting a full interval between
217  * tend iterations. Upon cluster shutdown, unlocked by the main
218  * thread, allowing a fast termination of the tend thread.
219  */
220  pthread_mutex_t tend_lock;
221 
222  /**
223  * @private
224  * Tend thread identifier to be used with tend_lock.
225  */
226  pthread_cond_t tend_cond;
227 
228  /**
229  * @private
230  * Configuration version. Incremented, when the configuration is changed.
231  */
232  uint32_t version;
233 
234  /**
235  * @private
236  * Milliseconds between cluster tends.
237  */
238  uint32_t tend_interval;
239 
240  /**
241  * @private
242  * Size of node's synchronous connection pool.
243  */
244  uint32_t conn_queue_size;
245 
246  /**
247  * @private
248  * Maximum number of asynchronous (non-pipeline) connections allowed for each node.
249  * Async transactions will be rejected if the maximum async node connections would be exceeded.
250  * This variable is ignored if asynchronous event loops are not created.
251  */
253 
254  /**
255  * @private
256  * Maximum number of pipeline connections allowed for each node.
257  * Pipeline transactions will be rejected if the maximum pipeline node connections would be exceeded.
258  * This variable is ignored if asynchronous event loops are not created.
259  */
261 
262  /**
263  * @private
264  * Number of pending async commands (i.e., commands with an outstanding reply).
265  */
266  uint32_t async_pending;
267 
268  /**
269  * @private
270  * Number of active async pipeline and non-pipeline connections combined.
271  */
273 
274  /**
275  * @private
276  * Number of async connections in the pools.
277  */
278  uint32_t async_conn_pool;
279 
280  /**
281  * @private
282  * Initial connection timeout in milliseconds.
283  */
284  uint32_t conn_timeout_ms;
285 
286  /**
287  * @private
288  * Maximum socket idle in seconds.
289  */
290  uint32_t max_socket_idle;
291 
292  /**
293  * @private
294  * Random node index.
295  */
296  uint32_t node_index;
297 
298  /**
299  * @private
300  * Total number of data partitions used by cluster.
301  */
302  uint16_t n_partitions;
303 
304  /**
305  * @private
306  * If "services-alternate" should be used instead of "services"
307  */
309 
310  /**
311  * @private
312  * Should continue to tend cluster.
313  */
314  volatile bool valid;
315 } as_cluster;
316 
317 /******************************************************************************
318  * FUNCTIONS
319  ******************************************************************************/
320 
321 /**
322  * Create and initialize cluster.
323  */
324 as_status
325 as_cluster_create(as_config* config, as_error* err, as_cluster** cluster);
326 
327 /**
328  * Close all connections and release memory associated with cluster.
329  */
330 void
332 
333 /**
334  * Is cluster connected to any server nodes.
335  */
336 bool
338 
339 /**
340  * Get all node names in cluster.
341  */
342 void
343 as_cluster_get_node_names(as_cluster* cluster, int* n_nodes, char** node_names);
344 
345 /**
346  * Reserve reference counted access to cluster nodes.
347  */
348 static inline as_nodes*
350 {
351  as_nodes* nodes = (as_nodes *)ck_pr_load_ptr(&cluster->nodes);
352  //ck_pr_fence_acquire();
353  ck_pr_inc_32(&nodes->ref_count);
354  return nodes;
355 }
356 
357 /**
358  * Release reference counted access to cluster nodes.
359  */
360 static inline void
362 {
363  //ck_pr_fence_release();
364 
365  bool destroy;
366  ck_pr_dec_32_zero(&nodes->ref_count, &destroy);
367 
368  if (destroy) {
369  cf_free(nodes);
370  }
371 }
372 
373 /**
374  * Add seeds to the cluster.
375  */
376 void
377 as_seeds_add(as_cluster* cluster, as_host* seed_list, uint32_t size);
378 
379 /**
380  * Replace the seeds of the cluster.
381  */
382 void
383 as_seeds_update(as_cluster* cluster, as_host* seed_list, uint32_t size);
384 
385 /**
386  * Reserve reference counted access to IP map.
387  */
388 static inline as_addr_maps*
390 {
391  as_addr_maps* ip_map = (as_addr_maps *)ck_pr_load_ptr(&cluster->ip_map);
392 
393  if (ip_map == NULL) {
394  return NULL;
395  }
396 
397  ck_pr_inc_32(&ip_map->ref_count);
398  return ip_map;
399 }
400 
401 /**
402  * Release reference counted access to IP map.
403  */
404 static inline void
406 {
407  bool destroy;
408  ck_pr_dec_32_zero(&ip_map->ref_count, &destroy);
409 
410  if (destroy) {
411  for (uint32_t i = 0; i < ip_map->size; i++) {
412  cf_free(ip_map->array[i].orig);
413  cf_free(ip_map->array[i].alt);
414  }
415 
416  cf_free(ip_map);
417  }
418 }
419 
420 /**
421  * Replace the IP address map of the cluster.
422  */
423 void
424 as_ip_map_update(as_cluster* cluster, as_addr_map* ip_map_list, uint32_t size);
425 
426 /**
427  * Change maximum async connections per node.
428  */
429 void
430 as_cluster_set_async_max_conns_per_node(as_cluster* cluster, uint32_t async_size, uint32_t pipe_size);
431 
432 /**
433  * @private
434  * Change user and password that is used to authenticate with cluster servers.
435  */
436 void
437 as_cluster_change_password(as_cluster* cluster, const char* user, const char* password);
438 
439 /**
440  * @private
441  * Get random node in the cluster.
442  * as_nodes_release() must be called when done with node.
443  */
444 as_node*
446 
447 /**
448  * @private
449  * Get node given node name.
450  * as_nodes_release() must be called when done with node.
451  */
452 as_node*
453 as_node_get_by_name(as_cluster* cluster, const char* name);
454 
455 /**
456  * @private
457  * Reserve reference counted access to partition tables.
458  * as_partition_tables_release() must be called when done with tables.
459  */
460 static inline as_partition_tables*
462 {
463  as_partition_tables* tables = (as_partition_tables *)ck_pr_load_ptr(&cluster->partition_tables);
464  ck_pr_inc_32(&tables->ref_count);
465  return tables;
466 }
467 
468 /**
469  * @private
470  * Release reference counted access to partition tables.
471  */
472 static inline void
474 {
475  bool destroy;
476  ck_pr_dec_32_zero(&tables->ref_count, &destroy);
477 
478  if (destroy) {
479  cf_free(tables);
480  }
481 }
482 
483 /**
484  * @private
485  * Get partition table given namespace.
486  */
487 static inline as_partition_table*
489 {
490  // Partition tables array size does not currently change after first cluster tend.
491  // Also, there is a one second delayed garbage collection coupled with as_partition_tables_get()
492  // being very fast. Reference counting the tables array is not currently necessary, but do it
493  // anyway in case the server starts supporting dynamic namespaces.
495  as_partition_table* table = as_partition_tables_get(tables, ns);
497  return table;
498 }
499 
500 /**
501  * @private
502  * Get mapped node given digest key and partition table. If there is no mapped node, a random
503  * node is used instead.
504  * as_nodes_release() must be called when done with node.
505  */
506 as_node*
507 as_partition_table_get_node(as_cluster* cluster, as_partition_table* table, const uint8_t* digest, as_policy_replica replica, bool master);
508 
509 /**
510  * @private
511  * Get shared memory mapped node given digest key. If there is no mapped node, a random node is used instead.
512  * as_nodes_release() must be called when done with node.
513  */
514 as_node*
515 as_shm_node_get(as_cluster* cluster, const char* ns, const uint8_t* digest, as_policy_replica replica, bool master);
516 
517 /**
518  * @private
519  * Get mapped node given digest key. If there is no mapped node, a random node is used instead.
520  * as_nodes_release() must be called when done with node.
521  */
522 static inline as_node*
523 as_node_get(as_cluster* cluster, const char* ns, const uint8_t* digest, as_policy_replica replica, bool master)
524 {
525 #ifdef AS_TEST_PROXY
526  return as_node_get_random(cluster);
527 #else
528  if (cluster->shm_info) {
529  return as_shm_node_get(cluster, ns, digest, replica, master);
530  }
531  else {
533  return as_partition_table_get_node(cluster, table, digest, replica, master);
534  }
535 #endif
536 }
537 
538 #ifdef __cplusplus
539 } // end extern "C"
540 #endif
as_thread_pool thread_pool
Definition: as_cluster.h:205
pthread_mutex_t tend_lock
Definition: as_cluster.h:220
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:69
as_namespace ns
Definition: as_scan.h:359
as_policy_replica
Definition: as_policy.h:270
uint32_t ref_count
Definition: as_cluster.h:45
as_nodes * nodes
Definition: as_cluster.h:140
as_addr_map array[]
Definition: as_cluster.h:105
as_status
Definition: as_status.h:30
static void as_partition_tables_release(as_partition_tables *tables)
Definition: as_cluster.h:473
void as_seeds_update(as_cluster *cluster, as_host *seed_list, uint32_t size)
as_addr_maps * ip_map
Definition: as_cluster.h:193
void(* as_release_fn)(void *value)
Definition: as_cluster.h:112
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:123
static as_partition_tables * as_partition_tables_reserve(as_cluster *cluster)
Definition: as_cluster.h:461
as_partition_tables * partition_tables
Definition: as_cluster.h:146
as_seeds * seeds
Definition: as_cluster.h:182
static void as_ip_map_release(as_addr_maps *ip_map)
Definition: as_cluster.h:405
uint32_t conn_queue_size
Definition: as_cluster.h:244
uint32_t conn_timeout_ms
Definition: as_cluster.h:284
char * password
Definition: as_cluster.h:170
as_release_fn release_fn
Definition: as_cluster.h:129
pthread_t tend_thread
Definition: as_cluster.h:211
void as_cluster_set_async_max_conns_per_node(as_cluster *cluster, uint32_t async_size, uint32_t pipe_size)
bool use_services_alternate
Definition: as_cluster.h:308
static as_addr_maps * as_ip_map_reserve(as_cluster *cluster)
Definition: as_cluster.h:389
uint32_t async_max_conns_per_node
Definition: as_cluster.h:252
uint32_t max_socket_idle
Definition: as_cluster.h:290
void as_cluster_get_node_names(as_cluster *cluster, int *n_nodes, char **node_names)
uint32_t async_conn_pool
Definition: as_cluster.h:278
char * user
Definition: as_cluster.h:164
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:523
uint32_t node_index
Definition: as_cluster.h:296
pthread_cond_t tend_cond
Definition: as_cluster.h:226
uint32_t tend_interval
Definition: as_cluster.h:238
char * cluster_name
Definition: as_cluster.h:176
uint32_t version
Definition: as_cluster.h:232
static as_partition_table * as_cluster_get_partition_table(as_cluster *cluster, const char *ns)
Definition: as_cluster.h:488
uint32_t size
Definition: as_cluster.h:75
uint16_t n_partitions
Definition: as_cluster.h:302
uint32_t pipe_max_conns_per_node
Definition: as_cluster.h:260
uint32_t size
Definition: as_cluster.h:51
struct as_shm_info_s * shm_info
Definition: as_cluster.h:158
uint32_t ref_count
Definition: as_cluster.h:93
uint32_t async_pending
Definition: as_cluster.h:266
volatile bool valid
Definition: as_cluster.h:314
uint32_t async_conn_count
Definition: as_cluster.h:272
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:152
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:349
bool as_cluster_is_connected(as_cluster *cluster)
void as_ip_map_update(as_cluster *cluster, as_addr_map *ip_map_list, uint32_t size)
as_node * as_shm_node_get(as_cluster *cluster, const char *ns, const uint8_t *digest, as_policy_replica replica, bool master)
void as_seeds_add(as_cluster *cluster, as_host *seed_list, uint32_t size)
char * alt
Definition: as_config.h:86
static void as_nodes_release(as_nodes *nodes)
Definition: as_cluster.h:361
uint32_t size
Definition: as_cluster.h:99
as_tls_context tls_ctx
Definition: as_cluster.h:199
char * orig
Definition: as_config.h:81
as_node * as_node_get_random(as_cluster *cluster)