Blog

2016.12.14 - 번역 - State of the official Elasticsearch Java clients ...

drscg 2019. 1. 7. 10:44

Java programmers have two choices when communicating with Elasticsearch: they can use either the REST API over HTTP, or the internal Java API used by Elasticsearch itself for node-to-node communication.

Java programmer는 Elasticsearch와 통신 할 경우, 두 가지 중 하나를 선택을 할 수 있다. HTTP를 통한 REST API 또는 Elasticsearch 자체에서 node 간 통신을 위해 사용하는 내부 Java API를 사용할 수 있다.

So, what's the difference between these two APIs?  When a user sends a REST request to an Elasticsearch node, the coordinating node parses the JSON body and transforms it into its corresponding Java object.  From then on, the request is sent to other nodes in the cluster in a binary format -- the Java API -- using the transport networking layer.  A Java user uses the Transport Client to build these Java objects directly in their application, then makes requests using the same binary format passed across the transport layer, skipping the need for the parsing step needed by REST.

그렇다면, 이 두 API의 차이점은 무엇일까? 사용자가 Elasticsearch node에 REST request를 보내면, coordinating node는 JSON body를 parsing하고, 이를 해당 Java object로 변환한다. 그런 다음, request는 transport networking layer를 사용하여, Java API인 binary format으로, cluster의 다른 node로 전송된다. Java 사용자는 Transport Client를 사용하여, 해당 Java object를 application에서 직접 만든 다음, 동일한 binary format을 사용하는 request를, transport layer 통해, 전달하고, REST가 필요로 하는 parsing 단계를 생략한다.

What are the problems with this approach?

This solution is quite powerful, and didn’t require us to write specific Java client code for Elasticsearch as the Java API was already used and maintained internally. The Java API is also theoretically more performant than REST, as it skips the parsing step and allows clients to use the binary protocol. Benchmarks, however,  show that the performance of the HTTP client is close enough to that of the Transport client that the difference can be pretty much disregarded.

이 솔루션은 매우 강력하며, Java API가 이미 사용되고 내부적으로 유지 관리되어 있으므로, Elasticsearch에 대한 특정 Java client code를 작성할 필요가 없다. Java API는 parsing 단계를 건너 뛰고, client가 binary protocol을 사용할 수 있으므로, 이론적으로 REST보다 성능이 우수하다. 그러나 그러나, benchmark에서는 HTTP client의 성능이 Transport client의 성능과 거의 비슷하여, 차이를 거의 무시할 수 있음을 보여준다.

Over time, we came to realize that the Java API has some downsides:

시간이 지나면서, Java API에 몇 가지 단점이 있다는 것을 알게 되었다.

Backwards compatibility

We are very careful with backwards compatibility on the REST layer where breaking changes are made only in major releases. On the other hand, we make breaking changes to Elasticsearch’s internal classes all the time, which is necessary in order to move the project forward. Those changes result in changes to the binary format, which we compensate for by having version-specific serialization code.  It is this compatibility layer that allows you to do a rolling upgrade of an Elasticsearch cluster.

우리는 major release에서만 변경 내용이 적용되는, REST layer에서 이전 버전과의 호환성에 매우 주의를 기울이고 있다. 반면에, 우리는 프로젝트를 진전시키기 위해 필요한, Elasticsearch의 내부 class를 항상 변경했다. 이러한 변화는 binary format 변경으로 이어지고, version-specific serialization code를 사용하여, 이를 보완한다. 이 이 호환성 계층(compatibility layer)을 사용하여, Elasticsearch cluster를 rolling upgrade할 수 있다.

That said, running a mixed version cluster is something we only recommend during the upgrade process, not as the status quo. Having older versions of nodes or clients in the cluster limits the support of newer features, as the older client simply doesn't know how to write or read requests in the newer binary format.

즉, version이 혼합된 cluster를 실행하는 것은, 현상 유지가 아닌, upgrade 시에만 권장된다. 기존의 client가 새로운 binary format으로 request를 쓰거나 읽는 방법을 모르기 때문에, cluster가 node 또는 client의 기존 version을 갖는 것은 새로운 기능의 지원을 제한한다.

When you upgrade your cluster, you should upgrade all nodes and clients to have the same version. The requirement to upgrade all Java clients makes upgrades harder, because it affects all the applications that communicate with Elasticsearch. And all of those changes we made to the internal Java API?  Your application has to be adapted to cope with them.  Fortunately, Java has a compiler which complains when an interface has changed, so updating your Java app shouldn't be too complicated.  That said it can still be a pain in the neck to do for every upgrade.

