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  ```