'GET'에 해당되는 글 4건

  1. 2018.05.09 [Elasticsearch] GET API 에 대해서
  2. 2013.04.16 [elasticsearch] Core API - Get/Multi Get/Update
  3. 2013.04.09 [elasticsearch] Java API : Get
  4. 2007.04.18 [HTTP Method] post vs get

[Elasticsearch] GET API 에 대해서

Elastic/Elasticsearch 2018.05.09 14:22

평소 Get API 에 대해서 설명을 할 때 document id 로 lookup 을 하기 때문에 모든 shard 로 request 를 보내지 않아 빠르다고 설명을 했습니다.

이 과정에서 놓치기 쉬운 부분이 있는데 기본적으로 Get API 는 realtime  동작을 합니다.

즉, refresh 동작과 상관 없이 기본적으로 최신 정보를 가져오게 되는 것입니다.


다시 말해, 내부적으로 refresh 동작을 수행한다는 의미가 됩니다.

그래서 Get API 에서는 realtime 이라는 변수를 통해서 realtime Get 을 사용 할 것인지 말 것인지를 정의 할 수 있습니다.


아래는 위 설명을 이해 하는데 도움을 주기 위해서 소스 코드의 일부를 발췌 하였습니다.


[GetRequest.java]

private boolean refresh = false;

boolean realtime = true;
/**
* Should a refresh be executed before this get operation causing the operation to
* return the latest value. Note, heavy get should not set this to {@code true}. Defaults
* to {@code false}.
*/
public GetRequest refresh(boolean refresh) {
this.refresh = refresh;
return this;
}

public boolean refresh() {
return this.refresh;
}

public boolean realtime() {
return this.realtime;
}

@Override
public GetRequest realtime(boolean realtime) {
this.realtime = realtime;
return this;
}


[RestGetAction.java]

@Override
public RestChannelConsumer prepareRequest(final RestRequest request, final NodeClient client) throws IOException {
final boolean includeTypeName = request.paramAsBoolean("include_type_name", true);
final String type = request.param("type");
if (includeTypeName == false && MapperService.SINGLE_MAPPING_NAME.equals(type) == false) {
throw new IllegalArgumentException("You may only use the [include_type_name=false] option with the get APIs with the " +
"[{index}/_doc/{id}] endpoint.");
}
final GetRequest getRequest = new GetRequest(request.param("index"), type, request.param("id"));
getRequest.refresh(request.paramAsBoolean("refresh", getRequest.refresh()));
getRequest.routing(request.param("routing"));
getRequest.preference(request.param("preference"));
getRequest.realtime(request.paramAsBoolean("realtime", getRequest.realtime()));
if (request.param("fields") != null) {
throw new IllegalArgumentException("the parameter [fields] is no longer supported, " +
"please use [stored_fields] to retrieve stored fields or [_source] to load the field from _source");
}
final String fieldsParam = request.param("stored_fields");
if (fieldsParam != null) {
final String[] fields = Strings.splitStringByCommaToArray(fieldsParam);
if (fields != null) {
getRequest.storedFields(fields);
}
}

getRequest.version(RestActions.parseVersion(request));
getRequest.versionType(VersionType.fromString(request.param("version_type"), getRequest.versionType()));

getRequest.fetchSourceContext(FetchSourceContext.parseFromRestRequest(request));

return channel -> client.get(getRequest, new RestToXContentListener<GetResponse>(channel) {
@Override
protected RestStatus getStatus(final GetResponse response) {
return response.isExists() ? OK : NOT_FOUND;
}
});
}


[TransportGetAction.java]

@Override
protected void asyncShardOperation(GetRequest request, ShardId shardId, ActionListener<GetResponse> listener) throws IOException {
IndexService indexService = indicesService.indexServiceSafe(shardId.getIndex());
IndexShard indexShard = indexService.getShard(shardId.id());
if (request.realtime()) { // we are not tied to a refresh cycle here anyway
listener.onResponse(shardOperation(request, shardId));
} else {
indexShard.awaitShardSearchActive(b -> {
try {
super.asyncShardOperation(request, shardId, listener);
} catch (Exception ex) {
listener.onFailure(ex);
}
});
}
}

@Override
protected GetResponse shardOperation(GetRequest request, ShardId shardId) {
IndexService indexService = indicesService.indexServiceSafe(shardId.getIndex());
IndexShard indexShard = indexService.getShard(shardId.id());

if (request.refresh() && !request.realtime()) {
indexShard.refresh("refresh_flag_get");
}

GetResult result = indexShard.getService().get(request.type(), request.id(), request.storedFields(),
request.realtime(), request.version(), request.versionType(), request.fetchSourceContext());
return new GetResponse(result);
}

