'elastic'에 해당되는 글 24건

  1. 2017.08.17 [Logstash] input file start_position => "end"
  2. 2017.08.03 [Elasticsearch] Snapshot and Restore 알아보기
  3. 2017.07.19 [Logstash] input file plugin 에 대해서 알아 봅니다.
  4. 2017.07.17 [esquery-proxy] Elasticsearch 용 RESTful API Gateway/Proxy
  5. 2017.07.17 [Elasticsearch] Multi Search API 사용
  6. 2017.07.13 [Elasticsearch] post_filter
  7. 2017.07.10 [Elasticsearch] elasticsearch-analysis-arirang-5.5.0 공유
  8. 2017.06.08 [Elasticsearch] 각 노드별 meta 정보 저장 관련.
  9. 2017.03.09 [Elasticsearch] TransportClient on 5.x
  10. 2017.01.24 [검색추천] Apache mahout + Elastic Stack 을 이용한 기본 추천

[Logstash] input file start_position => "end"

Elastic/Logstash 2017.08.17 11:20

먼저 앞서 기술한 input file 에 대한 내용을 먼저 읽어 보시면 이해 하시는데 도움이 됩니다.


※ [Logstash] input file plugin 에 대해서 알아 봅니다.


이전 글은 데이터 유실 방지를 위한 설정과 input file 의 주요 설정 정보에 대해서 알아 봤습니다.

이번 글에서는 반대로 start_position => "end" 로 했을 때 왜 데이터가 유실 되는지 간략하게 살펴 보겠습니다.


설정)

input {

  file {

    path => "/xxxx/logs/test-file.log"

    start_position => "end"

    stat_interval => 1

  }


  file {

    path => "/xxxx/logs/test-file1.log"

    start_position => "end"

    stat_interval => 10

  }

}


output {

    stdout {

      codec => "rubydebug"

    }

}


첫 번째 실행)

$ bin/logstash -f config/test-file.conf


첫번째 실행 후 sincedb)

189766986 1 4 3675


두 번째 실행)

$ bin/logstash -f config/test-file.conf


두번째 실행 후 sincedb)

189766986 1 4 4065


보시는 것 처럼 start_position => "end"로 했을 경우 해당 파일의 end byte offset 정보를 기록하게 됩니다.

이후 sincedb  정보는 변경이 되지 않게 됩니다.

logstash 를 중지 하고 재실행 합니다.

그 동안 test-file.log 에는 계속 데이터가 누적 되도록 하였습니다.

두 번째 실행 된 후 sincedb 값을 확인해 보면 변경 되어 있는 것을 볼 수 있습니다.


이와 같이 첫 번째 offset 정보와 두 번째 offset 정보의 차이 만큼 데이터가 유실 되게 되는 것입니다.


저작자 표시 비영리 변경 금지
신고
크리에이티브 커먼즈 라이선스
Creative Commons License
Trackback 0 : Comment 0

[Elasticsearch] Snapshot and Restore 알아보기

Elastic/Elasticsearch 2017.08.03 11:23

Elasticsearch 에서 제공하는 Snapshot과 Restore 기능에 대해서 정리합니다.


Snapshot과 Restore 기능에 대한 정의와 설명은 아래 본문에 잘 나와 있습니다.


[원본 문서]

https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-snapshots.html

https://www.elastic.co/guide/en/elasticsearch/guide/current/backing-up-your-cluster.html


※ 각 API의 상세 옵션과 설명은 원본 문서 참고 하시면 됩니다.


[발췌]

The snapshot and restore module allows to create snapshots of individual indices or an entire cluster into a remote repository like shared file system, S3, or HDFS. These snapshots are great for backups because they can be restored relatively quickly but they are not archival because they can only be restored to versions of Elasticsearch that can read the index. That means that:


  • A snapshot of an index created in 2.x can be restored to 5.x.
  • A snapshot of an index created in 1.x can be restored to 2.x.
  • A snapshot of an index created in 1.x can not be restored to 5.x.

글에서도 보시는 것 처럼 snapshot type 은 아래와 같이 지원 합니다.
  • fs
  • s3
  • hdfs
  • gcs

각 type을 지정하고 사용하기 위해서는 아래와 같은 추가 작업이 필요 합니다.


fs)

클러스터 내 모든 노드에 path.repo 설정 후 재시작 합니다.

- elasticsearch.yml

반드시 shared file system 적용을 해주셔야 합니다. 


s3)

클러스터 내 모든 노드에 plugin 설치를 해주셔야 합니다.

