'Elastic'에 해당되는 글 498건

  1. 2013.12.16 [Elasticsearch] shard reroute 하기..
  2. 2013.12.09 elasticsearch-hadoop 기능 테스트.
  3. 2013.12.06 queryWeight, queryNorm, fieldWeight, fieldNorm
  4. 2013.11.13 [elasticsearch] unassinged shard reroute...
  5. 2013.10.23 [Elasticsearch] logging.yml appender 추가 하기.
  6. 2013.10.11 [Lucene] score 계산식 알아보기.
  7. 2013.09.24 [Elasticsearch] join 기능 구현은 어떻게?
  8. 2013.09.23 [Elasticsearch] node.local or node.mode .... 2
  9. 2013.09.17 [Elasticsearch] Bulk Indexing 후 Data Consistency 관리.
  10. 2013.09.16 [elasticsearch] Java API : Bulk

[Elasticsearch] shard reroute 하기..

Elastic/Elasticsearch 2013. 12. 16. 17:04

간혹 elasticsearch 가 비정상 종료 되거나 했을 경우 unassigned shard 가 남는 경우가 있습니다.

이럴 경우 아래와 같이 재할당을 할 수 있는데요.

운영 하실 때 참고 하면 좋습니다.

[shard_reroute.sh]

#!/bin/bash

size=$#

if [ $size -ne 2 ]; then
    echo "Usage: shard.sh INDICE_NAME SHARD_NUMBER";
    echo "Example: shard.sh products 1";
    exit 0;
fi

indice=$1
shard=$2

echo "curl -XPOST http://localhost:9200/_cluster/reroute -d '{ "commands" : [ { "allocate" : { "index" : \"$indice\", "shard" : $shard, "node" : "node1", "allow_primary" : true } } ] }'"
echo ""
curl -XPOST http://localhost:9200/_cluster/reroute -d '{ "commands" : [ { "allocate" : { "index" : "'$indice'", "shard" : '$shard', "node" : "node1", "allow_primary" : true } } ] }'

[Reference URL]

http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/cluster-reroute.html

:

elasticsearch-hadoop 기능 테스트.

Elastic/Elasticsearch 2013. 12. 9. 17:54

[프로젝트]

https://github.com/elasticsearch/elasticsearch-hadoop


[소개]

http://www.elasticsearch.org/guide/en/elasticsearch/hadoop/current/requirements.html


hadoop 이랑 연동 하기 위해서 위 프로젝트를 테스트 하였습니다.

정말 예전에 나왔던것 보다 많이 좋아졌내요.


간략하게 정리 하면 hdfs 에 저장되어 있는 데이터를 elasticsearch 로 migration 하는 거라고 보시면 됩니다.

당연한 이야기 입니다만, es 로 데이터가 들어 가기 때문에 당연히 검색도 되겠죠.


저 같은 경우는 mapreducer 와 hive 를 까지만 테스트 하였는데요.

기능 동작 잘되고 활용할 부분이 많을 듯 싶내요.

어떻게 활용할지는 아래 링크 참고 하시면 좋을 듯 합니다.

http://hortonworks.com/blog/fast-search-and-analytics-on-hadoop-with-elasticsearch-and-hdp/


Use Cases

Here are just some of the use case results from Elasticsearch:

  • Perform real-time analysis of 200 million conversations across the social web each day helping major brands make business decisions based on social data
  • Run marketing campaigns that quickly identify the right key influencers from a database of 400 million users
  • Provide real-time search results from an index of over 10 billion documents
  • Power intelligent search and better inform recommendations to millions of customers a month
  • Increase the speed of searches by 1000 times
  • Instant search for 100,000 source code repositories containing tens of billions lines of code

위 그림에서만 보면 호튼웍스가 꼭 끼어야 할 것 처럼 보이지만 뭐 없어도 됩니다.

그냥 hadoop + elasticsearch 로 활용 하시면 되니까.. 잘 만들어 쓰시면 좋겠내요.


실제 제가 참고한 코드는

[MapReducer]

http://www.elasticsearch.org/guide/en/elasticsearch/hadoop/current/mapreduce.html


[Hive]

http://www.elasticsearch.org/guide/en/elasticsearch/hadoop/current/hive.html

이렇습니다.


[SW Version]

hadoop 1.2.1

hive 0.12.0

elasticsearch-hadoop-1.3.0-SNAMSHOP





:

queryWeight, queryNorm, fieldWeight, fieldNorm

Elastic/Elasticsearch 2013. 12. 6. 10:55