cluster를 upgrade할 경우, 모든 node와 client를 동일한 version으로 upgrade해야 한다. 모든 Java client를 upgrade해야 하는 이유는 Elasticsearch와 통신하는 모든 application에 영향을 주기 때문이다. 그리고 내부 Java API에 대한 모든 변경 사항은? application은 그에 맞게 수정되어야 한다.다행스럽게도, Java에는 interface가 변경되었음을 알아차리는 compiler가 있어서, Java application을 update하는 것이 그렇게 복잡하지는 않다. 즉, 모든 것을 upgrade하는 것은 여전히 골치거리가 될 수 있다는 말이다.

The REST interface is much more stable and can be upgraded out of step with the Elasticsearch cluster.

REST interface는 훨씬 더 안정적이며, Elasticsearch cluster와 관계없이 upgrade될 수 있다.

JVM version

We also recommend that the client and the server are on the same Java version. This used to be a strict requirement before Elasticsearch 2.0, when we used Java serialization for exceptions.  These days, having exactly the same Java version probably isn't as important as it used to be, but given how low level the binary format of the Java API is, it is advisable to use the same JVM version on all nodes and clients.

client와 server는 동일한 Java version을 사용하는 것이 좋다. 이는 Elasticsearch 2.0 이전에, exception 처리를 위해  Java serialization을 사용할 경우, 엄격한 요구 사항이었다. 요즘은 정확이 동일한 Java version을 사용하는 것이 예전처럼 중요하지는 않지만, Java API의 binary format이 얼마나 낮은지를 고려하여, 모든 node와 client에서 동일한 JVM version을 사용하는 것이 좋다.

The REST client can use the same version of the JVM that is used by your application.

REST client는 application에서 사용하는 JVM과 동일한 version을 사용할 수 있다.

Dependencies

The Java API is not published as a separate artifact, which means that, your project has to depend on the whole Elasticsearch, including all the server code that is not really needed on the client side. This means you have some strange dependencies like lucene and log4j2, which you may not need in your application, and can actually end up conflicting with libraries that you have in your classpath. This problem has been reduced with the recent removal of the Guava dependency, but it still exists.

Java API는 개별 artifact로 게시되지 않는다. 즉, client 측에서 실제로 필요하지 않은 모든 server code를 포함하여, project가 전체 Elasticsearch에 의존해야 한다. 이는 lucene과 log4j2와 같은 약간은 이상한 dependency를 가지고 있음을 의미한다. 이것은 application에서 필요하지 않을 수도 있으며, 실제로classpath의 library와 충돌 할 수 있다. 이 문제는 최근에 Guava dependency의 제거로 줄어들었지만, 여전히 존재한다.

The low-level REST client today has minimal dependencies: Apache HTTP Async Client and its transitive dependencies (Apache HTTP Client, Apache HTTP Core, Apache HTTP Core NIO, Apache Commons Codec and Apache Commons Logging).

현재 low-level REST client는 최소한의 depency를 가진다: Apache HTTP Async client와 그것의 transitive dependency(Apache HTTP Client, Apache HTTP Core, Apache HTTP Core NIO, Apache Commons Codec and Apache Commons Logging)

Security

Ideally, we would like to have a single entry-point to the cluster for users: the REST API, which can be secured via HTTPS. The transport layer should only be used for internal node-to-node communication. Knowing that users can only enter via the REST layer and not via the transport layer would greatly simplify how we write code, give us more freedom to add new features and also simplify how an Elasticsearch cluster can be secured.

이상적으로는, 사용자를 위해 cluster에 대한 single entry-point(HTTPS를 통해 보안될 수 있는 REST API)을를 원한다. transport layer는 내부 node 간 통신에만 사용되어야 한다. 사용자가 transport layer을 통하지 않고 REST layer을 통해서만 진입할 수 있다는 것을 알면, code를 작성하는 방법이 크게 단순해지고, 새로운 기능을 추가가 자유로워지고, Elasticsearch cluster의 보안을 단순화할 수 있다.

We reached the point where the disadvantages of the java API outweighed the main benefit, which is not having to write and maintain a separate client.

Java API의 단점이, 별도의 client를 작성하고 유지관리 할 필요가 없는, 주요 이점을 능가하는 수준에 도달했습니다.

Low-level Java REST client