aws의 s3를 사용하기 위해서는 repository plugin 을 설치해야 합니다.


2.x)

bin/plugin install cloud-aws


5.x)

bin/elasticsearch-pluin install repository-s3


hdfs)

https://github.com/elastic/elasticsearch-hadoop/tree/master/repository-hdfs


클러스터 내 모든 노드에 plugin 설치를 해주셔야 합니다.

hadoop file system을 사용하기 위해서는 repository plugin 을 설치해야 합니다.


2.x)

bin/plugin install elasticsearch-repository-hdfs


5.x)

bin/elasticsearch-pluin install repository-hdfs


gcs)

클러스터 내 모든 노드에 plugin 설치를 해주셔야 합니다.

google cloud storage를 사용하기 위해서는 repository plugin 을 설치해야 합니다.


5.x)

bin/elasticsearch-pluin install repository-gcs


azure)

https://github.com/elastic/elasticsearch-cloud-azure


클러스터 내 모든 노드에 plugin 설치를 해주셔야 합니다.

azure repository를 사용하기 위해서는 repository plugin 을 설치해야 합니다.


2.x)

bin/plugin install elasticsearch/elasticsearch-cloud-azure


5.x)

bin/elasticsearch-pluin install repository-azure


이 중 2.X 클러스터에서 제가 추천 하는 것은 fs, s3 입니다.

이유는 다른건 제가 경험이 없어서 좋은지 나쁜지는 모릅니다.


fs, s3 에 대한 예제를 가지고 snapshot 과정과 restore 과정을 살펴 보겠습니다.


[fs]

step 1)

snapshot 기능을 수행 하기 위한 snapshot 저장소를 생성 합니다.


$ curl -XPUT 'localhost:9200/_snapshot/fs_snapshot?pretty' -d '{

    "type": "fs",

    "settings": {

        "location": "/mount/snapshot",

        "compress": true

    }

}'


step 2)

snapshot 할 대상을 선정하고 실행 합니다.


$ curl -XPUT 'localhost:9200/_snapshot/fs_snapshot/logstash_20170803?pretty' -d '

{

  "indices": "logstash-web-20170803,logstash-app-20170803",

  "ignore_unavailable": true,

  "include_global_state": false

}'


step 3)

이제 restore 해보겠습니다.


$ curl -XPOST 'localhost:9200/_snapshot/fs_snapshot/logstash_20170803/_restore'


[s3]

step 1)

snapshot 기능을 수행 하기 위한 snapshot 저장소를 생성 합니다.


$ curl -XPUT 'localhost:9200/_snapshot/s3_snapshot?pretty' -d '{

    "type": "s3",

    "settings": {

        "bucket": "s3-bucket",

        "region": "ap-northeast-2"

    }

}'


step 2)

snapshot 할 대상을 선정하고 실행 합니다.


$ curl -XPUT 'localhost:9200/_snapshot/s3_snapshot/logstash_20170803?pretty' -d '

{

  "indices": "logstash-web-20170803,logstash-app-20170803",

  "ignore_unavailable": true,

  "include_global_state": false

}'


step 3)

이제 restore 해보겠습니다.


$ curl -XPOST 'localhost:9200/_snapshot/s3_snapshot/logstash_20170803/_restore'


하나의 클러스터 내 여러개의 snapshot repository 를 등록해서 사용 하셔도 되기 때문에 목적에 맞게 사용 하시면 좋을 것 같습니다.


이 과정들은 모두 background 로 동작 하기 때문에 실행 후 바로 acknowledged/accepted 가 전달 됩니다.

그렇기 때문에 실행한 snapshot 의 상태 점검을 하셔야 합니다.


$ curl -XGET 'localhost:9200/_snapshot/s3_snapshot/logstash_20170803/_status'


추가적으로 사용하시면서 약간의 주의점 공유 드립니다.

- 더이상 색인 작업이 발생 하지 않는 index 들에 대해서 snapshot 작업을 수행하시면 좋습니다.

- restore 시는 대상 index 가 없거나 close 되어 있어야 하기 때문에 지속적인 색인 작업이 발생 하는 index에 대한 snapshot은 추천 하지 않지만, 아직 필요한 경우를 찾지는 못했습니다.


저작자 표시 비영리 변경 금지
신고
크리에이티브 커먼즈 라이선스
Creative Commons License
Trackback 0 : Comment 0

[Logstash] input file plugin 에 대해서 알아 봅니다.

Elastic/Logstash 2017.07.19 13:25

가장 많이 사용하고 있는 logstash input plugin 중에 하나라고 생각 합니다.

