Revert "Doc: /_reindex: Add a note about the source size parameter"

This reverts commit 4de284866875b987110df66229fb7c7d0b9cd4d8.

[[docs-reindex]]
== Reindex API

experimental[The reindex API is new and should still be considered experimental.  The API may change in ways that are not backwards compatible]

The most basic form of `_reindex` just copies documents from one index to another.
This will copy documents from the `twitter` index into the `new_twitter` index:

[source,js]
--------------------------------------------------
POST _reindex
{
  "source": {
    "index": "twitter"
  },
  "dest": {
    "index": "new_twitter"
  }
}
--------------------------------------------------
// CONSOLE
// TEST[setup:big_twitter]

That will return something like this:

[source,js]
--------------------------------------------------
{
  "took" : 147,
  "timed_out": false,
  "created": 120,
  "updated": 0,
  "batches": 1,
  "version_conflicts": 0,
  "noops": 0,
  "retries": {
    "bulk": 0,
    "search": 0
  },
  "throttled_millis": 0,
  "requests_per_second": "unlimited",
  "throttled_until_millis": 0,
  "total": 120,
  "failures" : [ ]
}
--------------------------------------------------
// TESTRESPONSE[s/"took" : 147/"took" : "$body.took"/]

Just like <<docs-update-by-query,`_update_by_query`>>, `_reindex` gets a
snapshot of the source index but its target must be a **different** index so
version conflicts are unlikely. The `dest` element can be configured like the
index API to control optimistic concurrency control. Just leaving out
`version_type` (as above) or setting it to `internal` will cause Elasticsearch
to blindly dump documents into the target, overwriting any that happen to have
the same type and id:

[source,js]
--------------------------------------------------
POST _reindex
{
  "source": {
    "index": "twitter"
  },
  "dest": {
    "index": "new_twitter",
    "version_type": "internal"
  }
}
--------------------------------------------------
// CONSOLE
// TEST[setup:twitter]

Setting `version_type` to `external` will cause Elasticsearch to preserve the
`version` from the source, create any documents that are missing, and update
any documents that have an older version in the destination index than they do
in the source index:

[source,js]
--------------------------------------------------
POST _reindex
{
  "source": {
    "index": "twitter"
  },
  "dest": {
    "index": "new_twitter",
    "version_type": "external"
  }
}
--------------------------------------------------
// CONSOLE
// TEST[setup:twitter]

Settings `op_type` to `create` will cause `_reindex` to only create missing
documents in the target index. All existing documents will cause a version
conflict:

[source,js]
--------------------------------------------------
POST _reindex
{
  "source": {
    "index": "twitter"
  },
  "dest": {
    "index": "new_twitter",
    "op_type": "create"
  }
}
--------------------------------------------------
// CONSOLE
// TEST[setup:twitter]

By default version conflicts abort the `_reindex` process but you can just
count them by settings `"conflicts": "proceed"` in the request body:

[source,js]
--------------------------------------------------
POST _reindex
{
  "conflicts": "proceed",
  "source": {
    "index": "twitter"
  },
  "dest": {
    "index": "new_twitter",
    "op_type": "create"
  }
}
--------------------------------------------------
// CONSOLE
// TEST[setup:twitter]

You can limit the documents by adding a type to the `source` or by adding a
query. This will only copy ++tweet++'s made by `kimchy` into `new_twitter`:

[source,js]
--------------------------------------------------
POST _reindex
{
  "source": {
    "index": "twitter",
    "type": "tweet",
    "query": {
      "term": {
        "user": "kimchy"
      }
    }
  },
  "dest": {
    "index": "new_twitter"
  }
}
--------------------------------------------------
// CONSOLE
// TEST[setup:twitter]

`index` and `type` in `source` can both be lists, allowing you to copy from
lots of sources in one request. This will copy documents from the `tweet` and
`post` types in the `twitter` and `blog` index. It'd include the `post` type in
the `twitter` index and the `tweet` type in the `blog` index. If you want to be
more specific you'll need to use the `query`. It also makes no effort to handle
ID collisions. The target index will remain valid but it's not easy to predict
which document will survive because the iteration order isn't well defined.

[source,js]
--------------------------------------------------
POST _reindex
{
  "source": {
    "index": ["twitter", "blog"],
    "type": ["tweet", "post"]
  },
  "dest": {
    "index": "all_together"
  }
}
--------------------------------------------------
// CONSOLE
// TEST[s/^/PUT twitter\nPUT blog\nGET _cluster\/health?wait_for_status=yellow\n/]

It's also possible to limit the number of processed documents by setting
`size`. This will only copy a single document from `twitter` to
`new_twitter`:

[source,js]
--------------------------------------------------
POST _reindex
{
  "size": 1,
  "source": {
    "index": "twitter"
  },
  "dest": {
    "index": "new_twitter"
  }
}
--------------------------------------------------
// CONSOLE
// TEST[setup:twitter]

If you want a particular set of documents from the twitter index you'll
need to sort. Sorting makes the scroll less efficient but in some contexts
it's worth it. If possible, prefer a more selective query to `size` and `sort`.
This will copy 10000 documents from `twitter` into `new_twitter`:

[source,js]
--------------------------------------------------
POST _reindex
{
  "size": 10000,
  "source": {
    "index": "twitter",
    "sort": { "date": "desc" }
  },
  "dest": {
    "index": "new_twitter"
  }
}
--------------------------------------------------
// CONSOLE
// TEST[setup:twitter]

Like `_update_by_query`, `_reindex` supports a script that modifies the
document. Unlike `_update_by_query`, the script is allowed to modify the
document's metadata. This example bumps the version of the source document:

[source,js]
--------------------------------------------------
POST _reindex
{
  "source": {
    "index": "twitter"
  },
  "dest": {
    "index": "new_twitter",
    "version_type": "external"
  },
  "script": {
    "script": "if (ctx._source.foo == 'bar') {ctx._version++; ctx._source.remove('foo')}"
  }
}
--------------------------------------------------
// CONSOLE
// TEST[setup:twitter]

Think of the possibilities! Just be careful! With great power.... You can
change:

 * `_id`
 * `_type`
 * `_index`
 * `_version`
 * `_routing`
 * `_parent`
 * `_timestamp`
 * `_ttl`

Setting `_version` to `null` or clearing it from the `ctx` map is just like not
sending the version in an indexing request. It will cause that document to be
overwritten in the target index regardless of the version on the target or the
version type you use in the `_reindex` request.

By default if `_reindex` sees a document with routing then the routing is
preserved unless it's changed by the script. You can set `routing` on the
`dest` request to change this:

`keep`::

Sets the routing on the bulk request sent for each match to the routing on
the match. The default.

`discard`::

Sets the routing on the bulk request sent for each match to null.

`=<some text>`::

Sets the routing on the bulk request sent for each match to all text after
the `=`.

For example, you can use the following request to copy all documents from
the `source` index with the company name `cat` into the `dest` index with
routing set to `cat`.

[source,js]
--------------------------------------------------
POST _reindex
{
  "source": {
    "index": "source",
    "query": {
      "match": {
        "company": "cat"
      }
    }
  },
  "dest": {
    "index": "dest",
    "routing": "=cat"
  }
}
--------------------------------------------------
// CONSOLE
// TEST[s/^/PUT source\nGET _cluster\/health?wait_for_status=yellow\n/]

By default `_reindex` uses scroll batches of 1000. You can change the
batch size with the `size` field in the `source` element:

[source,js]
--------------------------------------------------
POST _reindex
{
  "source": {
    "index": "source",
    "size": 100
  },
  "dest": {
    "index": "dest",
    "routing": "=cat"
  }
}
--------------------------------------------------
// CONSOLE
// TEST[s/^/PUT source\nGET _cluster\/health?wait_for_status=yellow\n/]

Reindex can also use the <<ingest>> feature by specifying a
`pipeline` like this:

[source,js]
--------------------------------------------------
POST _reindex
{
  "source": {
    "index": "source"
  },
  "dest": {
    "index": "dest",
    "pipeline": "some_ingest_pipeline"
  }
}
--------------------------------------------------
// CONSOLE
// TEST[s/^/PUT source\nGET _cluster\/health?wait_for_status=yellow\n/]

[float]
=== URL Parameters

In addition to the standard parameters like `pretty`, the Reindex API also
supports `refresh`, `wait_for_completion`, `consistency`, `timeout`, and
`requests_per_second`.

Sending the `refresh` url parameter will cause all indexes to which the request
wrote to be refreshed. This is different than the Index API's `refresh`
parameter which causes just the shard that received the new data to be indexed.

If the request contains `wait_for_completion=false` then Elasticsearch will
perform some preflight checks, launch the request, and then return a `task`
which can be used with <<docs-reindex-task-api,Tasks APIs>> to cancel or get
the status of the task. For now, once the request is finished the task is gone
and the only place to look for the ultimate result of the task is in the
Elasticsearch log file. This will be fixed soon.

`consistency` controls how many copies of a shard must respond to each write
request. `timeout` controls how long each write request waits for unavailable
shards to become available. Both work exactly how they work in the
<<docs-bulk,Bulk API>>.

`requests_per_second` can be set to any decimal number (`1.4`, `6`, `1000`, etc)
and throttles the number of requests per second that the reindex issues. The
throttling is done waiting between bulk batches so that it can manipulate the
scroll timeout. The wait time is the difference between the time it took the
batch to complete and the time `requests_per_second * requests_in_the_batch`.
Since the batch isn't broken into multiple bulk requests large batch sizes will
cause Elasticsearch to create many requests and then wait for a while before
starting the next set. This is "bursty" instead of "smooth". The default is
`unlimited` which is also the only non-number value that it accepts.

[float]
=== Response body

The JSON response looks like this:

[source,js]
--------------------------------------------------
{
  "took" : 639,
  "updated": 0,
  "created": 123,
  "batches": 1,
  "version_conflicts": 2,
  "retries": {
    "bulk": 0,
    "search": 0
  }
  "throttled_millis": 0,
  "failures" : [ ]
}
--------------------------------------------------

`took`::

The number of milliseconds from start to end of the whole operation.

`updated`::

The number of documents that were successfully updated.

`created`::

The number of documents that were successfully created.

`batches`::

The number of scroll responses pulled back by the the reindex.

`version_conflicts`::

The number of version conflicts that reindex hit.

`retries`::

The number of retries attempted by reindex. `bulk` is the number of bulk
actions retried and `search` is the number of search actions retried.

`throttled_millis`::

Number of milliseconds the request slept to conform to `requests_per_second`.

`failures`::

Array of all indexing failures. If this is non-empty then the request aborted
because of those failures. See `conflicts` for how to prevent version conflicts
from aborting the operation.

[float]
[[docs-reindex-task-api]]
=== Works with the Task API