reference : http://grokbase.com/t/lucene/solr-user/12cdvgz48t/score-calculation

queryWeight = the impact of the query against the field
implementation: boost(query)*idf*queryNorm


boost(query) = boost of the field at query-time
Implication: hits in fields with higher boost get a higher score
Rationale: a term in field A could be more relevant than the same term in field B


idf = inverse document frequency = measure of how often the term appears across the index for this field
implementation: log(numDocs/(docFreq+1))+1
Implication: the greater the occurrence of a term in different documents, the lower its score
Rationale: common terms are less important than uncommon ones
numDocs = the total number of documents in the index, not including those that are marked as deleted but have not yet been purged. This is a constant (the same value for all documents in the index).
docFreq = the number of documents in the index which contain the term in this field. This is a constant (the same value for all documents in the index containing this field)


queryNorm = normalization factor so that queries can be compared
implementation: 1/sqrt(sumOfSquaredWeights)
Implication: doesn't impact the relevancy of this result
Rationale: queryNorm is not related to the relevance of the document, but rather tries to make scores between different queries comparable. This value is equal for all results of the query


fieldWeight = the score of a term matching the field
implementation: tf*idf*fieldNorm


tf = term frequency in a field = measure of how often a term appears in the field
implementation: sqrt(freq)
Implication: the more frequent a term occurs in a field, the greater its score
Rationale: fields which contains more of a term are generally more relevant
freq = termFreq = amount of times the term occurs in the field for this document


fieldNorm = impact of a hit in this field
implementation: lengthNorm*boost(index)
lengthNorm = measure of the importance of a term according to the total number of terms in the field
implementation: 1/sqrt(numTerms)
Implication: a term matched in fields with less terms have a higher score
Rationale: a term in a field with less terms is more important than one with more
numTerms = amount of terms in a field
boost (index) = boost of the field at index-time
Implication: hits in fields with higher boost get a higher score
Rationale: a term in field A could be more relevant than the same term in field B


maxDocs = the number of documents in the index, including those that are marked as deleted but have not yet been purged. This is a constant (the same value for all documents in the index)
Implication: (probably) doesn't play a role in the scoring calculation


coord = number of terms in the query that were found in the document (omitted if equal to 1)
implementation: overlap/maxOverlap
Implication: of the terms in the query, a document that contains more terms will have a higher score
Rationale: documents that match the most optional terms score highest
overlap = the number of query terms matched in the document
maxOverlap = the total number of terms in the query


FunctionQuery = could be any kind of custom ranking function, which outcome is added to, or multiplied with the default rank score.
Implication: various


Look at the EXPLAIN information to see how the final score is calculated.

:

[elasticsearch] unassinged shard reroute...

Elastic/Elasticsearch 2013. 11. 13. 15:05

간혹 shard unassigned 되는 경우가 있습니다.

실제 데이터가 깨진게 아니라면 reroute 를 통해서 노드에 할당해 주시면 됩니다.

http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/cluster-reroute.html

curl -XPOST 'localhost:9200/_cluster/reroute' -d '{
   
"commands" : [ {
       
"move" :
           
{
             
"index" : "test", "shard" : 0,
             
"from_node" : "node1", "to_node" : "node2"
           
}
       
},
       
{
         
"allocate" : {
             
"index" : "test", "shard" : 1, "node" : "node3"
         
}
       
}
   
]
}'


curl -XPOST 'http://localhost:9200/_cluster/reroute' -d '{"commands" : [ {"allocate" : {"index" : "index_test", "shard" : 13, "node" : "genie1", "allow_primary" : true}}]}'


- allow_primary 가 설정 되어 있지 않을 경우 primary shard 는 할당 할 수 없습니다.

:

[Elasticsearch] logging.yml appender 추가 하기.

Elastic/Elasticsearch 2013. 10. 23. 11:08

elasticsearch 에서 logging 관련해서는 log4j 나 slf4j 를 이용하시면 됩니다.

java.util.logging 을 이용할 경우 elasticsearch 가 비정상적으로 동작 하는 문제가 있으니 유의 하시기 바랍니다.


es 패키지 내 Logger, ESLogger 를 사용하셔도 됩니다.

그리고 그냥 일반적으로 log4j 나 slf4j 사용하듯이 사용을 하셔도 됩니다.

아래는 별도 appender 를 하나 추가해서 제가 작성한 플러그인 로그만 따로 뺀 설정 입니다.