저 역시 현업에서 제일 많이 사용하고 있는 plugin 이기도 합니다.


elastic reference 문서를 보시면 설명이 잘 나와 있습니다.

하지만 신뢰 할 수 없는 기억력으로 인해서 한번 작성해 봅니다.


이미 많은 분들이 input file plugin 에 대해서 많은 자료들을 공유해 주셨기 때문에 구글링 몇 번 해보시면 좋은 정보를 얻으실 수 있습니다.


참고문서)
https://www.elastic.co/guide/en/logstash/current/plugins-inputs-file.html


logstash input file 기본 동작은 ruby-filewatch를 이용한 tail 입니다. 


주요 설정 정보)

1. start_position

이 설정은 logstash 실행 시 읽기 작업에 대한 수행 정보를 정의 합니다.

beginning 과 end 설정은 2번 sincedb 파일이 있고 없고에 따라 동작이 다르다고 생각 하시면 됩니다.

즉, sincedb 에 offset 정보가 있으면 해당 offset 부터 읽게 되고 없으면 beginning, end 설정 동작 방식으로 동작 합니다.

beginning 은 처음(이전) 부터 읽어 들이고, end 는 가장 최근 부터 읽어 들이게 됩니다.


결국, 데이터의 유실 없이 데이터를 읽기 위해서는 beginning 으로 설정 하셔야 합니다.

default value 는 end 입니다.


2. sincedb

이건 설정은 아니고 sincedb 파일에 대한 내용입니다.

logstash input file 을 사용하게 되면 sincedb 파일에 어디까지 읽었는지 정보를 기록하게 됩니다.

reference 문서를 보시면 sincedb 에 기록하는 정보에 대해서 설명이 자세히 나와 있습니다.


Sincedb files are text files with four columns:


The inode number (or equivalent).

The major device number of the file system (or equivalent).

The minor device number of the file system (or equivalent).

The current byte offset within the file.


$ cat .sincedb_8d6238d5255f464e564ecdb307fe0c0c

7341423 0 51713 67247655


sincedb_path 를 설정 하지 않을 셨을 경우는 user home directory 를 확인해 보시거나,

~/logstash-5.5.0/data/plugins/inputs/file/ 을 확인해 보시면 됩니다.


#pick SINCEDB_DIR if available, otherwise use HOME

sincedb_dir = ENV["SINCEDB_DIR"] || ENV["HOME"]

※ .sincedb 작성 시 overwrite 인지 append 인지 확인 후 공유 드리겠습니다. ㅡ.ㅡ;

미쳐 확인을 못했내요.

->

input file 을 여러개 등록 하면 sincedb 가 여러개 생성이 됩니다.

참고 파일은 filewatch 소스코드를 보시면 되시겠습니다.

($ ~elastic/logstash-5.5.0/vendor/bundle/jruby/1.9/gems/filewatch-0.9.0/lib/filewatch)


input file 을 여러개 등록 하면 sincedb 에 inode 가 다른게 여러게 생성 됩니다.

즉, overwrite(update) 이라고 보시면 되겠습니다.

위에 잘못 설명한 부분은 확인 없이 그냥 동작 하고 있는 것만 가지고 작성을 하다 보니 놓친 부분 입니다. 죄송합니다.

기존에 logstash 가 처리 하고 있는 log file 자체의 변경이 발생 하였을 경우 기 생성된 sincedb 에 row가 추가 되면서 변경된 log file 의 inode 값과 offset 정보가 추가 되게 됩니다.

- 파일이 삭제 된 후 다시 생성 된 경우가 대표적인 예가 되겠습니다.


189699226 -rw-r--r--  1 henry  staff  105  7 20 15:03 file.log

$ rm -f file.log

189766986 -rw-r--r--  1 henry  staff  120  7 20 15:04 file.log


$ cat .sincedb_27eb92c828fb885f9741fac9e538c0e1

189699226 1 4 285

189766986 1 4 150


3. sincedb_write_interval

이 설정은 logstash 가 열심히 일을 하고 어디까지 일을 했는지 주기적으로 기록하도록 하는 주기를 작성 하게 됩니다.

설정 주기가 너무 길게 되면 logstash가 비정상 종료 후 재 실행 되었을 때 데이터가 중복으로 입력 될 수도 있으니 적절한 주기를 찾아서 설정 하는게 중요 합니다.


현재 inode 파일의 읽어 들인 offset 정보를 sincedb 에 기록 하게 됩니다.

default value 는 15초로 되어 있습니다.


4. stat_interval