While Reindex is running you can fetch their status using the
<<tasks,Task API>>:

[source,js]
--------------------------------------------------
GET _tasks?detailed=true&actions=*reindex
--------------------------------------------------
// CONSOLE

The responses looks like:

[source,js]
--------------------------------------------------
{
  "nodes" : {
    "r1A2WoRbTwKZ516z6NEs5A" : {
      "name" : "Tyrannus",
      "transport_address" : "127.0.0.1:9300",
      "host" : "127.0.0.1",
      "ip" : "127.0.0.1:9300",
      "attributes" : {
        "testattr" : "test",
        "portsfile" : "true"
      },
      "tasks" : {
        "r1A2WoRbTwKZ516z6NEs5A:36619" : {
          "node" : "r1A2WoRbTwKZ516z6NEs5A",
          "id" : 36619,
          "type" : "transport",
          "action" : "indices:data/write/reindex",
          "status" : {    <1>
            "total" : 6154,
            "updated" : 3500,
            "created" : 0,
            "deleted" : 0,
            "batches" : 4,
            "version_conflicts" : 0,
            "noops" : 0,
            "retries": {
              "bulk": 0,
              "search": 0
            },
            "throttled_millis": 0
          },
          "description" : ""
        }
      }
    }
  }
}
--------------------------------------------------

<1> this object contains the actual status. It is just like the response json
with the important addition of the `total` field. `total` is the total number
of operations that the reindex expects to perform. You can estimate the
progress by adding the `updated`, `created`, and `deleted` fields. The request
will finish when their sum is equal to the `total` field.

[float]
[[docs-reindex-cancel-task-api]]
=== Works with the Cancel Task API

Any Reindex can be canceled using the <<tasks,Task Cancel API>>:

[source,js]
--------------------------------------------------
POST _tasks/taskid:1/_cancel
--------------------------------------------------
// CONSOLE

The `task_id` can be found using the tasks API above.

Cancelation should happen quickly but might take a few seconds. The task status
API above will continue to list the task until it is wakes to cancel itself.

[float]
[[docs-reindex-rethrottle]]
=== Rethrottling

The value of `requests_per_second` can be changed on a running reindex using
the `_rethrottle` API:

[source,js]
--------------------------------------------------
POST _reindex/taskid:1/_rethrottle?requests_per_second=unlimited
--------------------------------------------------
// CONSOLE

The `task_id` can be found using the tasks API above.

Just like when setting it on the `_reindex` API `requests_per_second` can be
either `unlimited` to disable throttling or any decimal number like `1.7` or
`12` to throttle to that level. Rethrottling that speeds up the query takes
effect immediately but rethrotting that slows down the query will take effect
on after completing the current batch. This prevents scroll timeouts.

[float]
=== Reindex to change the name of a field

`_reindex` can be used to build a copy of an index with renamed fields. Say you
create an index containing documents that look like this:

[source,js]
--------------------------------------------------
POST test/test/1?refresh
{
  "text": "words words",
  "flag": "foo"
}
--------------------------------------------------
// CONSOLE

But you don't like the name `flag` and want to replace it with `tag`.
`_reindex` can create the other index for you:

[source,js]
--------------------------------------------------
POST _reindex
{
  "source": {
    "index": "test"
  },
  "dest": {
    "index": "test2"
  },
  "script": {
    "inline": "ctx._source.tag = ctx._source.remove(\"flag\")"
  }
}
--------------------------------------------------
// CONSOLE
// TEST[continued]

Now you can get the new document:

[source,js]
--------------------------------------------------
GET test2/test/1
--------------------------------------------------
// CONSOLE
// TEST[continued]

and it'll look like:

[source,js]
--------------------------------------------------
{
  "found": true,
  "_id": "1",
  "_index": "test2",
  "_type": "test",
  "_version": 1,
  "_source": {
    "text": "words words",
    "tag": "foo"
  }
}
--------------------------------------------------
// TESTRESPONSE

Or you can search by `tag` or whatever you want.

[[docs-reindex]]
== Reindex API

experimental[The reindex API is new and should still be considered experimental.  The API may change in ways that are not backwards compatible]

The most basic form of `_reindex` just copies documents from one index to another.
This will copy documents from the `twitter` index into the `new_twitter` index:

[source,js]
--------------------------------------------------
POST _reindex
{
  "source": {
    "index": "twitter"
  },
  "dest": {
    "index": "new_twitter"
  }
}
--------------------------------------------------
// CONSOLE
// TEST[setup:big_twitter]

That will return something like this:

[source,js]
--------------------------------------------------
{
  "took" : 147,
  "timed_out": false,
  "created": 120,
  "updated": 0,
  "batches": 1,
  "version_conflicts": 0,
  "noops": 0,
  "retries": {
    "bulk": 0,
    "search": 0
  },
  "throttled_millis": 0,
  "requests_per_second": "unlimited",
  "throttled_until_millis": 0,
  "total": 120,
  "failures" : [ ]
}
--------------------------------------------------
// TESTRESPONSE[s/"took" : 147/"took" : "$body.took"/]

Just like <<docs-update-by-query,`_update_by_query`>>, `_reindex` gets a
snapshot of the source index but its target must be a **different** index so
version conflicts are unlikely. The `dest` element can be configured like the
index API to control optimistic concurrency control. Just leaving out
`version_type` (as above) or setting it to `internal` will cause Elasticsearch
to blindly dump documents into the target, overwriting any that happen to have
the same type and id:

[source,js]
--------------------------------------------------
POST _reindex
{
  "source": {
    "index": "twitter"
  },
  "dest": {
    "index": "new_twitter",
    "version_type": "internal"
  }
}
--------------------------------------------------
// CONSOLE
// TEST[setup:twitter]

Setting `version_type` to `external` will cause Elasticsearch to preserve the
`version` from the source, create any documents that are missing, and update
any documents that have an older version in the destination index than they do
in the source index:

[source,js]
--------------------------------------------------
POST _reindex
{
  "source": {
    "index": "twitter"
  },
  "dest": {
    "index": "new_twitter",
    "version_type": "external"
  }
}
--------------------------------------------------
// CONSOLE
// TEST[setup:twitter]

Settings `op_type` to `create` will cause `_reindex` to only create missing
documents in the target index. All existing documents will cause a version
conflict:

[source,js]
--------------------------------------------------
POST _reindex
{
  "source": {
    "index": "twitter"
  },
  "dest": {
    "index": "new_twitter",
    "op_type": "create"
  }
}
--------------------------------------------------
// CONSOLE
// TEST[setup:twitter]

By default version conflicts abort the `_reindex` process but you can just
count them by settings `"conflicts": "proceed"` in the request body:

[source,js]
--------------------------------------------------
POST _reindex
{
  "conflicts": "proceed",
  "source": {
    "index": "twitter"
  },
  "dest": {
    "index": "new_twitter",
    "op_type": "create"
  }
}
--------------------------------------------------
// CONSOLE
// TEST[setup:twitter]

You can increase the default batch size by setting the `size` parameter (which defaults to `1000`) to the `source`. Note that it is different than the `size` parameter available at the root, which limits the number of documents (see below).

[source,js]
--------------------------------------------------
POST /_reindex
{
  "source": {
    "index": "twitter",
    "size": 2000
  },
  "dest": {
    "index": "new_twitter"
  }
}
--------------------------------------------------
// AUTOSENSE

You can limit the documents by adding a type to the `source` or by adding a
query. This will only copy ++tweet++'s made by `kimchy` into `new_twitter`:

[source,js]
--------------------------------------------------
POST _reindex
{
  "source": {
    "index": "twitter",
    "type": "tweet",
    "query": {
      "term": {
        "user": "kimchy"
      }
    }
  },
  "dest": {
    "index": "new_twitter"
  }
}
--------------------------------------------------
// CONSOLE
// TEST[setup:twitter]

`index` and `type` in `source` can both be lists, allowing you to copy from
lots of sources in one request. This will copy documents from the `tweet` and
`post` types in the `twitter` and `blog` index. It'd include the `post` type in
the `twitter` index and the `tweet` type in the `blog` index. If you want to be
more specific you'll need to use the `query`. It also makes no effort to handle
ID collisions. The target index will remain valid but it's not easy to predict
which document will survive because the iteration order isn't well defined.

[source,js]
--------------------------------------------------
POST _reindex
{
  "source": {
    "index": ["twitter", "blog"],
    "type": ["tweet", "post"]
  },
  "dest": {
    "index": "all_together"
  }
}
--------------------------------------------------
// CONSOLE
// TEST[s/^/PUT twitter\nPUT blog\nGET _cluster\/health?wait_for_status=yellow\n/]

It's also possible to limit the number of processed documents by setting
`size`. This will only copy a single document from `twitter` to
`new_twitter`:

[source,js]
--------------------------------------------------
POST _reindex
{
  "size": 1,
  "source": {
    "index": "twitter"
  },
  "dest": {
    "index": "new_twitter"
  }
}
--------------------------------------------------
// CONSOLE
// TEST[setup:twitter]

If you want a particular set of documents from the twitter index you'll
need to sort. Sorting makes the scroll less efficient but in some contexts
it's worth it. If possible, prefer a more selective query to `size` and `sort`.
This will copy 10000 documents from `twitter` into `new_twitter`:

[source,js]
--------------------------------------------------
POST _reindex
{
  "size": 10000,
  "source": {
    "index": "twitter",
    "sort": { "date": "desc" }
  },
  "dest": {
    "index": "new_twitter"
  }
}
--------------------------------------------------
// CONSOLE
// TEST[setup:twitter]

Like `_update_by_query`, `_reindex` supports a script that modifies the
document. Unlike `_update_by_query`, the script is allowed to modify the
document's metadata. This example bumps the version of the source document:

[source,js]
--------------------------------------------------
POST _reindex
{
  "source": {
    "index": "twitter"
  },
  "dest": {
    "index": "new_twitter",
    "version_type": "external"
  },
  "script": {
    "script": "if (ctx._source.foo == 'bar') {ctx._version++; ctx._source.remove('foo')}"
  }
}
--------------------------------------------------
// CONSOLE
// TEST[setup:twitter]

Think of the possibilities! Just be careful! With great power.... You can
change:

 * `_id`
 * `_type`
 * `_index`
 * `_version`
 * `_routing`
 * `_parent`
 * `_timestamp`
 * `_ttl`

Setting `_version` to `null` or clearing it from the `ctx` map is just like not
sending the version in an indexing request. It will cause that document to be
overwritten in the target index regardless of the version on the target or the
version type you use in the `_reindex` request.

By default if `_reindex` sees a document with routing then the routing is
preserved unless it's changed by the script. You can set `routing` on the
`dest` request to change this:

`keep`::