[logging.yml]

  logger:

  elasticsearch.analysis: ERROR, failLogger

  additivity:

  elasticsearch.analysis: false

  failLogger:

    type: dailyRollingFile

    file: ${path.logs}/analyzed_fail_docs.log

    datePattern: "'.'yyyy-MM-dd"

    layout:

      type: pattern

      conversionPattern: "%m%n"


별 다른 내용은 없고 형태소 분석이 실패한 문서가 있을 경우 실패한 문서 ID 를 기록해서 다시 색인을 하기 위한 것입니다.


logger 에는 내가 작성한 패키지에 대해서 로그레벨 과 appender 를 지정 하는 것이구요.

additivity 에는 root logger 로 해당 패키지에 대한 로그를 전달 하지 않기 위해 false 로 지정 한 것이구요.

failLogger 는 appender 를 정의 한 것입니다.

:

[Lucene] score 계산식 알아보기.

Elastic/Elasticsearch 2013. 10. 11. 11:25
필요해서 어제 공부 좀 했습니다.

제가 elasticsearch 로 프로젝트를 진행 하고 있습니다.

랭킹과 문서 스코어링 관련해서 문의가 있어서 정확하게 설명을 해줘야 튜닝에 도움이 될 것 같아 글 좀 남겨 봅니다.


검색해 보시면 많은 문서들이 나오는데요.

아래 문서 참고 하시면 좋을 것 같내요.


[참고링크]

http://www.lucenetutorial.com/advanced-topics/scoring.html

http://devyongsik.tistory.com/364 (여긴 울 회사 재화님도 알고 계신 DEV용식님 사이트인데요. 작성 된지 좀 되었지만 이해 하기에는 좋습니다.)

https://lucene.apache.org/core/3_6_2/scoring.html

http://lucene.apache.org/core/4_5_0/core/org/apache/lucene/search/package-summary.html#package_description

http://lucene.apache.org/core/4_5_0/core/org/apache/lucene/search/similarities/TFIDFSimilarity.html  


[참고용 소스코드]

Similarity.java

DefaultSimilarity.java

TFIDFSimilarity.java


lucene 이나 elasticsearch 나 기본은 바로 위에 있는 넘들 가지고 similarity 계산을 하게 됩니다.

소스를 보시면 아시겠지만 아래 요소를 가지고 score 를 계산 합니다.


tf

idf

lengthNorm

queryNorm

coord


소스코드에서 식을 뽑아 보면 이렇습니다.


 TF

 (float)Math.sqrt(freq)

 IDF

 (float)(Math.log(numDocs/(double)(docFreq+1)) + 1.0)^2

 lengthNorm

 state.getBoost() * ((float) (1.0 / Math.sqrt(numTerms)))

 queryNorm

 (float)(1.0 / Math.sqrt(sumOfSquaredWeights))

 coord

 overlap / (float)maxOverlap


이런건 그냥 위에 나온거 보면 다 나오구요.

검색 질의 시 스코어 계산 유형을 살펴 보겠습니다.

(계산 할 때 위에 식에 넣어서 계산 하기 번거로우니 explain 떠서 나온 값들을 사용해서 계산 하도록 하세요.)


1. 검색어 하나 질의

쉽게는 explain 에서 나온 queryWeight * fieldWeight 를 곱하시면 score 가 나옵니다.

score = (queryWeight * fieldWeight)^2


TFIDFSimilarity.html 에 잘 나와 있죠.

score(q,d)   =   coord(q,d)  ·  queryNorm(q)  · ( tf(t in d)  ·  idf(t)2  ·  t.getBoost() ·  norm(t,d) )
t in q
Lucene Practical Scoring Function

이걸 엑셀 같은 데 식을 넣어서 계산 해 보면 값이 나오게 됩니다.

아래 2번에서 풀어 놓은 식을 참고하세요.


2. 검색어 여러개 질의

score = (queryNorm * SUM( tf * idf^2 * fieldBoost * fieldNorm) )^2


3. 필드 부스팅을 포함한 검색어 질의

쉽게는 아래 처럼 풀어서 이해 하시면 됩니다.

score = ((queryWeight * fieldWeight) + (queryWeight * fieldWeight))^2

-> 필드 부스팅 된 필드의 queryWeight 값은 기본 계산이 되어서 나오지만 같은 필드에 같은 term 으로 했을 경우 기본 queryWeight 에 곱하기 boostScore 만큼 해준다고 보면 됩니다.