이 설정은 logstash 가 읽어야 하는 로그 파일에 새로운 로그가 추가 되었는지 확인하기 위한 주기를 설정 하게 됩니다.

reference 문서에서는 아래와 같이 설명 하고 있습니다.

How often (in seconds) we stat files to see if they have been modified. Increasing this interval will decrease the number of system calls we make, but increase the time to detect new log lines.


system call 을 줄일 것인지 빠르게 신규 로그 감지 할 것인지 결정을 하셔야 합니다.

default value 는 1초 입니다.


5. discover_interval

이 설정은 filename pattern 을 이용해서 신규 로그 파일이 추가 되었는지 확인 하기 위한 주기를 설정 하게 됩니다.

 default value 는 15초 입니다.


여기까지 알아 두면 좋은 설정들은 이렇습니다.

이를 기반으로 샘플 설정을 작성해 보면 아래와 같습니다.


input {

  file {

    path => "/XXXX/logs/test-file.log"

    start_position => "beginning"

  }

}


결국 기본 설정으로 돌려도 크게 무리는 없습니다.

다만, 생성되는 로그 파일의 크기와 worker, queue 설정 크기에 따라 값들을 최적화 하시면 됩니다.

왜냐면 사용하시는 환경 마다 다 다르기 때문이고, 환경에 맞춰서 튜닝을 할 수 밖에 없기 때문 입니다.


3, 4, 5 번에 대한 테스트는

3번은 설정 변경 하시면서 sincedb 값이 바뀌는 걸 보시면 됩니다.

4번은 설정 변경 하시면서 output  으로 언제 전달 되는지 보시면 됩니다.

5번은 설정 변경 하시면서 log file을 rotate 해보시면 됩니다.


여기서는 그냥 4번 초간단 테스트 예제만 보여 드리겠습니다.


1. log file 을 생성하고 해당 파일에 log를 기록 합니다.

while true;
do

DATE=$(date '+%Y%m%d%H%M%S');

echo $DATE >> /XXXX/logs/test-file.log;

cat test-file.log;

sleep 2;

done

코드 보셔서 아시겠지만 2초 마다 datetime  을 file.log 에 기록하는 스크립트 입니다.


2. logstash 를 실행 시킵니다.

[file.config]

input {

  file {

    path => "/XXXX/logs/test-file.log"

    start_position => "beginning"

    stat_interval => 30

  }

}


output {

  stdout {

    codec => "rubydebug"

  }

}


$ bin/logstash -f ./config/file.conf --config.reload.automatic


이렇게 하시면 30초 마다 file.log 에 기록된 정보를 읽어 오게 됩니다.

참 쉽죠잉.


여기까지 logstash input file 에 대한 설명이였는데요.

도움이 되셨다면 좋겠습니다.


저작자 표시 비영리 변경 금지
신고
크리에이티브 커먼즈 라이선스
Creative Commons License
Trackback 0 : Comment 0

[esquery-proxy] Elasticsearch 용 RESTful API Gateway/Proxy

ITWeb/검색일반 2017.07.17 19:01

Elasticsearch 를 서비스 용도로 많은 분들이 사용하고 계시는 것으로 압니다.

저 처럼 Java API를 사용하고 계신 분들도 계실 테고 RESTful API 를 사용하고 계신 분들도 계실 것으로 압니다.

그냥 버전 업그레이도 해야 하고 해서 재미 삼아 가볍게 만들어 보았습니다.

관련해서 

- 단순 기능 동작 유무만 확인했습니다. (잘 됩니다.)

- 성능 테스트 하지 않았습니다.

- 안정성 테스트 하지 않았습니다.

그래서 가져다 막 고쳐서 사용하시면 좋겠습니다. 


일단 만들게 된 동기는

- Search 와 Aggregation 에 대해서 사용할 목적으로 만들었습니다.

- Elasticsearch JAVA API 버전 관리에 대한 유지보수 비용을 절감 해야 했습니다.

- Elasticsearch Cluster 에 대한 Version Upgrade 도 수행 해야 했습니다.

- Multi Cluster 에 대한 Concurrent 처리가 가능 해야 했습니다.


프로젝트 코드를 보시면 아시겠지만 매우 간단 합니다.


사용한 Framework)

- SpringMVC + Maven Project

- pom.xml  내 dependency 참고 하시면 됩니다.


지원 가능한 API)

- Elasticsearch에서 제공하는 거의 모든 RESTful API 를 제공 합니다.

- HTTP POST 만 구현해 놨기 때문에 POST 를 지원하지 않는 API 는 동작 하지 않습니다.