Sets the routing on the bulk request sent for each match to the routing on
the match. The default.

`discard`::

Sets the routing on the bulk request sent for each match to null.

`=<some text>`::

Sets the routing on the bulk request sent for each match to all text after
the `=`.

For example, you can use the following request to copy all documents from
the `source` index with the company name `cat` into the `dest` index with
routing set to `cat`.

[source,js]
--------------------------------------------------
POST _reindex
{
  "source": {
    "index": "source",
    "query": {
      "match": {
        "company": "cat"
      }
    }
  },
  "dest": {
    "index": "dest",
    "routing": "=cat"
  }
}
--------------------------------------------------
// CONSOLE
// TEST[s/^/PUT source\nGET _cluster\/health?wait_for_status=yellow\n/]

By default `_reindex` uses scroll batches of 1000. You can change the
batch size with the `size` field in the `source` element:

[source,js]
--------------------------------------------------
POST _reindex
{
  "source": {
    "index": "source",
    "size": 100
  },
  "dest": {
    "index": "dest",
    "routing": "=cat"
  }
}
--------------------------------------------------
// CONSOLE
// TEST[s/^/PUT source\nGET _cluster\/health?wait_for_status=yellow\n/]

Reindex can also use the <<ingest>> feature by specifying a
`pipeline` like this:

[source,js]
--------------------------------------------------
POST _reindex
{
  "source": {
    "index": "source"
  },
  "dest": {
    "index": "dest",
    "pipeline": "some_ingest_pipeline"
  }
}
--------------------------------------------------
// CONSOLE
// TEST[s/^/PUT source\nGET _cluster\/health?wait_for_status=yellow\n/]

[float]
=== URL Parameters

In addition to the standard parameters like `pretty`, the Reindex API also
supports `refresh`, `wait_for_completion`, `consistency`, `timeout`, and
`requests_per_second`.

Sending the `refresh` url parameter will cause all indexes to which the request
wrote to be refreshed. This is different than the Index API's `refresh`
parameter which causes just the shard that received the new data to be indexed.

If the request contains `wait_for_completion=false` then Elasticsearch will
perform some preflight checks, launch the request, and then return a `task`
which can be used with <<docs-reindex-task-api,Tasks APIs>> to cancel or get
the status of the task. For now, once the request is finished the task is gone
and the only place to look for the ultimate result of the task is in the
Elasticsearch log file. This will be fixed soon.

`consistency` controls how many copies of a shard must respond to each write
request. `timeout` controls how long each write request waits for unavailable
shards to become available. Both work exactly how they work in the
<<docs-bulk,Bulk API>>.

`requests_per_second` can be set to any decimal number (`1.4`, `6`, `1000`, etc)
and throttles the number of requests per second that the reindex issues. The
throttling is done waiting between bulk batches so that it can manipulate the
scroll timeout. The wait time is the difference between the time it took the
batch to complete and the time `requests_per_second * requests_in_the_batch`.
Since the batch isn't broken into multiple bulk requests large batch sizes will
cause Elasticsearch to create many requests and then wait for a while before
starting the next set. This is "bursty" instead of "smooth". The default is
`unlimited` which is also the only non-number value that it accepts.

[float]
=== Response body

The JSON response looks like this:

[source,js]
--------------------------------------------------
{
  "took" : 639,
  "updated": 0,
  "created": 123,
  "batches": 1,
  "version_conflicts": 2,
  "retries": {
    "bulk": 0,
    "search": 0
  }
  "throttled_millis": 0,
  "failures" : [ ]
}
--------------------------------------------------

`took`::

The number of milliseconds from start to end of the whole operation.

`updated`::

The number of documents that were successfully updated.

`created`::

The number of documents that were successfully created.

`batches`::

The number of scroll responses pulled back by the the reindex.

`version_conflicts`::

The number of version conflicts that reindex hit.

`retries`::

The number of retries attempted by reindex. `bulk` is the number of bulk
actions retried and `search` is the number of search actions retried.

`throttled_millis`::

Number of milliseconds the request slept to conform to `requests_per_second`.

`failures`::

Array of all indexing failures. If this is non-empty then the request aborted
because of those failures. See `conflicts` for how to prevent version conflicts
from aborting the operation.

[float]
[[docs-reindex-task-api]]
=== Works with the Task API

While Reindex is running you can fetch their status using the
<<tasks,Task API>>:

[source,js]
--------------------------------------------------
GET _tasks?detailed=true&actions=*reindex
--------------------------------------------------
// CONSOLE

The responses looks like:

[source,js]
--------------------------------------------------
{
  "nodes" : {
    "r1A2WoRbTwKZ516z6NEs5A" : {
      "name" : "Tyrannus",
      "transport_address" : "127.0.0.1:9300",
      "host" : "127.0.0.1",
      "ip" : "127.0.0.1:9300",
      "attributes" : {
        "testattr" : "test",
        "portsfile" : "true"
      },
      "tasks" : {
        "r1A2WoRbTwKZ516z6NEs5A:36619" : {
          "node" : "r1A2WoRbTwKZ516z6NEs5A",
          "id" : 36619,
          "type" : "transport",
          "action" : "indices:data/write/reindex",
          "status" : {    <1>
            "total" : 6154,
            "updated" : 3500,
            "created" : 0,
            "deleted" : 0,
            "batches" : 4,
            "version_conflicts" : 0,
            "noops" : 0,
            "retries": {
              "bulk": 0,
              "search": 0
            },
            "throttled_millis": 0
          },
          "description" : ""
        }
      }
    }
  }
}
--------------------------------------------------

<1> this object contains the actual status. It is just like the response json
with the important addition of the `total` field. `total` is the total number
of operations that the reindex expects to perform. You can estimate the
progress by adding the `updated`, `created`, and `deleted` fields. The request
will finish when their sum is equal to the `total` field.

[float]
[[docs-reindex-cancel-task-api]]
=== Works with the Cancel Task API

Any Reindex can be canceled using the <<tasks,Task Cancel API>>:

[source,js]
--------------------------------------------------
POST _tasks/taskid:1/_cancel
--------------------------------------------------
// CONSOLE

The `task_id` can be found using the tasks API above.

Cancelation should happen quickly but might take a few seconds. The task status
API above will continue to list the task until it is wakes to cancel itself.

[float]
[[docs-reindex-rethrottle]]
=== Rethrottling

The value of `requests_per_second` can be changed on a running reindex using
the `_rethrottle` API:

[source,js]
--------------------------------------------------
POST _reindex/taskid:1/_rethrottle?requests_per_second=unlimited
--------------------------------------------------
// CONSOLE

The `task_id` can be found using the tasks API above.

Just like when setting it on the `_reindex` API `requests_per_second` can be
either `unlimited` to disable throttling or any decimal number like `1.7` or
`12` to throttle to that level. Rethrottling that speeds up the query takes
effect immediately but rethrotting that slows down the query will take effect
on after completing the current batch. This prevents scroll timeouts.

[float]
=== Reindex to change the name of a field

`_reindex` can be used to build a copy of an index with renamed fields. Say you
create an index containing documents that look like this:

[source,js]
--------------------------------------------------
POST test/test/1?refresh
{
  "text": "words words",
  "flag": "foo"
}
--------------------------------------------------
// CONSOLE

But you don't like the name `flag` and want to replace it with `tag`.
`_reindex` can create the other index for you:

[source,js]
--------------------------------------------------
POST _reindex
{
  "source": {
    "index": "test"
  },
  "dest": {
    "index": "test2"
  },
  "script": {
    "inline": "ctx._source.tag = ctx._source.remove(\"flag\")"
  }
}
--------------------------------------------------
// CONSOLE
// TEST[continued]

Now you can get the new document:

[source,js]
--------------------------------------------------
GET test2/test/1
--------------------------------------------------
// CONSOLE
// TEST[continued]

and it'll look like:

[source,js]
--------------------------------------------------
{
  "found": true,
  "_id": "1",
  "_index": "test2",
  "_type": "test",
  "_version": 1,
  "_source": {
    "text": "words words",
    "tag": "foo"
  }
}
--------------------------------------------------
// TESTRESPONSE

Or you can search by `tag` or whatever you want.


