Slide 1

Slide 1 text

All About Elasticsearch Language Clients Honza Král Karel Minařík Zachary Tong

Slide 2

Slide 2 text

The motivation, the design process and the architecture behind the official clients for Elasticsearch.

Slide 3

Slide 3 text

{ } The Motivation Clients are part of the experience Fragmentation and inconsistency Solving the same problems over and over again Lack of support for the full breadth of Elasticsearch's APIs Different assumptions about exposing the APIs

Slide 4

Slide 4 text

{ } Exhibit A: The Tire client for Ruby Incomplete support for query and filter types Mixing together a Ruby API and Rails integration Still widely used and liked

Slide 5

Slide 5 text

{ } Design Principles “Nobody should have a reason to not use the client” We have no opinions Respect the language

Slide 6

Slide 6 text

{ } The Groundwork The specification of the Elasticsearch REST API The common integration test suite

Slide 7

Slide 7 text

{ } The REST API Specification Describes the HTTP methods, the URL parts, allowed parameters, documentation links for every API Now part of the core Elasticsearch repository A communication tool

Slide 8

Slide 8 text

{ "index": { "documentation": "http://www.elasticsearch.org/guide/en/elasticsearch/reference/ "methods": ["POST", "PUT"], "url": { "path": "/{index}/{type}", "paths": ["/{index}/{type}", "/{index}/{type}/{id}"], "parts": { "id": { "type" : "string", "description" : "Document ID" }, "index": { "type" : "string", "required" : true, "description" : "The name of the index" }, "type": { https://github.com/elasticsearch/elasticsearch/blob/master/rest-api-spec/api/index.json

Slide 9

Slide 9 text

{ } client.index index: 'my_index', type: 'my_type', id: '1', body: { title: 'Hello World!' } Ruby

Slide 10

Slide 10 text

{ } client.index( index='my_index', doc_type='my_type', id=1, body={'title':'Hello World!'} ) Python

Slide 11

Slide 11 text

{ } $client->index([ 'index' => 'my_index', 'type' => 'my_type', 'id' => 1, 'body' => [ 'title' => 'Hello World!' ] ]); PHP

Slide 12

Slide 12 text

{ } $client->index( index => 'my_index', type => 'my_type', id => 1, body => { title => "Hello World!" } ); Perl

Slide 13

Slide 13 text

{ } client.index({ index: 'myindex', type: 'mytype', id: '1', body: { title: 'Hello World!' } }) .then(function (response) { //... }) .catch(function (error) { //... }); JavaScript

Slide 14

Slide 14 text

{ } client.Index("my_index", "my_type", "1", new { title = "Hello World!" } ); C#

Slide 15

Slide 15 text

{ } Namespaced APIs Logical groups for the API client.cluster.health client->cluster->health() client.indices.create client->indices->create()

Slide 16

Slide 16 text

{ } The Common Integration Test Suite Verification of the specification “contract” YAML-based notation xUnit concepts, tailored to use-case “Runners” implemented in client languages Core developers contribute the tests Continuous integration

Slide 17

Slide 17 text

setup: - do: index: index: test type: test id: testing_document body: body: Amsterdam meetup - do: indices.refresh: {} --- "Basic tests for suggest API": - do: suggest: body: test_suggestion: text: "The Amsterdma meetpu" term: field: body - match: {test_suggestion.1.options.0.text: amsterdam} https://github.com/elasticsearch/elasticsearch/blob/master/rest-api-spec/test/suggest/10_basic.yaml

Slide 18

Slide 18 text

{ } The Implementation Sketch Ruby and Python “Enough differences” to notice language peculiarities Working in parallel Blueprint for all languages

Slide 19

Slide 19 text

{ } The Implementation Sketch Focus on functionality and naming, not abstractions Easy to change and reason about Working code — no room for elaborate diagrams, endless speculation or abstract discussions

Slide 20

Slide 20 text

CONNECTION CONNECTION HTTP LIBRARY 3 HTTP LIBRARY 2 … CLIENT High Level Architecture TRANSPORT CONNECTION POOL SELECTOR CONNECTION RANDOM ROUND ROBIN SNIFFER HTTP LIBRARY 1

Slide 21

Slide 21 text

{ } Tracer client = Elasticsearch::Client.new trace: true client.index index: 'my_index', type: 'my_type', id: '1', body: { title: 'Hello World!' } curl -X PUT 'http://localhost:9200/my_index/my_type/1?pretty' -d '{ "title":"Hello World!" }' # 2015-03-10T07:55:37-07:00 [201] (0.270s) # # { # "_index":"my_index", # "_type":"my_type", # "_id":"1", # "_version":1, # "created":true # # }

Slide 22

Slide 22 text

{ } Selector Customization for different cluster topologies The “local rack” selector “Sticky sessions“ in PHP

Slide 23

Slide 23 text

{ } current]->isAlive()) { return $connections[$this->current]; } $this->currentCounter += 1; $this->current = $this->currentCounter % count($connections); return $connections[$this->current]; } } ?> https://github.com/elasticsearch/elasticsearch-php/blob/master/src/Elasticsearch/ConnectionPool/Selectors/StickyRoundRobinSelector.php

Slide 24

Slide 24 text

{ } Sniffer Make use of the Elasticsearch's dynamic nature Reuse the cluster state information Add and remove nodes dynamically Reload nodes list on failure or periodically

Slide 25

Slide 25 text

{ } from elasticsearch import Elasticsearch es = Elasticsearch( # sniff before doing anything sniff_on_start=True, # refresh nodes after a node fails to respond sniff_on_connection_fail=True, # and also every 60 seconds sniffer_timeout=60 ) https://www.elastic.co/webinars/the-why-and-what-about-python

Slide 26

Slide 26 text

{ } randomize_hosts By default, the client round-robins across the node list Prevent the “sequential load” effect in multi-process/ threaded environment Why not [host1, host2].shuffle ? Educate users about this fact and increase usability

Slide 27

Slide 27 text

An Elasticsearch client is much more than “just HTTP and JSON” wrapper

Slide 28

Slide 28 text

“Nobody should have a reason to not use the client”

Slide 29

Slide 29 text

{ } Thank you! Questions!

Slide 30

Slide 30 text

This work is licensed under the Creative Commons To view a copy of this license, visit: http://creativecommons.org/licenses/by-nd/4.0/ or send a letter to: Creative Commons PO Box 1866 Mountain View, CA 94042 USA