- 조만간 시간 나는데로 추가해 보겠습니다.

- Single Request 뿐만 아니라 Multi Request 도 지원 합니다.

- Single Cluster 뿐만 아니라 Multi Cluster 로 Request 를 보낼 수 있습니다.

-  서로 다른 Version 의 Cluster 라도 상관 없습니다.


Single Request Example)

[WAS Endpoint]

http://localhost:8080/query


[Method]

POST RAW


[Request Body]

{

  "target":"http://{YOUR-CLUSTER}/{YOUR-INDEX}/_search",

  "query":{}

}

- target

-  요청할 Elasticsearch Cluster 의 RESTful Endpoint 를 작성 하시면 됩니다.

- {YOUR-INDEX} 는 alias, single index, multi index  모두 사용 가능 합니다.

- query

- 기존에 사용하시던 QueryDSL 문을 그대로 넣어 주시면 됩니다.

- match_all  query 가 실행 됩니다.


Multi Request Example)

[WAS Endpoint]

http://localhost:8080/mquery


[Method]

POST RAW


[Request Body]

[

{

  "target":"http://{YOUR-CLUSTER1}/{YOUR-INDEX1}/_search",

  "query":{}

},

{

  "target":"http://{YOUR-CLUSTER1}/{YOUR-INDEX2}/_search",

  "query":{}

},

{

  "target":"http://{YOUR-CLUSTER2}/{YOUR-INDEX1}/_search",

  "query":{}

},

{

  "target":"http://{YOUR-CLUSTER2}/{YOUR-INDEX2}/_search",

  "query":{}

}

]


 Multi Request 의 경우 _msearch API 와 비슷 하게 동작은 합니다.

다만, _msearch의 경우 서로 다른 클러스터간에 통신은 지원 하지 않습니다.



추가 Parameters)

- routing

이 기능은 특정 key 를 가지고 문서를 저장 하기 위한 대상 shard 를 지정 하기 위해 사용 합니다.

문서 저장 시 해당 key 에 대한 Grouping 이나 Classify 를 위해 사용 합니다.

자세한 내용은 Elastic 사의 Reference 문서를 참고하세요. (클릭)

- preference

이 기능은 검색 질의 시 아주 유용하게 활용이 가능 합니다.

특정 shard 를 지정 할 수도 있고 질의 하고 싶은 node 를 선택 할 수도 있습니다.

자세한 내용은 Elastic 사의 Reference 문서를 참고하세요. (클릭)


Github Repository)

https://github.com/HowookJeong/esquery-proxy

저작자 표시 비영리 변경 금지
신고
크리에이티브 커먼즈 라이선스
Creative Commons License
Trackback 0 : Comment 0

[Elasticsearch] Multi Search API 사용

Elastic/Elasticsearch 2017.07.17 12:48

2.X 랑 5.X 랑 크게 바뀐 부분은 없습니다.

다만 5.X 에서는 template 지원도 함께 됩니다.


참고문서)

https://www.elastic.co/guide/en/elasticsearch/reference/current/search-multi-search.html


Multi Search API를 얼마나 많은 분들이 사용하고 계신지는 잘 모르겠습니다.

이 API 를 한 줄로 정의 하면 "통합 검색 API" 라고 할 수 있습니다.

뭐 동의 하지 않으시는 분들이 계시다면 어쩔수 없구요.


설명을 풀어서 하면, 서로 다른 query 를 하나의 index 에 질의 하거나 하나의 query 를 서로 다른 index 로 질의 할 때 사용 하시면 유용 합니다.


Case 1)

Single Query + Multi Index


Case 2)

Multi Query + Single Index


Case 3)

Multi Query + Multi Index


위 참고문서 에서는 Request 에 대한 내용은 나와 있지만 실제 Response 에 대한 예시는 나와 있지 않아 실제 실행 보지 않고서는 어떻게 결과가 나올지 모르실 수도 있습니다.

(사실 상상은 되실거예요.)


아래는 제가 테스트로 하나의 클러스터에 "Case 3" 으로 실행한 결과 입니다.


Request API)

Endpoint : http://xxxx/_msearch

Method : POST (raw)


Request Query)

{"index":"service_product"}

{"query":{"match_all":{}},"from":0,"size":1}

{"index":"service_item"}

{"query":{"term":{"title":{"value":"틴트"}}},"from":0,"size":1}


Response Data)

