- .NET Clients: other versions:
- Introduction
- Breaking changes
- API Conventions
- Elasticsearch.Net - Low level client
- NEST - High level client
- Troubleshooting
- Search
- Query DSL
- Full text queries
- Term level queries
- Exists Query Usage
- Fuzzy Date Query Usage
- Fuzzy Numeric Query Usage
- Fuzzy Query Usage
- Ids Query Usage
- Prefix Query Usage
- Date Range Query Usage
- Numeric Range Query Usage
- Term Range Query Usage
- Regexp Query Usage
- Term Query Usage
- Terms List Query Usage
- Terms Lookup Query Usage
- Terms Query Usage
- Type Query Usage
- Wildcard Query Usage
- Compound queries
- Joining queries
- Geo queries
- Geo Bounding Box Query Usage
- Geo Distance Query Usage
- Geo Distance Range Query Usage
- Geo Hash Cell Query Usage
- Geo Polygon Query Usage
- Geo Shape Circle Query Usage
- Geo Shape Envelope Query Usage
- Geo Shape Geometry Collection Query Usage
- Geo Shape Indexed Shape Query Usage
- Geo Shape Line String Query Usage
- Geo Shape Multi Line String Query Usage
- Geo Shape Multi Point Query Usage
- Geo Shape Multi Polygon Query Usage
- Geo Shape Point Query Usage
- Geo Shape Polygon Query Usage
- Specialized queries
- Span queries
- NEST specific queries
- Aggregations
- Metric Aggregations
- Average Aggregation Usage
- Cardinality Aggregation Usage
- Extended Stats Aggregation Usage
- Geo Bounds Aggregation Usage
- Geo Centroid Aggregation Usage
- Max Aggregation Usage
- Min Aggregation Usage
- Percentile Ranks Aggregation Usage
- Percentiles Aggregation Usage
- Scripted Metric Aggregation Usage
- Stats Aggregation Usage
- Sum Aggregation Usage
- Top Hits Aggregation Usage
- Value Count Aggregation Usage
- Bucket Aggregations
- Adjacency Matrix Usage
- Children Aggregation Usage
- Date Histogram Aggregation Usage
- Date Range Aggregation Usage
- Filter Aggregation Usage
- Filters Aggregation Usage
- Geo Distance Aggregation Usage
- Geo Hash Grid Aggregation Usage
- Global Aggregation Usage
- Histogram Aggregation Usage
- Ip Range Aggregation Usage
- Missing Aggregation Usage
- Nested Aggregation Usage
- Range Aggregation Usage
- Reverse Nested Aggregation Usage
- Sampler Aggregation Usage
- Significant Terms Aggregation Usage
- Terms Aggregation Usage
- Pipeline Aggregations
- Average Bucket Aggregation Usage
- Bucket Script Aggregation Usage
- Bucket Selector Aggregation Usage
- Cumulative Sum Aggregation Usage
- Derivative Aggregation Usage
- Extended Stats Bucket Aggregation Usage
- Max Bucket Aggregation Usage
- Min Bucket Aggregation Usage
- Moving Average Ewma Aggregation Usage
- Moving Average Holt Linear Aggregation Usage
- Moving Average Holt Winters Aggregation Usage
- Moving Average Linear Aggregation Usage
- Moving Average Simple Aggregation Usage
- Percentiles Bucket Aggregation Usage
- Serial Differencing Aggregation Usage
- Stats Bucket Aggregation Usage
- Sum Bucket Aggregation Usage
- Matrix Aggregations
- Metric Aggregations
WARNING: Version 5.x has passed its EOL date.
This documentation is no longer being maintained and may be removed. If you are running this version, we strongly advise you to upgrade. For the latest information, see the current release documentation.
Round robin behaviour
editRound robin behaviour
editSniffing and Static connection pools
round robin over the live
nodes to evenly distribute requests over all known nodes.
CreateView
editThis is the method on an IConnectionPool
that creates a view of all the live nodes in the cluster that the client
knows about. Different connection pool implementations can decide on the view to return, for example,
-
SingleNodeConnectionPool
is only ever seeded with and hence only knows about one node -
StickyConnectionPool
can return a view of live nodes with the same starting position as the last live node a request was made against -
SniffingConnectionPool
returns a view with a changing starting position that wraps over on each call
CreateView
is implemented in a lock free thread safe fashion, meaning each callee gets returned
its own cursor to advance over the internal list of nodes. This to guarantee each request that needs to
fall over tries all the nodes without suffering from noisy neighbours advancing a global cursor.
Here we have setup a Static connection pool seeded with 10 nodes. We force randomization OnStartup to false so that we can test the nodes being returned are in the order we expect them to be.
var uris = Enumerable.Range(9200, NumberOfNodes).Select(p => new Uri("http://localhost:" + p)); var staticPool = new StaticConnectionPool(uris, randomize: false); var sniffingPool = new SniffingConnectionPool(uris, randomize: false); this.AssertCreateView(staticPool); this.AssertCreateView(sniffingPool);
So what order do we expect? Imagine the following:
-
Thread A calls
CreateView()
first without a local cursor and takes the current value from the internal global cursor, which is0
-
Thread B calls
CreateView()
second without a local cursor and therefore starts at1
- After this, each thread should walk the nodes in successive order using their local cursor. For example, Thread A might get 0,1,2,3,5 and thread B will get 1,2,3,4,0.
var startingPositions = Enumerable.Range(0, NumberOfNodes) .Select(i => pool.CreateView().First()) .Select(n => n.Uri.Port) .ToList(); var expectedOrder = Enumerable.Range(9200, NumberOfNodes); startingPositions.Should().ContainInOrder(expectedOrder);
What the above code just proved is that each call to CreateView()
gets assigned the next available node.
Lets up the ante:
-
Call
CreateView()
overNumberOfNodes * 2
threads -
On each thread, call
CreateView()
NumberOfNodes * 10
times using a local cursor.
We’ll validate that each thread sees all the nodes and that they wrap over, for example, after node 9209 comes 9200 again
var threadedStartPositions = new ConcurrentBag<int>(); var threads = Enumerable.Range(0, 20) .Select(i => CreateThreadCallingCreateView(pool, threadedStartPositions)) .ToList(); foreach (var t in threads) t.Start(); foreach (var t in threads) t.Join();
Each thread reported the first node it started off. Let’s make sure we see each node twice
because we started NumberOfNodes * 2
threads
var grouped = threadedStartPositions.GroupBy(p => p).ToList(); grouped.Count.Should().Be(NumberOfNodes); grouped.Select(p => p.Count()).Should().OnlyContain(p => p == 2);
On this page