You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
338 lines
10 KiB
338 lines
10 KiB
'\" t
|
|
.\" Title: zgossip
|
|
.\" Author: [see the "AUTHORS" section]
|
|
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
|
|
.\" Date: 12/31/2016
|
|
.\" Manual: CZMQ Manual
|
|
.\" Source: CZMQ 4.0.2
|
|
.\" Language: English
|
|
.\"
|
|
.TH "ZGOSSIP" "3" "12/31/2016" "CZMQ 4\&.0\&.2" "CZMQ Manual"
|
|
.\" -----------------------------------------------------------------
|
|
.\" * Define some portability stuff
|
|
.\" -----------------------------------------------------------------
|
|
.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
.\" http://bugs.debian.org/507673
|
|
.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
|
|
.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
.ie \n(.g .ds Aq \(aq
|
|
.el .ds Aq '
|
|
.\" -----------------------------------------------------------------
|
|
.\" * set default formatting
|
|
.\" -----------------------------------------------------------------
|
|
.\" disable hyphenation
|
|
.nh
|
|
.\" disable justification (adjust text to left margin only)
|
|
.ad l
|
|
.\" -----------------------------------------------------------------
|
|
.\" * MAIN CONTENT STARTS HERE *
|
|
.\" -----------------------------------------------------------------
|
|
.SH "NAME"
|
|
zgossip \- decentralized configuration management
|
|
.SH "SYNOPSIS"
|
|
.sp
|
|
.nf
|
|
// To work with zgossip, use the CZMQ zactor API:
|
|
//
|
|
// Create new zgossip instance, passing logging prefix:
|
|
//
|
|
// zactor_t *zgossip = zactor_new (zgossip, "myname");
|
|
//
|
|
// Destroy zgossip instance
|
|
//
|
|
// zactor_destroy (&zgossip);
|
|
//
|
|
// Enable verbose logging of commands and activity:
|
|
//
|
|
// zstr_send (zgossip, "VERBOSE");
|
|
//
|
|
// Bind zgossip to specified endpoint\&. TCP endpoints may specify
|
|
// the port number as "*" to aquire an ephemeral port:
|
|
//
|
|
// zstr_sendx (zgossip, "BIND", endpoint, NULL);
|
|
//
|
|
// Return assigned port number, specifically when BIND was done using an
|
|
// an ephemeral port:
|
|
//
|
|
// zstr_sendx (zgossip, "PORT", NULL);
|
|
// char *command, *port_str;
|
|
// zstr_recvx (zgossip, &command, &port_str, NULL);
|
|
// assert (streq (command, "PORT"));
|
|
//
|
|
// Specify configuration file to load, overwriting any previous loaded
|
|
// configuration file or options:
|
|
//
|
|
// zstr_sendx (zgossip, "LOAD", filename, NULL);
|
|
//
|
|
// Set configuration path value:
|
|
//
|
|
// zstr_sendx (zgossip, "SET", path, value, NULL);
|
|
//
|
|
// Save configuration data to config file on disk:
|
|
//
|
|
// zstr_sendx (zgossip, "SAVE", filename, NULL);
|
|
//
|
|
// Send zmsg_t instance to zgossip:
|
|
//
|
|
// zactor_send (zgossip, &msg);
|
|
//
|
|
// Receive zmsg_t instance from zgossip:
|
|
//
|
|
// zmsg_t *msg = zactor_recv (zgossip);
|
|
//
|
|
// This is the zgossip constructor as a zactor_fn:
|
|
//
|
|
CZMQ_EXPORT void
|
|
zgossip (zsock_t *pipe, void *args);
|
|
|
|
// Self test of this class
|
|
CZMQ_EXPORT void
|
|
zgossip_test (bool verbose);
|
|
Please add \*(Aq@interface\*(Aq section in \*(Aq\&./\&.\&./src/zgossip\&.c\*(Aq\&.
|
|
.fi
|
|
.SH "DESCRIPTION"
|
|
.sp
|
|
Implements a gossip protocol for decentralized configuration management\&. Your applications nodes form a loosely connected network (which can have cycles), and publish name/value tuples\&. Each node re\-distributes the new tuples it receives, so that the entire network eventually achieves a consistent state\&. The current design does not expire tuples\&.
|
|
.sp
|
|
Provides these commands (sent as multipart strings to the actor):
|
|
.sp
|
|
.RS 4
|
|
.ie n \{\
|
|
\h'-04'\(bu\h'+03'\c
|
|
.\}
|
|
.el \{\
|
|
.sp -1
|
|
.IP \(bu 2.3
|
|
.\}
|
|
BIND endpoint \(em binds the gossip service to specified endpoint
|
|
.RE
|
|
.sp
|
|
.RS 4
|
|
.ie n \{\
|
|
\h'-04'\(bu\h'+03'\c
|
|
.\}
|
|
.el \{\
|
|
.sp -1
|
|
.IP \(bu 2.3
|
|
.\}
|
|
PORT \(em returns the last TCP port, if any, used for binding
|
|
.RE
|
|
.sp
|
|
.RS 4
|
|
.ie n \{\
|
|
\h'-04'\(bu\h'+03'\c
|
|
.\}
|
|
.el \{\
|
|
.sp -1
|
|
.IP \(bu 2.3
|
|
.\}
|
|
LOAD configfile \(em load configuration from specified file
|
|
.RE
|
|
.sp
|
|
.RS 4
|
|
.ie n \{\
|
|
\h'-04'\(bu\h'+03'\c
|
|
.\}
|
|
.el \{\
|
|
.sp -1
|
|
.IP \(bu 2.3
|
|
.\}
|
|
SET configpath value \(em set configuration path = value
|
|
.RE
|
|
.sp
|
|
.RS 4
|
|
.ie n \{\
|
|
\h'-04'\(bu\h'+03'\c
|
|
.\}
|
|
.el \{\
|
|
.sp -1
|
|
.IP \(bu 2.3
|
|
.\}
|
|
SAVE configfile \(em save configuration to specified file
|
|
.RE
|
|
.sp
|
|
.RS 4
|
|
.ie n \{\
|
|
\h'-04'\(bu\h'+03'\c
|
|
.\}
|
|
.el \{\
|
|
.sp -1
|
|
.IP \(bu 2.3
|
|
.\}
|
|
CONNECT endpoint \(em connect the gossip service to the specified peer
|
|
.RE
|
|
.sp
|
|
.RS 4
|
|
.ie n \{\
|
|
\h'-04'\(bu\h'+03'\c
|
|
.\}
|
|
.el \{\
|
|
.sp -1
|
|
.IP \(bu 2.3
|
|
.\}
|
|
PUBLISH key value \(em publish a key/value pair to the gossip cluster
|
|
.RE
|
|
.sp
|
|
.RS 4
|
|
.ie n \{\
|
|
\h'-04'\(bu\h'+03'\c
|
|
.\}
|
|
.el \{\
|
|
.sp -1
|
|
.IP \(bu 2.3
|
|
.\}
|
|
STATUS \(em return number of key/value pairs held by gossip service
|
|
.RE
|
|
.sp
|
|
Returns these messages:
|
|
.sp
|
|
.RS 4
|
|
.ie n \{\
|
|
\h'-04'\(bu\h'+03'\c
|
|
.\}
|
|
.el \{\
|
|
.sp -1
|
|
.IP \(bu 2.3
|
|
.\}
|
|
PORT number \(em reply to PORT command
|
|
.RE
|
|
.sp
|
|
.RS 4
|
|
.ie n \{\
|
|
\h'-04'\(bu\h'+03'\c
|
|
.\}
|
|
.el \{\
|
|
.sp -1
|
|
.IP \(bu 2.3
|
|
.\}
|
|
STATUS number \(em reply to STATUS command
|
|
.RE
|
|
.sp
|
|
.RS 4
|
|
.ie n \{\
|
|
\h'-04'\(bu\h'+03'\c
|
|
.\}
|
|
.el \{\
|
|
.sp -1
|
|
.IP \(bu 2.3
|
|
.\}
|
|
DELIVER key value \(em new tuple delivered from network
|
|
.RE
|
|
.sp
|
|
The gossip protocol distributes information around a loosely\-connected network of gossip services\&. The information consists of name/value pairs published by applications at any point in the network\&. The goal of the gossip protocol is to create eventual consistency between all the using applications\&.
|
|
.sp
|
|
The name/value pairs (tuples) can be used for configuration data, for status updates, for presence, or for discovery\&. When used for discovery, the gossip protocol works as an alternative to e\&.g\&. UDP beaconing\&.
|
|
.sp
|
|
The gossip network consists of a set of loosely\-coupled nodes that exchange tuples\&. Nodes can be connected across arbitrary transports, so the gossip network can have nodes that communicate over inproc, over IPC, and/or over TCP, at the same time\&.
|
|
.sp
|
|
Each node runs the same stack, which is a server\-client hybrid using a modified Harmony pattern (from Chapter 8 of the Guide): \m[blue]\fBhttp://zguide\&.zeromq\&.org/page:all#True\-Peer\-Connectivity\-Harmony\-Pattern\fR\m[]
|
|
.sp
|
|
Each node provides a ROUTER socket that accepts client connections on an key defined by the application via a BIND command\&. The state machine for these connections is in zgossip\&.xml, and the generated code is in zgossip_engine\&.inc\&.
|
|
.sp
|
|
Each node additionally creates outbound connections via DEALER sockets to a set of servers ("remotes"), and under control of the calling app, which sends CONNECT commands for each configured remote\&.
|
|
.sp
|
|
The messages between client and server are defined in zgossip_msg\&.xml\&. We built this stack using the zeromq/zproto toolkit\&.
|
|
.sp
|
|
To join the gossip network, a node connects to one or more peers\&. Each peer acts as a forwarder\&. This loosely\-coupled network can scale to thousands of nodes\&. However the gossip protocol is NOT designed to be efficient, and should not be used for application data, as the same tuples may be sent many times across the network\&.
|
|
.sp
|
|
The basic logic of the gossip service is to accept PUBLISH messages from its owning application, and to forward these to every remote, and every client it talks to\&. When a node gets a duplicate tuple, it throws it away\&. When a node gets a new tuple, it stores it, and fowards it as just described\&. At any point the application can access the node\(cqs set of tuples\&.
|
|
.sp
|
|
At present there is no way to expire tuples from the network\&.
|
|
.sp
|
|
The assumptions in this design are:
|
|
.sp
|
|
.RS 4
|
|
.ie n \{\
|
|
\h'-04'\(bu\h'+03'\c
|
|
.\}
|
|
.el \{\
|
|
.sp -1
|
|
.IP \(bu 2.3
|
|
.\}
|
|
The data set is slow\-changing\&. Thus, the cost of the gossip protocol is irrelevant with respect to other traffic\&.
|
|
.RE
|
|
.SH "EXAMPLE"
|
|
.PP
|
|
\fBFrom zgossip_test method\fR.
|
|
.sp
|
|
.if n \{\
|
|
.RS 4
|
|
.\}
|
|
.nf
|
|
// Test basic client\-to\-server operation of the protocol
|
|
zactor_t *server = zactor_new (zgossip, "server");
|
|
assert (server);
|
|
if (verbose)
|
|
zstr_send (server, "VERBOSE");
|
|
zstr_sendx (server, "BIND", "inproc://zgossip", NULL);
|
|
|
|
zsock_t *client = zsock_new (ZMQ_DEALER);
|
|
assert (client);
|
|
zsock_set_rcvtimeo (client, 2000);
|
|
int rc = zsock_connect (client, "inproc://zgossip");
|
|
assert (rc == 0);
|
|
|
|
// Send HELLO, which gets no message
|
|
zgossip_msg_t *message = zgossip_msg_new ();
|
|
zgossip_msg_set_id (message, ZGOSSIP_MSG_HELLO);
|
|
zgossip_msg_send (message, client);
|
|
|
|
// Send PING, expect PONG back
|
|
zgossip_msg_set_id (message, ZGOSSIP_MSG_PING);
|
|
zgossip_msg_send (message, client);
|
|
zgossip_msg_recv (message, client);
|
|
assert (zgossip_msg_id (message) == ZGOSSIP_MSG_PONG);
|
|
zgossip_msg_destroy (&message);
|
|
|
|
zactor_destroy (&server);
|
|
zsock_destroy (&client);
|
|
|
|
// Test peer\-to\-peer operations
|
|
zactor_t *base = zactor_new (zgossip, "base");
|
|
assert (base);
|
|
if (verbose)
|
|
zstr_send (base, "VERBOSE");
|
|
// Set a 100msec timeout on clients so we can test expiry
|
|
zstr_sendx (base, "SET", "server/timeout", "100", NULL);
|
|
zstr_sendx (base, "BIND", "inproc://base", NULL);
|
|
|
|
zactor_t *alpha = zactor_new (zgossip, "alpha");
|
|
assert (alpha);
|
|
zstr_sendx (alpha, "CONNECT", "inproc://base", NULL);
|
|
zstr_sendx (alpha, "PUBLISH", "inproc://alpha\-1", "service1", NULL);
|
|
zstr_sendx (alpha, "PUBLISH", "inproc://alpha\-2", "service2", NULL);
|
|
|
|
zactor_t *beta = zactor_new (zgossip, "beta");
|
|
assert (beta);
|
|
zstr_sendx (beta, "CONNECT", "inproc://base", NULL);
|
|
zstr_sendx (beta, "PUBLISH", "inproc://beta\-1", "service1", NULL);
|
|
zstr_sendx (beta, "PUBLISH", "inproc://beta\-2", "service2", NULL);
|
|
|
|
// got nothing
|
|
zclock_sleep (200);
|
|
|
|
zactor_destroy (&base);
|
|
zactor_destroy (&alpha);
|
|
zactor_destroy (&beta);
|
|
.fi
|
|
.if n \{\
|
|
.RE
|
|
.\}
|
|
.sp
|
|
.SH "AUTHORS"
|
|
.sp
|
|
The czmq manual was written by the authors in the AUTHORS file\&.
|
|
.SH "RESOURCES"
|
|
.sp
|
|
Main web site: \m[blue]\fB\%\fR\m[]
|
|
.sp
|
|
Report bugs to the email <\m[blue]\fBzeromq\-dev@lists\&.zeromq\&.org\fR\m[]\&\s-2\u[1]\d\s+2>
|
|
.SH "COPYRIGHT"
|
|
.sp
|
|
Copyright (c) the Contributors as noted in the AUTHORS file\&. This file is part of CZMQ, the high\-level C binding for 0MQ: http://czmq\&.zeromq\&.org\&. This Source Code Form is subject to the terms of the Mozilla Public License, v\&. 2\&.0\&. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla\&.org/MPL/2\&.0/\&. LICENSE included with the czmq distribution\&.
|
|
.SH "NOTES"
|
|
.IP " 1." 4
|
|
zeromq-dev@lists.zeromq.org
|
|
.RS 4
|
|
\%mailto:zeromq-dev@lists.zeromq.org
|
|
.RE
|
|
|