{

    "responses": [

        {

            "took": 1,

            "timed_out": false,

            "_shards": {

                "total": 1,

                "successful": 1,

                "failed": 0

            },

            "hits": {

                "total": xxxxxx,

                "max_score": 1,

                "hits": [

                    {

                        "_index": "service_product_201707171215",

                        "_type": "deal",

                        "_id": "7510",

                        "_score": 1,

                        "_source": {

                        ... 생략 ...

                        }

                    }

                ]

            }

        },

        {

            "took": 1,

            "timed_out": false,

            "_shards": {

                "total": 1,

                "successful": 1,

                "failed": 0

            },

            "hits": {

                "total": xxxxxx,

                "max_score": 7.0183215,

                "hits": [

                    {

                        "_index": "service_item_201707171215",

                        "_type": "item",

                        "_id": "1170617",

                        "_score": 7.0183215,

                        "_source": {

                            ... 중략 ...

                            "title": "라네즈 투톤틴트바 No.3 2g 틴트민트",

                            ... 중략 ...

                        }

                    }

                ]

            }

        }

    ]

}


결과적으로 보면, 검색엔진에서 해당 연산과 실행을 하실지 아니면 별도 API Gateway 같은 WAS 에서 연산과 실행을 하실지에 대한 문제로 트래픽과 용량을 잘 산정 하셔서 사용하시면 매우 유용하리라 생각 합니다.

(너무 오래 전에 비슷한 내용을 올린 것 같아 5.5 릴리즈 기념으로 한번 더 복습해 봤습니다.)


저작자 표시 비영리 변경 금지
신고
크리에이티브 커먼즈 라이선스
Creative Commons License
Trackback 0 : Comment 0

[Elasticsearch] post_filter

Elastic/Elasticsearch 2017.07.13 15:08

§ Elasticsearch Reference 5.5


https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-post-filter.html


한 줄 요약)

모든 action 완료 후 결과 내 재검색 수행 후 결과를 리턴 합니다.


이전 글 참고)

[Elasticsearch] aggregations 사용 시 filter 의 차이점.


저작자 표시 비영리 변경 금지
신고
크리에이티브 커먼즈 라이선스
Creative Commons License
Trackback 0 : Comment 0

[Elasticsearch] elasticsearch-analysis-arirang-5.5.0 공유

Elastic/Elasticsearch 2017.07.10 14:18

5.5.0 에서 RestActionPlugin 등록하는 코드가 변경이 되어서 수정 반영 했습니다.




elasticsearch-analysis-arirang-5.5.0 공유 합니다.


Lucene 6.6.0

Elasticsearch 5.5.0 

기준 입니다.


설치파일 다운로드)

elasticsearch-analysis-arirang-5.5.0.zip



설치 방법)

$ bin/elasticsearch-plugin install --verbose file:///services/apps/elasticsearch-analysis-arirang-5.5.0.zip


아래는 플러그인 구현 시 필요한 내용 몇 가지 정리 했습니다.


1. arirang 관련 프로젝트 두개를 빌드 하셔야 합니다.

https://github.com/korlucene/arirang-analyzer-6

https://github.com/korlucene/arirang.morph


arirang.morph 의 경우 수명님이 arirang-analyzer-6 에 포함 시켜 놓았기 때문에 반드시 빌드해서 하실 필요는 없지만 그래도 한번 해보시면 좋습니다.

version 정보등은 맞게 수정해서 사용 하시면 됩니다.

(참고로 arirang 에 있었던 몇 가지 버그들이 수정된 것 같습니다.)


2. elasticsearch arirang plugin 을 만드시면 됩니다.

항상 그렇지만 version 이 올라가고 나면 변경된 내용에 대해서 적용을 해주셔야 합니다.

이번에는 큰 변화는 없었지만 test code 쪽 내용이 좀 변경이 되었내요.

이전 브랜치와 비교해서 보시면 될 것 같습니다.


설치 후 테스트)

http://localhost:9200/_analyze?pretty&analyzer=arirang_analyzer&text=한국 엘라스틱서치 사용자 그룹의 HENRY 입니다.


테스트 결과)

더보기


저작자 표시 비영리 변경 금지
신고
크리에이티브 커먼즈 라이선스
Creative Commons License
Trackback 0 : Comment 0

[Elasticsearch] 각 노드별 meta 정보 저장 관련.

Elastic/Elasticsearch 2017.06.08 10:12

master, data 노드에는 기본적으로 모든 index 들의 settings, mappings 정보를 가지고 있습니다.

search  노드만 index 에 대한 meta 정보를 가지고 있지 않습니다.

어떻게 보면 당연한 건데 확인 하지 않으면 실수 할 수 있는 내용이라 그냥 기록해 봅니다.