여기서 필드 부스팅을 한개가 아닌 여러개를 했다면 (queryWeight * fieldWeight) 이넘을 여러번 계산 해서 더하시면 됩니다.


근데 여기서 궁금한거 하나.... 

- fieldNorm 과 sumOfSquaredWeights 는 어떻게 구하나요???

소스 코드를 보시면 됩니다.


[fieldNorm]

computeNorm(), encodeNormValue(), decodeNormValue(), NORM_TABLE 을 참고하세요.

풀면 결국 아래와 같이 됩니다.


fieldNorm = NORM_TABLE[(floatToByte315(1/SQRT(fieldTotalTermsNum)) & 0xFF)];


[sumOfSquaredWeights]

말 처럼 이건 각각의 term 에 대해서 더하셔야 합니다.

1번에서 처럼  sigma 가 붙어 있는 걸 잊으시면 안됩니다.

이해를 돕고자 풀면 아래와 같이 됩니다.

queryBoost^2 * SUM( (idf * fieldBoost)^2 )


가볍게 이해 하는 수준으로만 사용하시고 깊이 있게 이해를 하고 싶으신 분들은 소스 코드를 꼭 드려야 보세요. :)


:

[Elasticsearch] join 기능 구현은 어떻게?

Elastic/Elasticsearch 2013. 9. 24. 12:50

아래 링크 참고해서 설계 및 구현 하시면 되겠습니다.

http://www.elasticsearch.org/blog/managing-relations-inside-elasticsearch/

https://github.com/imotov/elasticsearch-native-script-example

:

[Elasticsearch] node.local or node.mode ....

Elastic/Elasticsearch 2013. 9. 23. 14:52

0.90.5 에 추가 된 node.mode 관련 내용입니다.

기존에는 node.local 설정을 이용했었는데요.

이 설정이 없어진건 아니고 그대로 유지 되면서 이 옵션이 추가 된 것입니다.

node.local: true or false 로 설정을 했었는데요.

node.mode: local or network 으로 설정을 하게 됩니다.


kimchy 말에 의하면 

You set the node to local(true), this means it will not discover other nodes using network, only within the same JVM.

이와 같습니다.


관련 코드는 DiscoveryNode.java, DiscoveryModule.java, TransportModule.java 이 세 파일을 참고 하시면 됩니다.


의미는 노드간 communication 을 할 것인지 말것인지를 설정 하는 것으로 보시면 됩니다.

:

[Elasticsearch] Bulk Indexing 후 Data Consistency 관리.

Elastic/Elasticsearch 2013. 9. 17. 12:35

벌크 인덱싱 후 간혹 샤드간에 데이터가 왔다 갔다 할 때가 있습니다.

이건 elasticsearch 색인이 잘못 되었다고 보시면 안됩니다.

인덱스와 샤드의 status 정보를 보면

- num_docs

- max_docs

- deleted_docs

이런게 있죠.


기본적으로 벌크 색인 시 empty index 에 색인을 하게 될 텐데요.

색인 도중 문제가 발생해서 일부 색인 데이터가 들어가고 다시 같은 인덱스에 색인을 하게 되면  updateDocument 를 실행 하게 됩니다.

뭐 루씬 API 보시면 이제 add/update 가 하나의 API 로 동작 하긴 합니다.

암튼 이렇게 되다 보니 deleted_docs 가 발생 하게 되고 num_docs 와 max_docs 수치가 안맞게 됩니다.

즉, num_docs = max_docs - deleteed_docs 와 같습니다.


이런 관계로 색인 완료 시 recovery 또는 optimize 작업을 통해서 data consistency 를 보정해 주어야 합니다.

그럼 이걸 어떻게 할까요?


아래 명령어로 해보시고  ES  API 문서 참고 하시면 되겠습니다.

(거의 대부분 default value 입니다.)


[Java API]

new OptimizeRequest()

    .indices(indice)

    .flush(true)

    .onlyExpungeDeletes(false)

    .refresh(true)

    .waitForMerge(true)

    .operationThreading(BroadcastOperationThreading.THREAD_PER_SHARD)

    .maxNumSegments(1)



[Rest API]

curl -XPOST 'http://localhost:9200/indice/_optimize?only_expunge_deletes=false&max_num_segments=1&refresh=true&flush=true&wait_for_merge=true'



[Recovery]

curl -XPOST 'http://localhost:9200/indice/_close'

curl -XPOST 'http://localhost:9200/indice/_open'


client.admin()

    .indices()

    .close(new CloseIndexRequest("indice"));


client.admin()

    .indices()

    .close(new OpenIndexRequest("indice"));