보시면 아시겠지만 refresh 와 realtime 의 동작에는 차이가 있습니다.

이해 하기 쉽게 정리 하면,

- refresh 는 get 수행 전에 relevant shard 를 대상으로 refresh 동작을 먼저 하기 때문에 성능 저하가 있을 수 있습니다.

- realtime 은 수행 시점에 refresh 동작을 수행 하게 됩니다. (이 경우 refresh searcher 의 대상은 internal searcher 가 됩니다.)

- 여기서 translog 에서 데이터를 읽어야 하는 경우가 있는데 이 경우는 update API 에서 사용 되게 됩니다.


[InternalEngine.java]

@Override
public GetResult get(Get get, BiFunction<String, SearcherScope, Searcher> searcherFactory) throws EngineException {
assert Objects.equals(get.uid().field(), IdFieldMapper.NAME) : get.uid().field();
try (ReleasableLock ignored = readLock.acquire()) {
ensureOpen();
SearcherScope scope;
if (get.realtime()) {
VersionValue versionValue = null;
try (Releasable ignore = versionMap.acquireLock(get.uid().bytes())) {
// we need to lock here to access the version map to do this truly in RT
versionValue = getVersionFromMap(get.uid().bytes());
}
if (versionValue != null) {
if (versionValue.isDelete()) {
return GetResult.NOT_EXISTS;
}
if (get.versionType().isVersionConflictForReads(versionValue.version, get.version())) {
throw new VersionConflictEngineException(shardId, get.type(), get.id(),
get.versionType().explainConflictForReads(versionValue.version, get.version()));
}
if (get.isReadFromTranslog()) {
// this is only used for updates - API _GET calls will always read form a reader for consistency
// the update call doesn't need the consistency since it's source only + _parent but parent can go away in 7.0
if (versionValue.getLocation() != null) {
try {
Translog.Operation operation = translog.readOperation(versionValue.getLocation());
if (operation != null) {
// in the case of a already pruned translog generation we might get null here - yet very unlikely
TranslogLeafReader reader = new TranslogLeafReader((Translog.Index) operation, engineConfig
.getIndexSettings().getIndexVersionCreated());
return new GetResult(new Searcher("realtime_get", new IndexSearcher(reader)),
new VersionsAndSeqNoResolver.DocIdAndVersion(0, ((Translog.Index) operation).version(), reader, 0));
}
} catch (IOException e) {
maybeFailEngine("realtime_get", e); // lets check if the translog has failed with a tragic event
throw new EngineException(shardId, "failed to read operation from translog", e);
}
} else {
trackTranslogLocation.set(true);
}
}
refresh("realtime_get", SearcherScope.INTERNAL);
}
scope = SearcherScope.INTERNAL;
} else {
// we expose what has been externally expose in a point in time snapshot via an explicit refresh
scope = SearcherScope.EXTERNAL;
}

// no version, get the version from the index, we know that we refresh on flush
return getFromSearcher(get, searcherFactory, scope);
}
}


[코드의 이해]

RestGetAction -> TransportGetAction (TransportSingleShardAction) -> IndexShard ->

ShardGetService -> InternalEngine (Engine) -> SearcherManager(ReferenceManager)


Trackback 0 : Comment 0

[elasticsearch] Core API - Get/Multi Get/Update

Elastic/Elasticsearch 2013.04.16 15:22

본 문서는 개인적인 테스트와 elasticsearch.org 그리고 community 등을 참고해서 작성된 것이며,

정보 교환이 목적입니다.


잘못된 부분에 대해서는 지적 부탁 드립니다.

(예시 코드는 성능 및 보안 검증이 되지 않았습니다.)



[elasticsearch 리뷰]

원문 링크

http://www.elasticsearch.org/guide/reference/api/get.html

http://www.elasticsearch.org/guide/reference/api/multi-get.html

http://www.elasticsearch.org/guide/reference/api/update.html


위 3개의 API 들은 Java API 를 참고하는게 더 좋습니다.

기본  Core API 에서 보여 주고 있는 예제는 REST API 로 kimchy 가 추천하는 방식과는 조금 다른 예제로 보여 주기 위한 목적이 강하다는 판단 입니다.


kimchy 의 추천은 Native Java API 를 사용할 것을 추천 합니다.

Trackback 0 : Comment 0

[elasticsearch] Java API : Get

Elastic/Elasticsearch 2013.04.09 12:25

본 문서는 개인적인 테스트와 elasticsearch.org 그리고 community 등을 참고해서 작성된 것이며,

정보 교환이 목적입니다.


잘못된 부분에 대해서는 지적 부탁 드립니다.

(예시 코드는 성능 및 보안 검증이 되지 않았습니다.)



[elasticsearch java api 리뷰]

원문 링크 : http://www.elasticsearch.org/guide/reference/java-api/get/