master 노드는 모드 node 와 index 에 대한 관리를 하기 때문에 당연히 정보를 가지고 있어야 합니다.

data 노드는 물리적인 index, shard 를 저장하고 있기 때문에 역시 정보를 가지고 있을 수 밖에 없습니다.

search 노드는 coordinator 역할과 질의 결과에 대한 merge 등의 역할을 하고 있어 물리적으로 정보를 가지고 있지는 않지만 필요 시 master node 로 정보를 요청 할 수는 있습니다.

저작자 표시 비영리 변경 금지
신고
크리에이티브 커먼즈 라이선스
Creative Commons License
Trackback 0 : Comment 0

[Elasticsearch] TransportClient on 5.x

Elastic/Elasticsearch 2017.03.09 11:51

elasticsearch 2.4 에서 사용하던 java api 중 TransportClinet 사용 방법이 바뀌어서 작성 합니다.

변경된 내용에 대해서는 elasticsearch 공식 홈페이지에 자세히 나와 있습니다.


[참고문서]

https://www.elastic.co/guide/en/elasticsearch/client/java-api/current/_maven_repository.html

https://www.elastic.co/guide/en/elasticsearch/client/java-api/current/transport-client.html


[코드 변경]


2.x)

settings = settingsBuilder()

  .put("cluster.name", cluster)

  .put("client.transport.sniff", true)

  .put("network.tcp.blocking", false)           // tcp non-blocking mode

  .put("client.transport.ping_timeout", "10s")

  .build();


5.x)

settings = builder()

  .put("cluster.name", cluster)

  .put("client.transport.sniff", true)

  .put("network.tcp.blocking", false)           // tcp non-blocking mode

  .put("client.transport.ping_timeout", "10s")

  .build();


2.x)

TransportClient client = TransportClient.builder().settings(settings).build();


5.x)

TransportClient client = new PreBuiltTransportClient(settings);


여기서 주의 하실 점은 참고문서에 있지만  transport 가 분리 되었기 때문에 별도로 dependency 구성을 해주셔야 합니다.


Maven Dependency 추가)

<dependency>

  <groupId>org.elasticsearch.client</groupId>

  <artifactId>transport</artifactId>

  <version>${elasticsearch.version}</version>

</dependency>


별 내용은 아니지만 혹시라도 삽질 하시는 분들이 계실 수 있어 작성해 봤습니다.

저작자 표시 비영리 변경 금지
신고
크리에이티브 커먼즈 라이선스
Creative Commons License
Trackback 0 : Comment 0

[검색추천] Apache mahout + Elastic Stack 을 이용한 기본 추천

Elastic/Elasticsearch 2017.01.24 11:47

Elastic Stack 과 Apache mahout 을 이용한 추천 데이터 생성을 다뤄 볼까 합니다.

기본적으로는 Elastic Stack 만 가지고도 cohort 분석을 통해 추천 데이터 마트 구성이 가능 한데요.

추천 데이터에 대한 품질을 좀 더 좋게 하기 위해 Apache mahout 을 활용해 보도록 하겠습니다.


여기서 다루는 내용은 누구나 쉽게 접근 할 수 있도록 Hello World! 수준만 기술 합니다.


[Elastic Stack]

https://www.elastic.co/products


[Apache mahout]

https://mahout.apache.org/


위 두 솔루션은 모두 오픈소스 이며 예제 코드가 해당 소스에 잘 만들어져 있어 누구나 쉽게 활용이 가능합니다.


Step 1)

Elasticsearch + Logstash + Kibana 를 이용해 로그를 수집하고 추천 할 raw data 를 생성 합니다.


User item click log -> Logstash collect -> Elasticsearch store -> Kibana visualize -> CSV download


여기서 수집한 데이터 중 추출 데이터는 user id + item id + click count 입니다.

아래는 Kibana QueryDSL 예제 입니다.

{

  "size": 0,

  "query": {

    "filtered": {

      "query": {

        "query_string": {

          "query": "cp:CLK AND id:[0 TO *]",

          "analyze_wildcard": true

        }

      },

      "filter": {

        "bool": {

          "must": [

            {

              "range": {

                "time": {

                  "gte": 1485010800000,

                  "lte": 1485097199999,

                  "format": "epoch_millis"

                }

              }

            }

          ],

          "must_not": []

        }

      }

    }

  },

  "aggs": {

    "2": {

      "terms": {

        "field": "user_id",

        "size": 30000,

        "order": {

          "_count": "desc"

        }

      },

      "aggs": {

        "3": {

          "terms": {

            "field": "item_id",

            "size": 10,

            "order": {

              "_count": "desc"

            }

          }

        }

      }

    }

  }

}


