github.com/outbrain/consul@v1.4.5/website/source/docs/internals/coordinates.html.md (about) 1 --- 2 layout: "docs" 3 page_title: "Network Coordinates" 4 sidebar_current: "docs-internals-coordinates" 5 description: |- 6 Serf uses a network tomography system to compute network coordinates for nodes in the cluster. These coordinates are useful for easily calculating the estimated network round trip time between any two nodes in the cluster. This page documents the details of this system. The core of the network tomography system us based on Vivaldi: A Decentralized Network Coordinate System, with several improvements based on several follow-on papers. 7 --- 8 9 # Network Coordinates 10 11 Consul uses a [network tomography](https://en.wikipedia.org/wiki/Network_tomography) 12 system to compute network coordinates for nodes in the cluster. These coordinates 13 allow the network round trip time to be estimated between any two nodes using a 14 very simple calculation. This allows for many useful applications, such as finding 15 the service node nearest a requesting node, or failing over to services in the next 16 closest datacenter. 17 18 All of this is provided through the use of the [Serf library](https://www.serf.io/). 19 Serf's network tomography is based on ["Vivaldi: A Decentralized Network Coordinate System"](http://www.cs.ucsb.edu/~ravenben/classes/276/papers/vivaldi-sigcomm04.pdf), 20 with some enhancements based on other research. There are more details about 21 [Serf's network coordinates here](https://www.serf.io/docs/internals/coordinates.html). 22 23 ~> **Advanced Topic!** This page covers the technical details of 24 the internals of Consul. You don't need to know these details to effectively 25 operate and use Consul. These details are documented here for those who wish 26 to learn about them without having to go spelunking through the source code. 27 28 ## Network Coordinates in Consul 29 30 Network coordinates manifest in several ways inside Consul: 31 32 * The [`consul rtt`](/docs/commands/rtt.html) command can be used to query for the 33 network round trip time between any two nodes. 34 35 * The [Catalog endpoints](/api/catalog.html) and 36 [Health endpoints](/api/health.html) can sort the results of queries based 37 on the network round trip time from a given node using a "?near=" parameter. 38 39 * [Prepared queries](/api/query.html) can automatically fail over services 40 to other Consul datacenters based on network round trip times. See the 41 [Geo Failover](/docs/guides/geo-failover.html) for some examples. 42 43 * The [Coordinate endpoint](/api/coordinate.html) exposes raw network 44 coordinates for use in other applications. 45 46 Consul uses Serf to manage two different gossip pools, one for the LAN with members 47 of a given datacenter, and one for the WAN which is made up of just the Consul servers 48 in all datacenters. It's important to note that **network coordinates are not compatible 49 between these two pools**. LAN coordinates only make sense in calculations with other 50 LAN coordinates, and WAN coordinates only make sense with other WAN coordinates. 51 52 ## Working with Coordinates 53 54 Computing the estimated network round trip time between any two nodes is simple 55 once you have their coordinates. Here's a sample coordinate, as returned from the 56 [Coordinate endpoint](/api/coordinate.html). 57 58 ``` 59 "Coord": { 60 "Adjustment": 0.1, 61 "Error": 1.5, 62 "Height": 0.02, 63 "Vec": [0.34,0.68,0.003,0.01,0.05,0.1,0.34,0.06] 64 } 65 ``` 66 67 All values are floating point numbers in units of seconds, except for the error 68 term which isn't used for distance calculations. 69 70 Here's a complete example in Go showing how to compute the distance between two 71 coordinates: 72 73 ``` 74 import ( 75 "math" 76 "time" 77 78 "github.com/hashicorp/serf/coordinate" 79 ) 80 81 func dist(a *coordinate.Coordinate, b *coordinate.Coordinate) time.Duration { 82 // Coordinates will always have the same dimensionality, so this is 83 // just a sanity check. 84 if len(a.Vec) != len(b.Vec) { 85 panic("dimensions aren't compatible") 86 } 87 88 // Calculate the Euclidean distance plus the heights. 89 sumsq := 0.0 90 for i := 0; i < len(a.Vec); i++ { 91 diff := a.Vec[i] - b.Vec[i] 92 sumsq += diff * diff 93 } 94 rtt := math.Sqrt(sumsq) + a.Height + b.Height 95 96 // Apply the adjustment components, guarding against negatives. 97 adjusted := rtt + a.Adjustment + b.Adjustment 98 if adjusted > 0.0 { 99 rtt = adjusted 100 } 101 102 // Go's times are natively nanoseconds, so we convert from seconds. 103 const secondsToNanoseconds = 1.0e9 104 return time.Duration(rtt * secondsToNanoseconds) 105 } 106 ```