[DOCS] http.client_stats.enabled setting (#71188)

[[http-settings]]
==== Advanced HTTP settings

Use the following advanced settings to configure the HTTP interface
independently of the <<transport-settings,transport interface>>. You can also
configure both interfaces together using the <<common-network-settings,network settings>>.

`http.host`::
(<<static-cluster-setting,Static>>)
Sets the address of this node for HTTP traffic. The node will bind to this
address and will also use it as its HTTP publish address. Accepts an IP
address, a hostname, or a <<network-interface-values,special value>>.
Use this setting only if you require different configurations for the
transport and HTTP interfaces.
+
Defaults to the address given by `network.host`.

`http.bind_host`::
(<<static-cluster-setting,Static>>)
The network address(es) to which the node should bind in order to listen for
incoming HTTP connections. Accepts a list of IP addresses, hostnames, and
<<network-interface-values,special values>>. Defaults to the address given by
`http.host` or `network.bind_host`. Use this setting only if you require to
bind to multiple addresses or to use different addresses for publishing and
binding, and you also require different binding configurations for the
transport and HTTP interfaces.

`http.publish_host`::
(<<static-cluster-setting,Static>>)
The network address for HTTP clients to contact the node using sniffing.
Accepts an IP address, a hostname, or a <<network-interface-values,special
value>>. Defaults to the address given by `http.host` or
`network.publish_host`. Use this setting only if you require to bind to
multiple addresses or to use different addresses for publishing and binding,
and you also require different binding configurations for the transport and
HTTP interfaces.

`http.publish_port`::
(<<static-cluster-setting,Static>>)
The port of the <<modules-network-binding-publishing,HTTP publish address>>.
Configure this setting only if you need the publish port to be different from
`http.port`. Defaults to the port assigned via `http.port`.

`http.max_content_length`::
(<<static-cluster-setting,Static>>)
Maximum size of an HTTP request body. Defaults to `100mb`.

`http.max_initial_line_length`::
(<<static-cluster-setting,Static>>)
Maximum size of an HTTP URL. Defaults to `4kb`.

`http.max_header_size`::
(<<static-cluster-setting,Static>>)
Maximum size of allowed headers. Defaults to `8kb`.

[[http-compression]]
// tag::http-compression-tag[]
`http.compression` {ess-icon}::
(<<static-cluster-setting,Static>>)
Support for compression when possible (with Accept-Encoding). If HTTPS is enabled, defaults to `false`. Otherwise, defaults to `true`.
+
Disabling compression for HTTPS mitigates potential security risks, such as a
{wikipedia}/BREACH[BREACH attack]. To compress HTTPS traffic,
you must explicitly set `http.compression` to `true`.
// end::http-compression-tag[]

`http.compression_level`::
(<<static-cluster-setting,Static>>)
Defines the compression level to use for HTTP responses. Valid values are in the range of 1 (minimum compression) and 9 (maximum compression). Defaults to `3`.

[[http-cors-enabled]]
// tag::http-cors-enabled-tag[]
`http.cors.enabled` {ess-icon}::
(<<static-cluster-setting,Static>>)
Enable or disable cross-origin resource sharing, which determines whether a browser on another origin can execute requests against {es}. Set to `true` to enable {es} to process pre-flight
{wikipedia}/Cross-origin_resource_sharing[CORS] requests.
{es} will respond to those requests with the `Access-Control-Allow-Origin` header if the `Origin` sent in the request is permitted by the `http.cors.allow-origin` list. Set to `false` (the default) to make {es} ignore the `Origin` request header, effectively disabling CORS requests because {es} will never respond with the `Access-Control-Allow-Origin` response header.
+
NOTE: If the client does not send a pre-flight request with an `Origin` header or it does not check the response headers from the server to validate the
`Access-Control-Allow-Origin` response header, then cross-origin security is
compromised. If CORS is not enabled on {es}, the only way for the client to know is to send a pre-flight request and realize the required response headers are missing.

// end::http-cors-enabled-tag[]

[[http-cors-allow-origin]]
// tag::http-cors-allow-origin-tag[]
`http.cors.allow-origin` {ess-icon}::
(<<static-cluster-setting,Static>>)
Which origins to allow. If you prepend and append a forward slash (`/`) to the value, this will be treated as a regular expression, allowing you to support HTTP and HTTPs. For example, using `/https?:\/\/localhost(:[0-9]+)?/` would return the request header appropriately in both cases. Defaults to no origins allowed.
+
IMPORTANT: A wildcard (`*`) is a valid value but is considered a security risk, as your {es} instance is open to cross origin requests from *anywhere*.

// end::http-cors-allow-origin-tag[]

[[http-cors-max-age]]
// tag::http-cors-max-age-tag[]
`http.cors.max-age` {ess-icon}::
(<<static-cluster-setting,Static>>)
Browsers send a "preflight" OPTIONS-request to determine CORS settings. `max-age` defines how long the result should be cached for. Defaults to `1728000` (20 days).
// end::http-cors-max-age-tag[]

[[http-cors-allow-methods]]
// tag::http-cors-allow-methods-tag[]
`http.cors.allow-methods` {ess-icon}::
(<<static-cluster-setting,Static>>)
Which methods to allow. Defaults to `OPTIONS, HEAD, GET, POST, PUT, DELETE`.
// end::http-cors-allow-methods-tag[]

[[http-cors-allow-headers]]
// tag::http-cors-allow-headers-tag[]
`http.cors.allow-headers` {ess-icon}::
(<<static-cluster-setting,Static>>)
Which headers to allow. Defaults to `X-Requested-With, Content-Type, Content-Length`.
// end::http-cors-allow-headers-tag[]

[[http-cors-allow-credentials]]
// tag::http-cors-allow-credentials-tag[]
`http.cors.allow-credentials` {ess-icon}::
(<<static-cluster-setting,Static>>)
Whether the `Access-Control-Allow-Credentials` header should be returned. Defaults to `false`.
+
NOTE: This header is only returned when the setting is set to `true`.

// end::http-cors-allow-credentials-tag[]

`http.detailed_errors.enabled`::
(<<static-cluster-setting,Static>>)
If `true`, enables the output of detailed error messages and stack traces in the response output. Defaults to `true`.
+
If `false`, use the `error_trace` parameter to <<common-options-error-options,enable stack traces>> and return detailed error messages. Otherwise, only a simple message will be returned.

`http.pipelining.max_events`::
(<<static-cluster-setting,Static>>)
The maximum number of events to be queued up in memory before an HTTP connection is closed, defaults to `10000`.

`http.max_warning_header_count`::
(<<static-cluster-setting,Static>>)
The maximum number of warning headers in client HTTP responses. Defaults to `unbounded`.

`http.max_warning_header_size`::
(<<static-cluster-setting,Static>>)
The maximum total size of warning headers in client HTTP responses. Defaults to `unbounded`.

`http.tcp.no_delay`::
(<<static-cluster-setting,Static>>)
Enable or disable the {wikipedia}/Nagle%27s_algorithm[TCP no delay]
setting. Defaults to `network.tcp.no_delay`.

`http.tcp.keep_alive`::
(<<static-cluster-setting,Static>>)
Configures the `SO_KEEPALIVE` option for this socket, which
determines whether it sends TCP keepalive probes.
Defaults to `network.tcp.keep_alive`.

`http.tcp.keep_idle`::
(<<static-cluster-setting,Static>>) Configures the `TCP_KEEPIDLE` option for this socket, which
determines the time in seconds that a connection must be idle before
starting to send TCP keepalive probes. Defaults to `network.tcp.keep_idle`, which
uses the system default. This value cannot exceed `300` seconds. Only applicable on
Linux and macOS, and requires Java 11 or newer.

`http.tcp.keep_interval`::
(<<static-cluster-setting,Static>>) Configures the `TCP_KEEPINTVL` option for this socket,
which determines the time in seconds between sending TCP keepalive probes.
Defaults to `network.tcp.keep_interval`, which uses the system default.
This value cannot exceed `300` seconds. Only applicable on Linux and macOS, and requires
Java 11 or newer.

`http.tcp.keep_count`::
(<<static-cluster-setting,Static>>) Configures the `TCP_KEEPCNT` option for this socket, which
determines the number of unacknowledged TCP keepalive probes that may be
sent on a connection before it is dropped. Defaults to `network.tcp.keep_count`,
which uses the system default. Only applicable on Linux and macOS, and
requires Java 11 or newer.

`http.tcp.reuse_address`::
(<<static-cluster-setting,Static>>)
Should an address be reused or not. Defaults to `network.tcp.reuse_address`.

`http.tcp.send_buffer_size`::
(<<static-cluster-setting,Static>>)
The size of the TCP send buffer (specified with <<size-units,size units>>).
Defaults to `network.tcp.send_buffer_size`.

`http.tcp.receive_buffer_size`::
(<<static-cluster-setting,Static>>)
The size of the TCP receive buffer (specified with <<size-units,size units>>).
Defaults to `network.tcp.receive_buffer_size`.

`http.client_stats.enabled`::
(<<dynamic-cluster-setting,Dynamic>>)
Enable or disable collection of HTTP client stats. Defaults to `true`.


Shows how to disable CCS from dedicated master/data (#26860)

This is really just the last bit of the OSS component of https://github.com/elastic/elasticsearch/issues/25210

[[modules-node]]
== Node

Any time that you start an instance of Elasticsearch, you are starting a
_node_. A collection of connected nodes is  called a
<<modules-cluster,cluster>>. If you are running a single node of Elasticsearch,
then you have a cluster of one node.

Every node in the cluster can handle <<modules-http,HTTP>> and
<<modules-transport,Transport>> traffic by default. The transport layer
is used exclusively for communication between nodes and the
{javaclient}/transport-client.html[Java `TransportClient`]; the HTTP layer is
used only by external REST clients.

All nodes know about all the other nodes in the cluster and can forward client
requests to the appropriate node. Besides that, each node serves one or more
purpose:

<<master-node,Master-eligible node>>::

A node that has `node.master` set to `true` (default), which makes it eligible
to be <<modules-discovery-zen,elected as the _master_ node>>, which controls
the cluster.

<<data-node,Data node>>::

A node that has `node.data` set to `true` (default). Data nodes hold data and
perform data related operations such as CRUD, search, and aggregations.

<<ingest,Ingest node>>::

A node that has `node.ingest` set to `true` (default). Ingest nodes are able
to apply an <<pipeline,ingest pipeline>> to a document in order to transform
and enrich the document before indexing. With a heavy ingest load, it makes
sense to use dedicated ingest nodes and to mark the master and data nodes as
`node.ingest: false`.

<<modules-tribe,Tribe node>>::

A tribe node, configured via the `tribe.*` settings, is a special type  of
coordinating only node that can connect to multiple clusters and perform
search and other operations across all connected clusters.

By default a node is a master-eligible node and a data node, plus it can
pre-process documents through ingest pipelines. This is very convenient for
small clusters but, as the cluster grows, it becomes important to consider
separating dedicated master-eligible nodes from dedicated data nodes.

[NOTE]
[[coordinating-node]]
.Coordinating node
===============================================

Requests like search requests or bulk-indexing requests may involve data held
on different data nodes. A search request, for example, is executed in two
phases which are coordinated by the node which receives the client request --
the _coordinating node_.

In the _scatter_ phase, the coordinating node forwards the request to the data
nodes which hold the data.  Each data node executes the request locally and
returns its results to the coordinating node. In the _gather_  phase, the
coordinating node reduces each data node's results into a single global
resultset.

Every node is implicitly a coordinating node. This means that a node that has
all three `node.master`, `node.data` and `node.ingest` set to `false` will
only act as a coordinating node, which cannot be disabled. As a result, such
a node needs to have enough memory and CPU in order to deal with the gather
phase.

===============================================

[float]
[[master-node]]
=== Master Eligible Node

The master node is responsible for lightweight cluster-wide actions such as
creating or deleting an index, tracking which nodes are part of the cluster,
and deciding which shards to allocate to which nodes. It is important for
cluster health to have a stable master node.

Any master-eligible node (all nodes by default) may be elected to become the
master node by the <<modules-discovery-zen,master election process>>.

IMPORTANT: Master nodes must have access to the `data/` directory (just like
`data` nodes) as this is where the cluster state is persisted between node restarts.

Indexing and searching your data is CPU-, memory-, and I/O-intensive work
which can put pressure on a node's resources. To ensure that your master
node is stable and not under pressure, it is a good idea in a bigger
cluster to split the roles between dedicated master-eligible nodes and
dedicated data nodes.

While master nodes can also behave as <<coordinating-node,coordinating nodes>>
and route search and indexing requests from clients to data nodes, it is
better _not_ to use dedicated master nodes for this purpose. It is important
for the stability of the cluster that master-eligible nodes do as little work
as possible.

To create a dedicated master-eligible node, set:

[source,yaml]
-------------------
node.master: true <1>
node.data: false <2>
node.ingest: false <3>
search.remote.connect: false <4>
-------------------
<1> The `node.master` role is enabled by default.
<2> Disable the `node.data` role (enabled by default).
<3> Disable the `node.ingest` role (enabled by default).
<4> Disable cross-cluster search (enabled by default).

ifdef::include-xpack[]
NOTE: These settings apply only when {xpack} is not installed. To create a
dedicated master-eligible node when {xpack} is installed, see <<modules-node-xpack,{xpack} node settings>>.
endif::include-xpack[]

[float]
[[split-brain]]
==== Avoiding split brain with `minimum_master_nodes`

To prevent data loss, it is vital to configure the
`discovery.zen.minimum_master_nodes` setting (which defaults to `1`) so that
each master-eligible node knows the _minimum number of master-eligible nodes_
that must be visible in order to form a cluster.

To explain, imagine that you have a cluster consisting of two master-eligible
nodes. A network failure breaks communication between these two nodes.  Each
node sees one master-eligible node... itself. With `minimum_master_nodes` set
to the default of `1`,  this is sufficient to form a cluster. Each node elects
itself as the new master (thinking that the other master-eligible node has
died) and the result is two clusters, or a _split brain_.  These two nodes
will never rejoin until one node is restarted.  Any data that has been written
to the restarted node will be lost.

Now imagine that you have a cluster with three master-eligible nodes, and
`minimum_master_nodes` set to `2`.  If a network split separates one node from
the other two nodes, the side with one node cannot see enough master-eligible
nodes and will realise that it cannot elect itself as master.  The side with
two nodes will elect a new master (if needed) and continue functioning
correctly.  As soon as the network split is resolved, the single node will
rejoin the cluster and start serving requests again.

This setting should be set to a _quorum_ of master-eligible nodes:

  (master_eligible_nodes / 2) + 1

In other words, if there are three master-eligible nodes, then minimum master
nodes should be set to `(3 / 2) + 1` or `2`:

[source,yaml]
----------------------------
discovery.zen.minimum_master_nodes: 2 <1>
----------------------------
<1> Defaults to `1`.

This setting can also be changed dynamically on a live cluster with the
<<cluster-update-settings,cluster update settings API>>:

[source,js]
----------------------------
PUT _cluster/settings
{
  "transient": {
    "discovery.zen.minimum_master_nodes": 2
  }
}
----------------------------
// CONSOLE
// TEST[catch:/cannot set discovery.zen.minimum_master_nodes to more than the current master nodes/]

TIP: An advantage of splitting the master and data roles between dedicated
nodes is that you can have just three master-eligible nodes and set
`minimum_master_nodes` to `2`. You never have to change this setting, no
matter how many dedicated data nodes you add to the cluster.

[float]
[[data-node]]
=== Data Node

Data nodes hold the shards that contain the documents you have indexed. Data
nodes handle data related operations like CRUD, search, and aggregations.
These operations are I/O-, memory-, and CPU-intensive. It is important to
monitor these resources and to add more data nodes if they are overloaded.

The main benefit of having dedicated data nodes is the separation of the
master and data roles.

To create a dedicated data node, set:

[source,yaml]
-------------------
node.master: false <1>
node.data: true <2>
node.ingest: false <3>
search.remote.connect: false <4>
-------------------
<1> Disable the `node.master` role (enabled by default).
<2> The `node.data` role is enabled by default.
<3> Disable the `node.ingest` role (enabled by default).
<4> Disable cross-cluster search (enabled by default).

ifdef::include-xpack[]
NOTE: These settings apply only when {xpack} is not installed. To create a
dedicated data node when {xpack} is installed, see <<modules-node-xpack,{xpack} node settings>>.
endif::include-xpack[]

[float]
[[node-ingest-node]]
=== Ingest Node

Ingest nodes can execute pre-processing pipelines, composed of one or more
ingest processors. Depending on the type of operations performed by the ingest
processors and the required resources, it may make sense to have dedicated
ingest nodes, that will only perform this specific task.

To create a dedicated ingest node, set:

[source,yaml]
-------------------
node.master: false <1>
node.data: false <2>
node.ingest: true <3>
search.remote.connect: false <4>
-------------------
<1> Disable the `node.master` role (enabled by default).
<2> Disable the `node.data` role (enabled by default).
<3> The `node.ingest` role is enabled by default.
<4> Disable cross-cluster search (enabled by default).

ifdef::include-xpack[]
NOTE: These settings apply only when {xpack} is not installed. To create a
dedicated ingest node when {xpack} is installed, see <<modules-node-xpack,{xpack} node settings>>.
endif::include-xpack[]

[float]
[[coordinating-only-node]]
=== Coordinating only node

If you take away the ability to be able to handle master duties, to hold data,
and pre-process documents, then you are left with a _coordinating_ node that
can only route requests, handle the search reduce phase, and distribute bulk
indexing. Essentially, coordinating only nodes behave as smart load balancers.

Coordinating only nodes can benefit large clusters by offloading the
coordinating node role from data and master-eligible nodes.  They join the
cluster and receive the full <<cluster-state,cluster state>>, like every other
node, and they use the cluster state to route requests directly to the
appropriate place(s).

WARNING: Adding too many coordinating only nodes to a cluster can increase the
burden on the entire cluster because the elected master node must await
acknowledgement of cluster state updates from every node! The benefit of
coordinating only nodes should not be overstated -- data nodes can happily
serve the same purpose.

To create a dedicated coordinating node, set:

[source,yaml]
-------------------
node.master: false <1>
node.data: false <2>
node.ingest: false <3>
search.remote.connect: false <4>
-------------------
<1> Disable the `node.master` role (enabled by default).
<2> Disable the `node.data` role (enabled by default).
<3> Disable the `node.ingest` role (enabled by default).
<4> Disable cross-cluster search (enabled by default).

ifdef::include-xpack[]
NOTE: These settings apply only when {xpack} is not installed. To create a
dedicated coordinating node when {xpack} is installed, see <<modules-node-xpack,{xpack} node settings>>.
endif::include-xpack[]

[float]
== Node data path settings

[float]
[[data-path]]
=== `path.data`

Every data and master-eligible node requires access to a data directory where
shards and index and cluster metadata will be stored. The `path.data` defaults
to `$ES_HOME/data` but can be configured in the `elasticsearch.yml` config
file an absolute path or a path relative to `$ES_HOME` as follows:

[source,yaml]
-----------------------
path.data:  /var/elasticsearch/data
-----------------------

Like all node settings, it can also be specified on the command line as:

[source,sh]
-----------------------
./bin/elasticsearch -Epath.data=/var/elasticsearch/data
-----------------------

TIP: When using the `.zip` or `.tar.gz` distributions, the `path.data` setting
should be configured to locate the data directory outside the Elasticsearch
home directory, so that the home directory can be deleted without deleting
your data! The RPM and Debian distributions do this for you already.

[float]
[[max-local-storage-nodes]]
=== `node.max_local_storage_nodes`

The <<data-path,data path>> can be shared by multiple nodes, even by nodes from different
clusters. This is very useful for testing failover and different configurations on your development
machine. In production, however, it is recommended to run only one node of Elasticsearch per server.

By default, Elasticsearch is configured to prevent more than one node from sharing the same data
path. To allow for more than one node (e.g., on your development machine), use the setting
`node.max_local_storage_nodes` and set this to a positive integer larger than one.

WARNING: Never run different node types (i.e. master, data) from the same data directory. This can
lead to unexpected data loss.

[float]
== Other node settings

More node settings can be found in <<modules,Modules>>.  Of particular note are
the <<cluster.name,`cluster.name`>>, the <<node.name,`node.name`>> and the
<<modules-network,network settings>>.

ifdef::include-xpack[]
:edit_url!:
include::{xes-repo-dir}/node.asciidoc[]
endif::include-xpack[]

[[modules-node]]
== Node

Any time that you start an instance of Elasticsearch, you are starting a
_node_. A collection of connected nodes is  called a
<<modules-cluster,cluster>>. If you are running a single node of Elasticsearch,
then you have a cluster of one node.

Every node in the cluster can handle <<modules-http,HTTP>> and
<<modules-transport,Transport>> traffic by default. The transport layer
is used exclusively for communication between nodes and the
{javaclient}/transport-client.html[Java `TransportClient`]; the HTTP layer is
used only by external REST clients.

All nodes know about all the other nodes in the cluster and can forward client
requests to the appropriate node. Besides that, each node serves one or more
purpose:

<<master-node,Master-eligible node>>::

A node that has `node.master` set to `true` (default), which makes it eligible
to be <<modules-discovery-zen,elected as the _master_ node>>, which controls
the cluster.

<<data-node,Data node>>::

A node that has `node.data` set to `true` (default). Data nodes hold data and
perform data related operations such as CRUD, search, and aggregations.

<<ingest,Ingest node>>::

A node that has `node.ingest` set to `true` (default). Ingest nodes are able
to apply an <<pipeline,ingest pipeline>> to a document in order to transform
and enrich the document before indexing. With a heavy ingest load, it makes
sense to use dedicated ingest nodes and to mark the master and data nodes as
`node.ingest: false`.

<<modules-tribe,Tribe node>>::

A tribe node, configured via the `tribe.*` settings, is a special type  of
coordinating only node that can connect to multiple clusters and perform
search and other operations across all connected clusters.

By default a node is a master-eligible node and a data node, plus it can
pre-process documents through ingest pipelines. This is very convenient for
small clusters but, as the cluster grows, it becomes important to consider
separating dedicated master-eligible nodes from dedicated data nodes.

[NOTE]
[[coordinating-node]]
.Coordinating node
===============================================

Requests like search requests or bulk-indexing requests may involve data held
on different data nodes. A search request, for example, is executed in two
phases which are coordinated by the node which receives the client request --
the _coordinating node_.

In the _scatter_ phase, the coordinating node forwards the request to the data
nodes which hold the data.  Each data node executes the request locally and
returns its results to the coordinating node. In the _gather_  phase, the
coordinating node reduces each data node's results into a single global
resultset.

Every node is implicitly a coordinating node. This means that a node that has
all three `node.master`, `node.data` and `node.ingest` set to `false` will
only act as a coordinating node, which cannot be disabled. As a result, such
a node needs to have enough memory and CPU in order to deal with the gather
phase.

===============================================

[float]
[[master-node]]
=== Master Eligible Node

The master node is responsible for lightweight cluster-wide actions such as
creating or deleting an index, tracking which nodes are part of the cluster,
and deciding which shards to allocate to which nodes. It is important for
cluster health to have a stable master node.

Any master-eligible node (all nodes by default) may be elected to become the
master node by the <<modules-discovery-zen,master election process>>.

IMPORTANT: Master nodes must have access to the `data/` directory (just like
`data` nodes) as this is where the cluster state is persisted between node restarts.

Indexing and searching your data is CPU-, memory-, and I/O-intensive work
which can put pressure on a node's resources. To ensure that your master
node is stable and not under pressure, it is a good idea in a bigger
cluster to split the roles between dedicated master-eligible nodes and
dedicated data nodes.

While master nodes can also behave as <<coordinating-node,coordinating nodes>>
and route search and indexing requests from clients to data nodes, it is
better _not_ to use dedicated master nodes for this purpose. It is important
for the stability of the cluster that master-eligible nodes do as little work
as possible.

To create a dedicated master-eligible node, set:

[source,yaml]
-------------------
node.master: true <1>
node.data: false <2>
node.ingest: false <3>
-------------------
<1> The `node.master` role is enabled by default.
<2> Disable the `node.data` role (enabled by default).
<3> Disable the `node.ingest` role (enabled by default).

ifdef::include-xpack[]
NOTE: These settings apply only when {xpack} is not installed. To create a
dedicated master-eligible node when {xpack} is installed, see <<modules-node-xpack,{xpack} node settings>>.
endif::include-xpack[]

[float]
[[split-brain]]
==== Avoiding split brain with `minimum_master_nodes`

To prevent data loss, it is vital to configure the
`discovery.zen.minimum_master_nodes` setting (which defaults to `1`) so that
each master-eligible node knows the _minimum number of master-eligible nodes_
that must be visible in order to form a cluster.

To explain, imagine that you have a cluster consisting of two master-eligible
nodes. A network failure breaks communication between these two nodes.  Each
node sees one master-eligible node... itself. With `minimum_master_nodes` set
to the default of `1`,  this is sufficient to form a cluster. Each node elects
itself as the new master (thinking that the other master-eligible node has
died) and the result is two clusters, or a _split brain_.  These two nodes
will never rejoin until one node is restarted.  Any data that has been written
to the restarted node will be lost.

Now imagine that you have a cluster with three master-eligible nodes, and
`minimum_master_nodes` set to `2`.  If a network split separates one node from
the other two nodes, the side with one node cannot see enough master-eligible
nodes and will realise that it cannot elect itself as master.  The side with
two nodes will elect a new master (if needed) and continue functioning
correctly.  As soon as the network split is resolved, the single node will
rejoin the cluster and start serving requests again.

This setting should be set to a _quorum_ of master-eligible nodes:

  (master_eligible_nodes / 2) + 1

In other words, if there are three master-eligible nodes, then minimum master
nodes should be set to `(3 / 2) + 1` or `2`:

[source,yaml]
----------------------------
discovery.zen.minimum_master_nodes: 2 <1>
----------------------------
<1> Defaults to `1`.

This setting can also be changed dynamically on a live cluster with the
<<cluster-update-settings,cluster update settings API>>:

[source,js]
----------------------------
PUT _cluster/settings
{
  "transient": {
    "discovery.zen.minimum_master_nodes": 2
  }
}
----------------------------
// CONSOLE
// TEST[catch:/cannot set discovery.zen.minimum_master_nodes to more than the current master nodes/]

TIP: An advantage of splitting the master and data roles between dedicated
nodes is that you can have just three master-eligible nodes and set
`minimum_master_nodes` to `2`. You never have to change this setting, no
matter how many dedicated data nodes you add to the cluster.

[float]
[[data-node]]
=== Data Node

Data nodes hold the shards that contain the documents you have indexed. Data
nodes handle data related operations like CRUD, search, and aggregations.
These operations are I/O-, memory-, and CPU-intensive. It is important to
monitor these resources and to add more data nodes if they are overloaded.

The main benefit of having dedicated data nodes is the separation of the
master and data roles.

To create a dedicated data node, set:

[source,yaml]
-------------------
node.master: false <1>
node.data: true <2>
node.ingest: false <3>
-------------------
<1> Disable the `node.master` role (enabled by default).
<2> The `node.data` role is enabled by default.
<3> Disable the `node.ingest` role (enabled by default).

ifdef::include-xpack[]
NOTE: These settings apply only when {xpack} is not installed. To create a
dedicated data node when {xpack} is installed, see <<modules-node-xpack,{xpack} node settings>>.
endif::include-xpack[]

[float]
[[node-ingest-node]]
=== Ingest Node

Ingest nodes can execute pre-processing pipelines, composed of one or more
ingest processors. Depending on the type of operations performed by the ingest
processors and the required resources, it may make sense to have dedicated
ingest nodes, that will only perform this specific task.

To create a dedicated ingest node, set:

[source,yaml]
-------------------
node.master: false <1>
node.data: false <2>
node.ingest: true <3>
search.remote.connect: false <4>
-------------------
<1> Disable the `node.master` role (enabled by default).
<2> Disable the `node.data` role (enabled by default).
<3> The `node.ingest` role is enabled by default.
<4> Disable cross-cluster search (enabled by default).

ifdef::include-xpack[]
NOTE: These settings apply only when {xpack} is not installed. To create a
dedicated ingest node when {xpack} is installed, see <<modules-node-xpack,{xpack} node settings>>.
endif::include-xpack[]

[float]
[[coordinating-only-node]]
=== Coordinating only node

If you take away the ability to be able to handle master duties, to hold data,
and pre-process documents, then you are left with a _coordinating_ node that
can only route requests, handle the search reduce phase, and distribute bulk
indexing. Essentially, coordinating only nodes behave as smart load balancers.

Coordinating only nodes can benefit large clusters by offloading the
coordinating node role from data and master-eligible nodes.  They join the
cluster and receive the full <<cluster-state,cluster state>>, like every other
node, and they use the cluster state to route requests directly to the
appropriate place(s).

WARNING: Adding too many coordinating only nodes to a cluster can increase the
burden on the entire cluster because the elected master node must await
acknowledgement of cluster state updates from every node! The benefit of
coordinating only nodes should not be overstated -- data nodes can happily
serve the same purpose.

To create a dedicated coordinating node, set:

[source,yaml]
-------------------
node.master: false <1>
node.data: false <2>
node.ingest: false <3>
search.remote.connect: false <4>
-------------------
<1> Disable the `node.master` role (enabled by default).
<2> Disable the `node.data` role (enabled by default).
<3> Disable the `node.ingest` role (enabled by default).
<4> Disable cross-cluster search (enabled by default).

ifdef::include-xpack[]
NOTE: These settings apply only when {xpack} is not installed. To create a
dedicated coordinating node when {xpack} is installed, see <<modules-node-xpack,{xpack} node settings>>.
endif::include-xpack[]

[float]
== Node data path settings

[float]
[[data-path]]
=== `path.data`

Every data and master-eligible node requires access to a data directory where
shards and index and cluster metadata will be stored. The `path.data` defaults
to `$ES_HOME/data` but can be configured in the `elasticsearch.yml` config
file an absolute path or a path relative to `$ES_HOME` as follows:

[source,yaml]
-----------------------
path.data:  /var/elasticsearch/data
-----------------------

Like all node settings, it can also be specified on the command line as:

[source,sh]
-----------------------
./bin/elasticsearch -Epath.data=/var/elasticsearch/data
-----------------------

TIP: When using the `.zip` or `.tar.gz` distributions, the `path.data` setting
should be configured to locate the data directory outside the Elasticsearch
home directory, so that the home directory can be deleted without deleting
your data! The RPM and Debian distributions do this for you already.

[float]
[[max-local-storage-nodes]]
=== `node.max_local_storage_nodes`

The <<data-path,data path>> can be shared by multiple nodes, even by nodes from different
clusters. This is very useful for testing failover and different configurations on your development
machine. In production, however, it is recommended to run only one node of Elasticsearch per server.

By default, Elasticsearch is configured to prevent more than one node from sharing the same data
path. To allow for more than one node (e.g., on your development machine), use the setting
`node.max_local_storage_nodes` and set this to a positive integer larger than one.

WARNING: Never run different node types (i.e. master, data) from the same data directory. This can
lead to unexpected data loss.

[float]
== Other node settings

More node settings can be found in <<modules,Modules>>.  Of particular note are
the <<cluster.name,`cluster.name`>>, the <<node.name,`node.name`>> and the
<<modules-network,network settings>>.

ifdef::include-xpack[]
:edit_url!:
include::{xes-repo-dir}/node.asciidoc[]
endif::include-xpack[]


Reinstate recommendation for ≥ 3 master-eligible nodes. (#27204)

In the docs for 1.7 ([doc][doc-1.7], [src][src-1.7]) there was a recommendation
for at least 3 master-eligible nodes "in critical clusters" but this was lost
when that page was updated in 2.0 ([doc][doc-2.0], [src][src-2.0]). I'd like to
reinstate this.

[doc-1.7]: https://www.elastic.co/guide/en/elasticsearch/reference/1.7/modules-node.html
[src-1.7]: https://github.com/elastic/elasticsearch/blob/2cbaccb2f2a495923bc64447fe3396e0fc58b3d3/docs/reference/modules/node.asciidoc
[doc-2.0]: https://www.elastic.co/guide/en/elasticsearch/reference/2.0/modules-node.html#split-brain
[src-2.0]: https://github.com/elastic/elasticsearch/blob/4799009ad7ea8f885b6aedc6f62ad61d69e7a40d/docs/reference/modules/node.asciidoc

[[modules-node]]
== Node

Any time that you start an instance of Elasticsearch, you are starting a
_node_. A collection of connected nodes is  called a
<<modules-cluster,cluster>>. If you are running a single node of Elasticsearch,
then you have a cluster of one node.

Every node in the cluster can handle <<modules-http,HTTP>> and
<<modules-transport,Transport>> traffic by default. The transport layer
is used exclusively for communication between nodes and the
{javaclient}/transport-client.html[Java `TransportClient`]; the HTTP layer is
used only by external REST clients.

All nodes know about all the other nodes in the cluster and can forward client
requests to the appropriate node. Besides that, each node serves one or more
purpose:

<<master-node,Master-eligible node>>::

A node that has `node.master` set to `true` (default), which makes it eligible
to be <<modules-discovery-zen,elected as the _master_ node>>, which controls
the cluster.

<<data-node,Data node>>::

A node that has `node.data` set to `true` (default). Data nodes hold data and
perform data related operations such as CRUD, search, and aggregations.

<<ingest,Ingest node>>::

A node that has `node.ingest` set to `true` (default). Ingest nodes are able
to apply an <<pipeline,ingest pipeline>> to a document in order to transform
and enrich the document before indexing. With a heavy ingest load, it makes
sense to use dedicated ingest nodes and to mark the master and data nodes as
`node.ingest: false`.

<<modules-tribe,Tribe node>>::

A tribe node, configured via the `tribe.*` settings, is a special type  of
coordinating only node that can connect to multiple clusters and perform
search and other operations across all connected clusters.

By default a node is a master-eligible node and a data node, plus it can
pre-process documents through ingest pipelines. This is very convenient for
small clusters but, as the cluster grows, it becomes important to consider
separating dedicated master-eligible nodes from dedicated data nodes.

[NOTE]
[[coordinating-node]]
.Coordinating node
===============================================

Requests like search requests or bulk-indexing requests may involve data held
on different data nodes. A search request, for example, is executed in two
phases which are coordinated by the node which receives the client request --
the _coordinating node_.

In the _scatter_ phase, the coordinating node forwards the request to the data
nodes which hold the data.  Each data node executes the request locally and
returns its results to the coordinating node. In the _gather_  phase, the
coordinating node reduces each data node's results into a single global
resultset.

Every node is implicitly a coordinating node. This means that a node that has
all three `node.master`, `node.data` and `node.ingest` set to `false` will
only act as a coordinating node, which cannot be disabled. As a result, such
a node needs to have enough memory and CPU in order to deal with the gather
phase.

===============================================

[float]
[[master-node]]
=== Master Eligible Node

The master node is responsible for lightweight cluster-wide actions such as
creating or deleting an index, tracking which nodes are part of the cluster,
and deciding which shards to allocate to which nodes. It is important for
cluster health to have a stable master node.

Any master-eligible node (all nodes by default) may be elected to become the
master node by the <<modules-discovery-zen,master election process>>.

IMPORTANT: Master nodes must have access to the `data/` directory (just like
`data` nodes) as this is where the cluster state is persisted between node restarts.

Indexing and searching your data is CPU-, memory-, and I/O-intensive work
which can put pressure on a node's resources. To ensure that your master
node is stable and not under pressure, it is a good idea in a bigger
cluster to split the roles between dedicated master-eligible nodes and
dedicated data nodes.

While master nodes can also behave as <<coordinating-node,coordinating nodes>>
and route search and indexing requests from clients to data nodes, it is
better _not_ to use dedicated master nodes for this purpose. It is important
for the stability of the cluster that master-eligible nodes do as little work
as possible.

To create a dedicated master-eligible node, set:

[source,yaml]
-------------------
node.master: true <1>
node.data: false <2>
node.ingest: false <3>
search.remote.connect: false <4>
-------------------
<1> The `node.master` role is enabled by default.
<2> Disable the `node.data` role (enabled by default).
<3> Disable the `node.ingest` role (enabled by default).
<4> Disable cross-cluster search (enabled by default).

ifdef::include-xpack[]
NOTE: These settings apply only when {xpack} is not installed. To create a
dedicated master-eligible node when {xpack} is installed, see <<modules-node-xpack,{xpack} node settings>>.
endif::include-xpack[]

[float]
[[split-brain]]
==== Avoiding split brain with `minimum_master_nodes`

To prevent data loss, it is vital to configure the
`discovery.zen.minimum_master_nodes` setting (which defaults to `1`) so that
each master-eligible node knows the _minimum number of master-eligible nodes_
that must be visible in order to form a cluster.

To explain, imagine that you have a cluster consisting of two master-eligible
nodes. A network failure breaks communication between these two nodes.  Each
node sees one master-eligible node... itself. With `minimum_master_nodes` set
to the default of `1`,  this is sufficient to form a cluster. Each node elects
itself as the new master (thinking that the other master-eligible node has
died) and the result is two clusters, or a _split brain_.  These two nodes
will never rejoin until one node is restarted.  Any data that has been written
to the restarted node will be lost.

Now imagine that you have a cluster with three master-eligible nodes, and
`minimum_master_nodes` set to `2`.  If a network split separates one node from
the other two nodes, the side with one node cannot see enough master-eligible
nodes and will realise that it cannot elect itself as master.  The side with
two nodes will elect a new master (if needed) and continue functioning
correctly.  As soon as the network split is resolved, the single node will
rejoin the cluster and start serving requests again.

This setting should be set to a _quorum_ of master-eligible nodes:

  (master_eligible_nodes / 2) + 1

In other words, if there are three master-eligible nodes, then minimum master
nodes should be set to `(3 / 2) + 1` or `2`:

[source,yaml]
----------------------------
discovery.zen.minimum_master_nodes: 2 <1>
----------------------------
<1> Defaults to `1`.

To be able to remain available when one of the master-eligible nodes fails,
clusters should have at least three master-eligible nodes, with
`minimum_master_nodes` set accordingly. A <<rolling-upgrades,rolling upgrade>>,
performed without any downtime, also requires at least three master-eligible
nodes to avoid the possibility of data loss if a network split occurs while the
upgrade is in progress.

This setting can also be changed dynamically on a live cluster with the
<<cluster-update-settings,cluster update settings API>>:

[source,js]
----------------------------
PUT _cluster/settings
{
  "transient": {
    "discovery.zen.minimum_master_nodes": 2
  }
}
----------------------------
// CONSOLE
// TEST[catch:/cannot set discovery.zen.minimum_master_nodes to more than the current master nodes/]

TIP: An advantage of splitting the master and data roles between dedicated
nodes is that you can have just three master-eligible nodes and set
`minimum_master_nodes` to `2`. You never have to change this setting, no
matter how many dedicated data nodes you add to the cluster.

[float]
[[data-node]]
=== Data Node

Data nodes hold the shards that contain the documents you have indexed. Data
nodes handle data related operations like CRUD, search, and aggregations.
These operations are I/O-, memory-, and CPU-intensive. It is important to
monitor these resources and to add more data nodes if they are overloaded.

The main benefit of having dedicated data nodes is the separation of the
master and data roles.

To create a dedicated data node, set:

[source,yaml]
-------------------
node.master: false <1>
node.data: true <2>
node.ingest: false <3>
search.remote.connect: false <4>
-------------------
<1> Disable the `node.master` role (enabled by default).
<2> The `node.data` role is enabled by default.
<3> Disable the `node.ingest` role (enabled by default).
<4> Disable cross-cluster search (enabled by default).

ifdef::include-xpack[]
NOTE: These settings apply only when {xpack} is not installed. To create a
dedicated data node when {xpack} is installed, see <<modules-node-xpack,{xpack} node settings>>.
endif::include-xpack[]

[float]
[[node-ingest-node]]
=== Ingest Node

Ingest nodes can execute pre-processing pipelines, composed of one or more
ingest processors. Depending on the type of operations performed by the ingest
processors and the required resources, it may make sense to have dedicated
ingest nodes, that will only perform this specific task.

To create a dedicated ingest node, set:

[source,yaml]
-------------------
node.master: false <1>
node.data: false <2>
node.ingest: true <3>
search.remote.connect: false <4>
-------------------
<1> Disable the `node.master` role (enabled by default).
<2> Disable the `node.data` role (enabled by default).
<3> The `node.ingest` role is enabled by default.
<4> Disable cross-cluster search (enabled by default).

ifdef::include-xpack[]
NOTE: These settings apply only when {xpack} is not installed. To create a
dedicated ingest node when {xpack} is installed, see <<modules-node-xpack,{xpack} node settings>>.
endif::include-xpack[]

[float]
[[coordinating-only-node]]
=== Coordinating only node

If you take away the ability to be able to handle master duties, to hold data,
and pre-process documents, then you are left with a _coordinating_ node that
can only route requests, handle the search reduce phase, and distribute bulk
indexing. Essentially, coordinating only nodes behave as smart load balancers.

Coordinating only nodes can benefit large clusters by offloading the
coordinating node role from data and master-eligible nodes.  They join the
cluster and receive the full <<cluster-state,cluster state>>, like every other
node, and they use the cluster state to route requests directly to the
appropriate place(s).

WARNING: Adding too many coordinating only nodes to a cluster can increase the
burden on the entire cluster because the elected master node must await
acknowledgement of cluster state updates from every node! The benefit of
coordinating only nodes should not be overstated -- data nodes can happily
serve the same purpose.

To create a dedicated coordinating node, set:

[source,yaml]
-------------------
node.master: false <1>
node.data: false <2>
node.ingest: false <3>
search.remote.connect: false <4>
-------------------
<1> Disable the `node.master` role (enabled by default).
<2> Disable the `node.data` role (enabled by default).
<3> Disable the `node.ingest` role (enabled by default).
<4> Disable cross-cluster search (enabled by default).

ifdef::include-xpack[]
NOTE: These settings apply only when {xpack} is not installed. To create a
dedicated coordinating node when {xpack} is installed, see <<modules-node-xpack,{xpack} node settings>>.
endif::include-xpack[]

[float]
== Node data path settings

[float]
[[data-path]]
=== `path.data`

Every data and master-eligible node requires access to a data directory where
shards and index and cluster metadata will be stored. The `path.data` defaults
to `$ES_HOME/data` but can be configured in the `elasticsearch.yml` config
file an absolute path or a path relative to `$ES_HOME` as follows:

[source,yaml]
-----------------------
path.data:  /var/elasticsearch/data
-----------------------

Like all node settings, it can also be specified on the command line as:

[source,sh]
-----------------------
./bin/elasticsearch -Epath.data=/var/elasticsearch/data
-----------------------

TIP: When using the `.zip` or `.tar.gz` distributions, the `path.data` setting
should be configured to locate the data directory outside the Elasticsearch
home directory, so that the home directory can be deleted without deleting
your data! The RPM and Debian distributions do this for you already.

[float]
[[max-local-storage-nodes]]
=== `node.max_local_storage_nodes`

The <<data-path,data path>> can be shared by multiple nodes, even by nodes from different
clusters. This is very useful for testing failover and different configurations on your development
machine. In production, however, it is recommended to run only one node of Elasticsearch per server.

By default, Elasticsearch is configured to prevent more than one node from sharing the same data
path. To allow for more than one node (e.g., on your development machine), use the setting
`node.max_local_storage_nodes` and set this to a positive integer larger than one.

WARNING: Never run different node types (i.e. master, data) from the same data directory. This can
lead to unexpected data loss.

[float]
== Other node settings

More node settings can be found in <<modules,Modules>>.  Of particular note are
the <<cluster.name,`cluster.name`>>, the <<node.name,`node.name`>> and the
<<modules-network,network settings>>.

ifdef::include-xpack[]
:edit_url!:
include::{xes-repo-dir}/node.asciidoc[]
endif::include-xpack[]

[[modules-node]]
== Node

Any time that you start an instance of Elasticsearch, you are starting a
_node_. A collection of connected nodes is  called a
<<modules-cluster,cluster>>. If you are running a single node of Elasticsearch,
then you have a cluster of one node.

Every node in the cluster can handle <<modules-http,HTTP>> and
<<modules-transport,Transport>> traffic by default. The transport layer
is used exclusively for communication between nodes and the
{javaclient}/transport-client.html[Java `TransportClient`]; the HTTP layer is
used only by external REST clients.

All nodes know about all the other nodes in the cluster and can forward client
requests to the appropriate node. Besides that, each node serves one or more
purpose:

<<master-node,Master-eligible node>>::

A node that has `node.master` set to `true` (default), which makes it eligible
to be <<modules-discovery-zen,elected as the _master_ node>>, which controls
the cluster.

<<data-node,Data node>>::

A node that has `node.data` set to `true` (default). Data nodes hold data and
perform data related operations such as CRUD, search, and aggregations.

<<ingest,Ingest node>>::

A node that has `node.ingest` set to `true` (default). Ingest nodes are able
to apply an <<pipeline,ingest pipeline>> to a document in order to transform
and enrich the document before indexing. With a heavy ingest load, it makes
sense to use dedicated ingest nodes and to mark the master and data nodes as
`node.ingest: false`.

<<modules-tribe,Tribe node>>::

A tribe node, configured via the `tribe.*` settings, is a special type  of
coordinating only node that can connect to multiple clusters and perform
search and other operations across all connected clusters.

By default a node is a master-eligible node and a data node, plus it can
pre-process documents through ingest pipelines. This is very convenient for
small clusters but, as the cluster grows, it becomes important to consider
separating dedicated master-eligible nodes from dedicated data nodes.

[NOTE]
[[coordinating-node]]
.Coordinating node
===============================================

Requests like search requests or bulk-indexing requests may involve data held
on different data nodes. A search request, for example, is executed in two
phases which are coordinated by the node which receives the client request --
the _coordinating node_.

In the _scatter_ phase, the coordinating node forwards the request to the data
nodes which hold the data.  Each data node executes the request locally and
returns its results to the coordinating node. In the _gather_  phase, the
coordinating node reduces each data node's results into a single global
resultset.

Every node is implicitly a coordinating node. This means that a node that has
all three `node.master`, `node.data` and `node.ingest` set to `false` will
only act as a coordinating node, which cannot be disabled. As a result, such
a node needs to have enough memory and CPU in order to deal with the gather
phase.

===============================================

[float]
[[master-node]]
=== Master Eligible Node

The master node is responsible for lightweight cluster-wide actions such as
creating or deleting an index, tracking which nodes are part of the cluster,
and deciding which shards to allocate to which nodes. It is important for
cluster health to have a stable master node.

Any master-eligible node (all nodes by default) may be elected to become the
master node by the <<modules-discovery-zen,master election process>>.

IMPORTANT: Master nodes must have access to the `data/` directory (just like
`data` nodes) as this is where the cluster state is persisted between node restarts.

Indexing and searching your data is CPU-, memory-, and I/O-intensive work
which can put pressure on a node's resources. To ensure that your master
node is stable and not under pressure, it is a good idea in a bigger
cluster to split the roles between dedicated master-eligible nodes and
dedicated data nodes.

While master nodes can also behave as <<coordinating-node,coordinating nodes>>
and route search and indexing requests from clients to data nodes, it is
better _not_ to use dedicated master nodes for this purpose. It is important
for the stability of the cluster that master-eligible nodes do as little work
as possible.

To create a dedicated master-eligible node, set:

[source,yaml]
-------------------
node.master: true <1>
node.data: false <2>
node.ingest: false <3>
search.remote.connect: false <4>
-------------------
<1> The `node.master` role is enabled by default.
<2> Disable the `node.data` role (enabled by default).
<3> Disable the `node.ingest` role (enabled by default).
<4> Disable cross-cluster search (enabled by default).

ifdef::include-xpack[]
NOTE: These settings apply only when {xpack} is not installed. To create a
dedicated master-eligible node when {xpack} is installed, see <<modules-node-xpack,{xpack} node settings>>.
endif::include-xpack[]

[float]
[[split-brain]]
==== Avoiding split brain with `minimum_master_nodes`

To prevent data loss, it is vital to configure the
`discovery.zen.minimum_master_nodes` setting (which defaults to `1`) so that
each master-eligible node knows the _minimum number of master-eligible nodes_
that must be visible in order to form a cluster.

To explain, imagine that you have a cluster consisting of two master-eligible
nodes. A network failure breaks communication between these two nodes.  Each
node sees one master-eligible node... itself. With `minimum_master_nodes` set
to the default of `1`,  this is sufficient to form a cluster. Each node elects
itself as the new master (thinking that the other master-eligible node has
died) and the result is two clusters, or a _split brain_.  These two nodes
will never rejoin until one node is restarted.  Any data that has been written
to the restarted node will be lost.

Now imagine that you have a cluster with three master-eligible nodes, and
`minimum_master_nodes` set to `2`.  If a network split separates one node from
the other two nodes, the side with one node cannot see enough master-eligible
nodes and will realise that it cannot elect itself as master.  The side with
two nodes will elect a new master (if needed) and continue functioning
correctly.  As soon as the network split is resolved, the single node will
rejoin the cluster and start serving requests again.

This setting should be set to a _quorum_ of master-eligible nodes:

  (master_eligible_nodes / 2) + 1

In other words, if there are three master-eligible nodes, then minimum master
nodes should be set to `(3 / 2) + 1` or `2`:

[source,yaml]
----------------------------
discovery.zen.minimum_master_nodes: 2 <1>
----------------------------
<1> Defaults to `1`.

This setting can also be changed dynamically on a live cluster with the
<<cluster-update-settings,cluster update settings API>>:

[source,js]
----------------------------
PUT _cluster/settings
{
  "transient": {
    "discovery.zen.minimum_master_nodes": 2
  }
}
----------------------------
// CONSOLE
// TEST[catch:/cannot set discovery.zen.minimum_master_nodes to more than the current master nodes/]

TIP: An advantage of splitting the master and data roles between dedicated
nodes is that you can have just three master-eligible nodes and set
`minimum_master_nodes` to `2`. You never have to change this setting, no
matter how many dedicated data nodes you add to the cluster.

[float]
[[data-node]]
=== Data Node

Data nodes hold the shards that contain the documents you have indexed. Data
nodes handle data related operations like CRUD, search, and aggregations.
These operations are I/O-, memory-, and CPU-intensive. It is important to
monitor these resources and to add more data nodes if they are overloaded.

The main benefit of having dedicated data nodes is the separation of the
master and data roles.

To create a dedicated data node, set:

[source,yaml]
-------------------
node.master: false <1>
node.data: true <2>
node.ingest: false <3>
search.remote.connect: false <4>
-------------------
<1> Disable the `node.master` role (enabled by default).
<2> The `node.data` role is enabled by default.
<3> Disable the `node.ingest` role (enabled by default).
<4> Disable cross-cluster search (enabled by default).

ifdef::include-xpack[]
NOTE: These settings apply only when {xpack} is not installed. To create a
dedicated data node when {xpack} is installed, see <<modules-node-xpack,{xpack} node settings>>.
endif::include-xpack[]

[float]
[[node-ingest-node]]
=== Ingest Node

Ingest nodes can execute pre-processing pipelines, composed of one or more
ingest processors. Depending on the type of operations performed by the ingest
processors and the required resources, it may make sense to have dedicated
ingest nodes, that will only perform this specific task.

To create a dedicated ingest node, set:

[source,yaml]
-------------------
node.master: false <1>
node.data: false <2>
node.ingest: true <3>
search.remote.connect: false <4>
-------------------
<1> Disable the `node.master` role (enabled by default).
<2> Disable the `node.data` role (enabled by default).
<3> The `node.ingest` role is enabled by default.
<4> Disable cross-cluster search (enabled by default).

ifdef::include-xpack[]
NOTE: These settings apply only when {xpack} is not installed. To create a
dedicated ingest node when {xpack} is installed, see <<modules-node-xpack,{xpack} node settings>>.
endif::include-xpack[]

[float]
[[coordinating-only-node]]
=== Coordinating only node

If you take away the ability to be able to handle master duties, to hold data,
and pre-process documents, then you are left with a _coordinating_ node that
can only route requests, handle the search reduce phase, and distribute bulk
indexing. Essentially, coordinating only nodes behave as smart load balancers.

Coordinating only nodes can benefit large clusters by offloading the
coordinating node role from data and master-eligible nodes.  They join the
cluster and receive the full <<cluster-state,cluster state>>, like every other
node, and they use the cluster state to route requests directly to the
appropriate place(s).

WARNING: Adding too many coordinating only nodes to a cluster can increase the
burden on the entire cluster because the elected master node must await
acknowledgement of cluster state updates from every node! The benefit of
coordinating only nodes should not be overstated -- data nodes can happily
serve the same purpose.

To create a dedicated coordinating node, set:

[source,yaml]
-------------------
node.master: false <1>
node.data: false <2>
node.ingest: false <3>
search.remote.connect: false <4>
-------------------
<1> Disable the `node.master` role (enabled by default).
<2> Disable the `node.data` role (enabled by default).
<3> Disable the `node.ingest` role (enabled by default).
<4> Disable cross-cluster search (enabled by default).

ifdef::include-xpack[]
NOTE: These settings apply only when {xpack} is not installed. To create a
dedicated coordinating node when {xpack} is installed, see <<modules-node-xpack,{xpack} node settings>>.
endif::include-xpack[]

[float]
== Node data path settings

[float]
[[data-path]]
=== `path.data`

Every data and master-eligible node requires access to a data directory where
shards and index and cluster metadata will be stored. The `path.data` defaults
to `$ES_HOME/data` but can be configured in the `elasticsearch.yml` config
file an absolute path or a path relative to `$ES_HOME` as follows:

[source,yaml]
-----------------------
path.data:  /var/elasticsearch/data
-----------------------

Like all node settings, it can also be specified on the command line as:

[source,sh]
-----------------------
./bin/elasticsearch -Epath.data=/var/elasticsearch/data
-----------------------

TIP: When using the `.zip` or `.tar.gz` distributions, the `path.data` setting
should be configured to locate the data directory outside the Elasticsearch
home directory, so that the home directory can be deleted without deleting
your data! The RPM and Debian distributions do this for you already.

[float]
[[max-local-storage-nodes]]
=== `node.max_local_storage_nodes`

The <<data-path,data path>> can be shared by multiple nodes, even by nodes from different
clusters. This is very useful for testing failover and different configurations on your development
machine. In production, however, it is recommended to run only one node of Elasticsearch per server.

By default, Elasticsearch is configured to prevent more than one node from sharing the same data
path. To allow for more than one node (e.g., on your development machine), use the setting
`node.max_local_storage_nodes` and set this to a positive integer larger than one.

WARNING: Never run different node types (i.e. master, data) from the same data directory. This can
lead to unexpected data loss.

[float]
== Other node settings

More node settings can be found in <<modules,Modules>>.  Of particular note are
the <<cluster.name,`cluster.name`>>, the <<node.name,`node.name`>> and the
<<modules-network,network settings>>.

ifdef::include-xpack[]
:edit_url!:
include::{xes-repo-dir}/node.asciidoc[]
endif::include-xpack[]


KARAF-4415 - Update the documentation about the verify goal