Step 2)

Apache mahout 에서 사용할 recommender 는 UserBasedRecommender 입니다.

샘플 코드에도 나와 있지만 dataset.csv 파일은 아래와 같은 형식 입니다.

- Creating a User-Based Recommender in 5 minutes


1,10,1.0
1,11,2.0
1,12,5.0
1,13,5.0

형식) userId,itemId,ratingValue


Step1 에서 위와 같은 형식을 맞추기 위해 user_id, item_id, click_count 를 생성 하였습니다.

이 데이터를 기반으로 UserBasedRecommender 를 돌려 보도록 하겠습니다.


Step 3)

아래 보시면 샘플 코드가 잘 나와 있습니다.

https://github.com/apache/mahout/tree/master/examples/src/main/java/org/apache/mahout


Main class 하나 만드셔서 Step2 에 나와 있는 코드로 돌려 보시면 됩니다.

저는 UserBasedRecommender 를 implements 해서 별도로 구현했습니다.

이건 누구나 쉽게 하실 수 있는 부분이기 때문에 examples 에 나와 있는 BookCrossingRecommender 클래스등을 참고 하시면 됩니다.


UserBasedRecommenderRunner runner = new UserBasedRecommenderRunner();

Recommender recommender = runner.buildRecommender();


// 710039번 유저에 대한 추천 아이템 3개

List<RecommendedItem> recommendations = recommender.recommend(710039, 3);


for (RecommendedItem recommendation : recommendations) {

    LOG.debug("추천 아이템 : {}", recommendation);

}


[실행 로그]

11:39:31.527 [main] INFO  o.a.m.c.t.i.model.file.FileDataModel - Creating FileDataModel for file /git/prototype/data/user-to-item.csv

11:39:31.626 [main] INFO  o.a.m.c.t.i.model.file.FileDataModel - Reading file info...

11:39:31.765 [main] INFO  o.a.m.c.t.i.model.file.FileDataModel - Read lines: 63675

11:39:31.896 [main] INFO  o.a.m.c.t.i.model.GenericDataModel - Processed 10000 users

11:39:31.911 [main] INFO  o.a.m.c.t.i.model.GenericDataModel - Processed 19124 users

11:39:31.949 [main] DEBUG o.a.m.c.t.i.r.GenericUserBasedRecommender - Recommending items for user ID '710039'

11:39:31.965 [main] DEBUG o.a.m.c.t.i.r.GenericUserBasedRecommender - Recommendations are: [RecommendedItem[item:35222, value:4.0], RecommendedItem[item:12260, value:4.0], RecommendedItem[item:12223, value:1.5]]

11:39:31.966 [main] DEBUG o.h.p.mahout.meme.MemeProductRunner - 추천 아이템 : RecommendedItem[item:35222, value:4.0]

11:39:31.966 [main] DEBUG o.h.p.mahout.meme.MemeProductRunner - 추천 아이템 : RecommendedItem[item:12260, value:4.0]

11:39:31.967 [main] DEBUG o.h.p.mahout.meme.MemeProductRunner - 추천 아이템 : RecommendedItem[item:12223, value:1.5]


[Recommender]

similarity = new PearsonCorrelationSimilarity(dataModel);


// 이웃한 N명의 사용자 데이터로 추천 데이터 생성

// UserNeighborhood neighborhood = new NearestNUserNeighborhood(2, similarity, dataModel, 0.2);


// 특정 값이나 임계치를 넘는 모든 사용자의 데이터로 추천 데이터 생성, samplingrate : user sampling rate 10%

// UserNeighborhood neighborhood = new ThresholdUserNeighborhood(0.1, similarity, dataModel, 0.1);


UserNeighborhood neighborhood = new ThresholdUserNeighborhood(0.2, similarity, dataModel, 1.0);

recommender = new GenericUserBasedRecommender(dataModel, neighborhood, similarity);


- 데이터 크기가 너무 작아 ThresholdUserNeighborhood 를 이용하였습니다.


이와 같이 검색 클릭 로그를 기반으로 CF를 돌려 추천 데이터를 만드는 아주 간단한 방법을 알아봤습니다.

만든 추천 데이터에 대한 평가도 가능 합니다.

역시 examples 에 xxxxxxEvaluator 클래스들을 참고하셔서 구현해 보시면 됩니다.


저작자 표시 비영리 변경 금지
신고
크리에이티브 커먼즈 라이선스
Creative Commons License
Trackback 0 : Comment 0

티스토리 툴바