- 이 API는 index 의 id(_id) 를 기반으로 json 형식의 문서를 구할 수 있습니다.


예제는 아래 문서에서 생성한 데이터로 테스트 합니다.

http://jjeong.tistory.com/792


GetResponse response = client.prepareGet("facebook", "post", "2")

        .execute()

        .actionGet();

log.debug("{}", response.getId());

log.debug("{}", response.getSource());


response = client.prepareGet("facebook", "post", "1")

        .setOperationThreaded(false)

        .execute()

        .actionGet();

log.debug("{}", response.getId());

log.debug("{}", response.getSource());

- 보시면 매우 간단 합니다.

- REST URL 방식으로 고치면 http://localhost:9200/facebook/post/2 와 같은 형식을 갖습니다.


좀 더 자사한 내용은 아래 링크 참고 바랍니다.

http://www.elasticsearch.org/guide/reference/api/get/


[.setOperationThreaded 옵션]

- 이 옵션의 기본 값은 true 로 설정이 되어 있습니다.

- operation 에 대한 threading model 을 지원.

- 설명이 어려워서 일단 쉽게 이해를 돕기 위해 소스코드를 좀 봅시다.


[SearchOperationThreading.java]

    /**

     * No threads are used, all the local shards operations will be performed on the calling

     * thread.

     */

    NO_THREADS((byte) 0),

    /**

     * The local shards operations will be performed in serial manner on a single forked thread.

     */

    SINGLE_THREAD((byte) 1),

    /**

     * Each local shard operation will execute on its own thread.

     */

    THREAD_PER_SHARD((byte) 2);


[ThreadingModel.java]

    NONE((byte) 0),

    OPERATION((byte) 1),

    LISTENER((byte) 2),

    OPERATION_LISTENER((byte) 3);


    /**

     * <tt>true</tt> if the actual operation the action represents will be executed

     * on a different thread than the calling thread (assuming it will be executed

     * on the same node).

     */

    public boolean threadedOperation() {

        return this == OPERATION || this == OPERATION_LISTENER;

    }


    /**

     * <tt>true</tt> if the invocation of the action result listener will be executed

     * on a different thread (than the calling thread or an "expensive" thread, like the

     * IO thread).

     */

    public boolean threadedListener() {

        return this == LISTENER || this == OPERATION_LISTENER;

    }


- 주석을 보시면 이해가 되시죠?

- 즉 false이면 자긴껀 자기가 실행 하고, true 이면 thread 를 fork 해서 넘겨준다고 보면 되겠내요.


※ 커뮤니티에 올라와 있는 것들을 보면 아래와 같이 사용하는걸 권장 하는 것 같습니다.

- read operation : setThreadOperation(true) // 즉 선언 하지 않아도 되구요.

- insert/update/delete operation : setThreadOperation(false)


Trackback 0 : Comment 0

[HTTP Method] post vs get

ITWeb/스크랩 2007.04.18 13:17

누가 http method 중 post 와 get 의 차이점이 무엇인지 물어 보더라구요.
인터넷개론에서 배웠던것 같은데 지금은 실무를 하면서 개념적으로 이해를 하면서 사용을 하다 보니 명확하게 이론적으로 설명을 잘 못해 주겠더라구요..

그래서 찾아 봤습니다.. ^^;

ref. http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html

get 과 post 만.. 간단히 설명 드리겠습니다.

- get method
    이 메서드는 form 에 포함되어 있는 entity 즉 request uri 에 의해서 전달이 되어 집니다.
    더 쉽게 얘기 하자면 query string 으로 해서 data 가 전달되는 형식 입니다.
    그냥 plain/text 로 전달되는게 아니고 application/x-www-form-urlencoded 되어 전달 됩니다.

- post method
    이 메서드는 get 방식과 틀리게 body 를 통해서 전달이 되게 됩니다.
    쉽게 얘기 해서 눈으로 봐서는 어떤 data 가 오고 가는지 확인이 힘들죠.
    body 패킷을 분석하게 되면 알수가 있게 됩니다.
   
추가적으로 보안과 관련된 내용인데요.
중요한 정보에 대해서는 get 을 사용하지 말고 post 를 사용하라고 되어 있습니다.
ref. http://www.w3.org/Protocols/rfc2616/rfc2616-sec15.html#sec15.1.3
왜 그런지는 아시죠!!
get 보다는 안전 하지만 역시 body 의 패킷을 분석하면 다 알수 있기 때문에 하나의 guideline 이라고 보시면 좋을것 같습니다.
(보안에 민감한 내용들은.. SSL 을 사용하기를 권장하구요 ^^* https:// 말이죠.. )

tags : GET, HTTP, POST
Trackback 0 : Comment 0