This is why we released our first Java REST Client with version 5.0.0. It was the first step towards making the Java client work in the same way as all the other language clients. The first release only included what we call a low-level client, which has the following features:

이것이 5.0.0 version과 함께 첫 번째 Java REST Client를 발표 한 이유이다. Java client를 다른 모든 언어의 client와 동일한 방식으로 만드는 첫 번째 단계였다. 첫 번째 release에는 다음과 같은 기능을 가진, low-level client라 불리는 것만 포함되었다.

  • compatibility with any Elasticsearch version
    모든 Elastic version과의 호환성
  • load balancing across all available nodes
    모든 이용 가능한 node에 대한 load balancing
  • failover in case of node failures and upon specific response codes
    node 장애와 특정 response code에 대한 failover
  • failed connection penalization
    연결 장애 penalization
  • persistent connections
    지속적인 연결
  • trace logging of requests and responses
    request와 response에 대한 trace logging
  • optional automatic discovery of cluster nodes (also known as sniffing)
    cluster node에 대한 선택적인 자동 감지(sniffing이라 함)

The documentation is available here.

document는 여기에서 볼 수 있다.

It is called the low-level client because it does little to help the Java users to build requests or to parse responses. It handles path and query-string construction for requests,  but it treats JSON request and response bodies as opaque byte arrays which have to be handled by the user.

Java 사용자가 request를 작성하거나 response를 parsing하는 데 도움이 되지 않기 때문에, low-level client라 한다. request에 대한 path 및 query-string 생성을 처리하지만, JSON request 및 response body는, 사용자가 처리해야 하는, 분명하지 않는 byte array로 취급한다.

The next step is releasing a high level client that accepts proper request objects,  takes care of their marshalling, and  returns parsed response objects. We’ve been considering a few different approaches on how to get there. We thought about starting from scratch: having a client with minimal dependencies with its own requests and responses. That would be a nice green field project to work on, but it would require a big effort and make migrating applications from the Java API quite a headache.

다음 단계는 적절한 request object를 받아들이고, marshalling을 처리하며, parsing된 response object를 반환하는, high level client를 발표하는 것이다. 이를 위해 몇 가지 다양한 방식을 고려했다. 우리는 처음부터 시작하는 것에 대해 생각했다. client가 자신의 request 및 response와 최소한의 dependency를 갖는 것이다. 멋진 프로젝트가 되겠지만, 많은 노력이 필요하고, Java API에서 application을 migration하는 것은 상당히 어려울 질이다.

We decided against this especially as this approach would considerably delay the first release of the high level REST client. Instead, the initial version of the high level Java REST client will still depend on Elasticsearch, like the Java API does today. This will allow us to reuse the existing Java API requests and responses, which will ease migration for users.

특히 이 방식이 high level REST client의 첫번째 release를 상당히 지연시킬 것이기 때문에, 이에 대해 반대로 결정했습니다. 대신, high level REST client의 초기 버전은 Java API가 현재 하는 것처럼, 여전히 Elasticsearch에 의존한다. 이렇게 하면, 기존의 Java API request와 response를 재사용할 수 있으므로 ,사용자의 migration이 쉬워진다.

We will not implement the existing Client interface though - we have plans to improve this interface, so client calls in your application will need to be migrated, but requests and responses should stay exactly the same as today. The first release will not support all the APIs but we are planning to support the most important ones to start with: index, bulk, get, delete and search.

그러나, 기존의 Client interface를 구현하지는 않을 것입니다. 이 interface를 개선 할 계획이 있으므로, application의 client 호출을 migration해야 하지만, request와 reponse는 현재와 정확히 동일하게 유지되어야한다. 첫 번째 release가 모든 API를 지원하지는 않지만, index, bulk, get, delete 및 search 부터 시작하여, 가장 중요한 API를 지원할 계획이다.

The Java REST client is the future for Java users of Elasticsearch. Please get involved and try out the high-level client as soon as it becomes available, as your feedback will help us to make it better faster. As soon as the REST client is feature complete and is mature enough to replace the Java API entirely, we will deprecate and finally remove the transport client and the Java API.

Java REST client는 Elasticsearch Java 사용자를 위한 기능이다. 여러분의 의견은 우리가 더 빨리 개선하는 데 도움이 되므로, 가능한 한 빨리 참여하여 high-level client를 사용해 보자. REST client의 기능이 완료되고, Java API를 완전히 대체할 수 있게 되자마자, transport client와 Java API는 deprecate되고, 마지막에 제거할 것이다.

원문 : State of the official Elasticsearch Java clients