[Reference]

http://www.elasticsearch.org/guide/reference/api/admin-indices-optimize/

http://www.elasticsearch.org/guide/reference/api/admin-indices-open-close/


:

[elasticsearch] Java API : Bulk

Elastic/Elasticsearch 2013. 9. 16. 18:34

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

정보 교환이 목적입니다.


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

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


벌크 색인 시 actionGet(TIMEOUT)  부분에 TIMEOUT 은 빼고 돌리시는게 좋습니다.

돌리시다 보면 timeout exception 이 발생 할 때가 있는데 timeout 값을 제거 하고 돌리시면 관련 에러는 없어집니다.


new OptimizeRequest()

.indices(indice)

.flush(true)

.onlyExpungeDeletes(true)

.refresh(true)

.waitForMerge(true)

.operationThreading(BroadcastOperationThreading.THREAD_PER_SHARD)

.maxNumSegments(1))




[elasticsearch java api 리뷰]

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


- 이 API는 한번의 요청으로 여러개의 문서를 색인 또는 삭제 할 수 있습니다.


우선 원문에 나와 있는 예제 부터 살펴 보겠습니다.


[원문예제]

BulkRequestBuilder bulkRequest = client.prepareBulk();


// either use client#prepare, or use Requests# to directly build index/delete requests

bulkRequest.add(client.prepareIndex("twitter", "tweet", "1")

        .setSource(jsonBuilder()

                    .startObject()

                        .field("user", "kimchy")

                        .field("postDate", new Date())

                        .field("message", "trying out Elastic Search")

                    .endObject()

                  )

        );


bulkRequest.add(client.prepareIndex("twitter", "tweet", "2")

        .setSource(jsonBuilder()

                    .startObject()

                        .field("user", "kimchy")

                        .field("postDate", new Date())

                        .field("message", "another post")

                    .endObject()

                  )

        );

        

BulkResponse bulkResponse = bulkRequest.execute().actionGet();

if (bulkResponse.hasFailures()) {

    // process failures by iterating through each bulk response item

}


- 기본 client.prepareIndex() 를 이용해서 문서 하나를 색인 요청 하는 것과 유사 합니다.

- 다만, bulkRequest 의 경우 이런 하나의 문서를 여러개 add(document) 해서 한번에 요청을 한다는 것입니다.

- index name : twitter

- index type : tweet

- document id (_id) : 1 과 2

- document id 를 지정 하지 않을 경우 자동으로 생성을 하게 됩니다.


아래 예제는 글 http://jjeong.tistory.com/792 에서 생성한 index 에 bulkRequest 를 보내는 것입니다.


[간단한 Bulk Request 예제]

BulkRequestBuilder bulkRequest;

BulkResponse bulkResponse;

String ts;

bulkRequest = client.prepareBulk();

int i=0;

for (i=0; i<100000; i++) {

ts = String.valueOf(System.currentTimeMillis());


bulkRequest.add(client.prepareIndex("facebook", "facebook_post")

.setRouting(ts)

.setOperationThreaded(false)

.setSource(jsonBuilder()

.startObject()

.field("docid", ts)

.field("title", "document "+String.valueOf(i))

.endObject()

)

)

.setReplicationType(ReplicationType.ASYNC)

.setConsistencyLevel(WriteConsistencyLevel.QUORUM)

.setRefresh(false);

if ( (i%100) == 0 ) {

bulkRequest.execute().actionGet(5000);

bulkRequest = client.prepareBulk();

log.debug("DOCUMENT Sequence : {}", i);

}

}


bulkRequest.execute().actionGet(5000);

log.debug("DOCUMENT Sequence : {}", i);

- 코드를 보시면 아시겠지만 문서 구조는 docid, title 로 아주 심플합니다.

- docid 에 timestamp를 넣고 document 에는 문자열 "document $SEQ"가 들어 갑니다. 

- 문서를 100개 단위로 묶어서 request 하게 됩니다.


[Bulk Request 고려사항]

- threadpool 세팅을 검토해 보셔야 합니다.

http://www.elasticsearch.org/guide/reference/modules/threadpool/


- refresh 설정을 검토해 보셔야 합니다.

disable 또는 10초 이상 설정


- index merge segment 크기를 조정해야 합니다.

20 또는 30 정도


- threadsafe 하지 않다는 걸 인지해야 합니다.

아직까지는 bulk request 시에 multithread 지원이 되지 않습니다.


- async 방식을 추천 합니다.


: