'Elastic/Elasticsearch'에 해당되는 글 385건

  1. 2013.04.17 [Elasticsearch] 불일치 데이터 검증 툴
  2. 2013.04.17 [elasticsearch] Indices API - Snapshot
  3. 2013.04.17 [elasticsearch] Indices API - Optimize
  4. 2013.04.17 [elasticsearch] Indices API - Put Mapping
  5. 2013.04.17 [elasticsearch] Indices API - Aliases
  6. 2013.04.16 [elasticsearch] Core API - More Like This
  7. 2013.04.16 [elasticsearch] Core API - Search
  8. 2013.04.16 [elasticsearch] Core API - Get/Multi Get/Update
  9. 2013.04.16 [elasticsearch] Core API - Delete
  10. 2013.04.16 [elasticsearch] Core API - Index

[Elasticsearch] 불일치 데이터 검증 툴

Elastic/Elasticsearch 2013. 4. 17. 14:41

원문 : https://github.com/Aconex/scrutineer


 README.md

Analyses a secondary stream of information against a known point-of-truth and reports inconsistencies.

The Why

When you have a Lucene-based index of substantial size, say many hundreds of millions of records, what you want is confidence that your index is correct. In many cases, people use Solr/ElasticSearch/Compass to index their central database, mongodb, hbase etc so the index is a secondary storage of data.

How do you know if your index is accurate? Can you just reindex 500 million documents anytime you like? (That's the Aliens: "Nuke the site from Orbit... It's the only way to be sure" approach). No, if there ARE inconsistencies in your index, then you want to:

  • find the items that are incorrect (and only them)
  • do it fast

Scrutineer has been designed with this in mind, it can find any inconsistencies in your index fast.

How does this work?

Scrutineer relies on your data having 2 core properties:

  • an ID - a unique identifier for your object
  • a Version - something stored in your primary datastore for that object that represents the temporal state of that object

The Version property is commonly used in an Optimistic Locking pattern. If you store the ID & Version information in your secondary store (say, Solr/ElasticSearch) then you can always compare for any given item whether the version in secondary store is up to date.

Scrutineer takes a stream from your primary, and a stream from your secondary store, presumes they are sorted identically (more on that later) and walks the streams doing a merge comparison. It detects 4 states:

  1. Both items are identical (yay!)
  2. An ID is missing from the secondary stream (A missed add? maybe that index message you sent to Solr/ElasticSearch never made it, anyway, it's not there)
  3. An ID was detected in the secondary, but wasn't in the primary stream (A missed delete? something was deleted on the primary, but the secondary never got the memo)
  4. The ID exists in both streams, but the Version values are inconsistent (A missed update? similar to the missed add, this time perhaps an update to a row in your DB never made it to Solr/ElasticSearch)

Example

Here's an example, 2 streams in sorted order, one from the Database (your point-of-truth), and one from ElasticSearch (the one you're checking) with the : for each side:

DatabaseElasticSearch
1:123451:12345
2:234553:84757
3:847574:98765
4:987655:38475
6:346666:34556

Scrutineer picks up that:

  • ID '2' is missing from ElasticSearch
  • ID '5' was deleted from the database at some point, but ElasticSearch still has it in there
  • ID '6' is visible in ElasticSearch but appears to have the wrong version

Running Scrutineer

The very first thing you'll need to do is get your JDBC Driver jar and place it in the 'lib' directory of the unpacked package. We already have a JTDS driver in there if you're using SQL Server (that's just what we use).

bin/scrutineer \
            --jdbcURL=jdbc:jtds:sqlserver://mydbhost/mydb  \
            --jdbcDriverClass=net.sourceforge.jtds.jdbc.Driver \
            --jdbcUser=itasecret \
            --jdbcPassword=itsasecret   \
            --sql="select id,version from myobjecttype order by cast(id as varchar(100))" \
            --clusterName=mycluster \
            --indexName=myindex \
            --query="_type:myobjecttype" \
            --numeric

Note: if you're weirded out about that '...cast(...)' then don't worry, we'll explain that shortly.

  • jdbcURL – Standard JDBC URL you would use for your app to connect to your database
  • jdbcDriverClass - Fully qualified class name of your JDBC Driver (don't forget to put your JDBC Driver jar in the lib directory as said above!)
  • jdbcUser - user account to access your JDBC Database
  • jdbcPassword -- password required for the user credentials
  • sql - The SQL used to generate a lexicographical stream of ID & Version values (in that column order)
  • clusterName - this is your ElasticSearch cluster name used to autodetect and connect to a node in your cluster
  • indexName - the name of the index on your ElasticSearch cluster
  • query - A query_parser compatible search query that returns all documents in your ElasticSearch index relating to the SQL query you're using Since it is common for an index to contain a type-per-db-table you can use the "_type:" search query to filter for all values for that type.
  • numeric - use this if your query returns results numerically ordered

Output

Scrutineer writes any inconsistencies direct to Standard Error, in a well-defined, tab-separated format for easy parsing to feed into a system to reindex/cleanup. If we use the Example scenario above, this is what Scrutineer would print out:

NOTINSECONDARY    2    23455
MISMATCH    6    34666    secondaryVersion=34556
NOTINPRIMARY    5    38475

The general format is:

FailureType\t**ID**\t**VERSION**\t**Optional:Additional Info**

NOTINSECONDARY

This means you are missing this item in your secondary and you should reindex/re-add to your secondary stream

MISMATCH

This means the version of the object stored in the secondary is not the same information as the primary, and you should reindex

NOTINPRIMARY

The object was removed from the Primary store, but the secondary still has it. You should remove this item from your secondary.

Scrutineer does not report when items match, we'll presume you're just fine with that...

Memory

By default, Scrutineer allocates 256m to the Java Heap, which is used for sort, and ElasticSearch result buffers. This should be more than enough for the majority of cases but if you find you get an OutOfMemoryError, you can override the JAVA_OPTS environment variable to provide more heap. e.g.

export JAVA_OPTS=-Xmx1048m

Sorting

VERY IMPORTANT: Scrutineer relies on both streams to be sorted using an identical mechanism. It requires input streams to be in lexicographical (default) or numerical (indicate using --numeric) sort order.

ElasticSearch

Since Aconex uses ElasticSearch, Scrutineer supports ES out of the box, but it would not be difficult for others to integrate a Solr stream and wire something up. Happy to take Pull Requests!

What are the 'best practices' for using Scrutineer?

The authors of Scrutineer, Aconex, index content from a JDBC data source and index using ElasticSearch. We do the following:

  • In the database table of the object being indexed we add an Insert/Update trigger to populate a 'lastupdated' timestamp column as our Version property
  • When we index into ElasticSearch, we set the Version property of the item using the VersionType.EXTERNAL setting.
  • We create an SQL Index on this tuple so these 2 fields can be retrieved from the database very fast

Assumptions

  • Your Version property is Long compatible. You can use java.sqlTimestamps column types too as a Version (that's what we do)
  • Aconex is DB->ElasticSearch centric at the moment. We've tried to keep things loosely coupled, so it should be simple to add further integration points for other Primary & Secondary sources (HBase, MongoDB, Solr).

JDBC Drivers

Scrutineer ships with the SQL Server JTDS driver by default (it's what we use). All you should need to do is drop your own JDBC driver in the 'repo' sub-directory of the Scrutineer distribution (where all the other jars are). We use the Maven AppAssembler plugin which is configured to automatically load all JARs in this path onto the classpath.

Building

Scrutineer is a Maven project, which really should just build right out of the box if you have Maven installed. Just type:

mvn package

And you should have a Tarball in the 'target' sub-directory.

Submitting Pull Requests

First, Please add unit tests!

Second, Please add integration tests!

Third, We have tightened up the quality rule set for CheckStyle, PMD etc pretty hard. Before you issue a pull request, please run:

mvn verify

which will run all quality checks. Sorry to be super-anal, but we just like Clean Code.

Roadmap

  • Scrutineer currently only runs in a single thread based on a single stream.
    It would be good to provide a 'manifest' to Scrutineer to outline a set of stream verifications to perform, perhaps one for each type you have so that your multi-core system can perform multiple stream comparisons in parallel.

  • Incremental checking – Right now Scrutineer checks the whole thing, BUT if you are using timestamp-based versions, there's no reason it couldn't only check objects that were changed after the last known full verification. This would require one to keep track of deletes on the primary stream (perhaps an OnDelete Trigger in your SQL database) so that IDs that were deleted in the primary stream after the last full check could be detected correctly.

  • Obviously we'd love to have a Solr implementation here, we hope the community can help here.

:

[elasticsearch] Indices API - Snapshot

Elastic/Elasticsearch 2013. 4. 17. 14:40

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

정보 교환이 목적입니다.


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

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



[elasticsearch API 리뷰]

원문 링크 : http://www.elasticsearch.org/guide/reference/api/admin-indices-gateway-snapshot/


이 API 는 shared storage gateway 에서 동작 합니다.

local storage gateway 에서는 필요 하지 않다는 점을 유의 하시기 바랍니다.


- snapshot 정보는 shared storage location 에 저장 됩니다.


아래는 간단한 Java Code 예제 입니다.


[Java 예제]

request.indices("blog")

.operationThreading(BroadcastOperationThreading.THREAD_PER_SHARD);


response = indices.gatewaySnapshot(request).actionGet();


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

:

[elasticsearch] Indices API - Optimize

Elastic/Elasticsearch 2013. 4. 17. 12:52

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

정보 교환이 목적입니다.


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

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



[elasticsearch API 리뷰]

원문 링크 : http://www.elasticsearch.org/guide/reference/api/admin-indices-optimize/


이 API 는 indices 를 최적화 시킨다.

검색 시 성능 향상을 가져 옴.


아래는 원문의 Request Parameters 이다.

Request Parameters

The optimize API accepts the following request parameters:

NameDescription
max_num_segmentsThe number of segments to optimize to. To fully optimize the index, set it to 1. Defaults to simply checking if a merge needs to execute, and if so, executes it.
only_expunge_deletesShould the optimize process only expunge segments with deletes in it. In Lucene, a document is not deleted from a segment, just marked as deleted. During a merge process of segments, a new segment is created that does not have those deletes. This flag allow to only merge segments that have deletes. Defaults to false.
refreshShould a refresh be performed after the optimize. Defaults to true.
flushShould a flush be performed after the optimize. Defaults to true.
wait_for_mergeShould the request wait for the merge to end. Defaults to true. Note, a merge can potentially be a very heavy operation, so it might make sense to run it set to false.

- 설명이 잘나와 있어서 요약만 합니다.

- fully optimize 를 위해서는 max_num_segments : 1

- only_expunge_deletes 가 true 이면 삭제 마킹만

- wait_for_merge false 를 이용해서 대용량 처리


파라미터를 이용한 샘플 코드를 보기로 하겠습니다.


[Java 예제코드]

response = builder.setIndices("blog")

.setMaxNumSegments(1) // full optimize 를 위해서는 1, 기본은 설정을 하지 않으면 simply checking 을 

.setOnlyExpungeDeletes(false) // 기본 false

.setWaitForMerge(true)

.setOperationThreading(BroadcastOperationThreading.THREAD_PER_SHARD)

.execute()

.actionGet();

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


OptimizeRequest 와 OptimizeRequestBuilder 이 두가지를 이용해서 구현 가능 함.


:

[elasticsearch] Indices API - Put Mapping

Elastic/Elasticsearch 2013. 4. 17. 11:32

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

정보 교환이 목적입니다.


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

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



[elasticsearch API 리뷰]

원문 링크 : http://www.elasticsearch.org/guide/reference/api/admin-indices-put-mapping/


이 API 는 Mapping type  을 정의 할 수 있도록 합니다.


[Merging & Conflicts]

- 이미 존재 하는 field 에 다른 type 으로 mapping 시도 시 merge & conflict 동작을 하게 됩니다.

- ignore_conflicts 설정을 true 로 할 경우 다른 type 에 대한 conflict 에러를 회피 할 수 있습니다.

- 하지만, 정상적인 동작은 하지 않는다는 점에 주의를 하셔야 합니다.

kimchy said :

You can't change the type of a field mapped, even when ignore_conflicts is set to true. Ignore conflicts simply does that, ignore the conflicts and applies what it can, it does not apply conflicts.



※ 정리 하면,

- 기정의한 field type 에 대한 변경을 하지 않도록 유의 합니다.

- 만약 변경이 필요 하다면, object type 으로 신규 추가 하거나 multi field 를 활용 하시기 바랍니다.


:

[elasticsearch] Indices API - Aliases

Elastic/Elasticsearch 2013. 4. 17. 10:26

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

정보 교환이 목적입니다.


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

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



[elasticsearch API 리뷰]

원문 링크 : http://www.elasticsearch.org/guide/reference/api/admin-indices-aliases/


[Indices Aliases]

이 API 는 index name 의 별칭을 생성 및 삭제를 할 수 있도록 한다.

하나의 별칭에 여러개의 index name 을 등록 할 수도 있으며 filter 를 통해 같은 index 의 또 다른 view 를 구현 할 수 있다.

관련 예제는 원문에 잘 나와 있기 때문에 Java API 샘플 코드만 살펴 보도록 한다.


[샘플코드 : IndicesAliasesRequestBuilder.java]

clientManager.openClient();                    // singletone 객체를 이용한 connection manager

Client client = clientManager.getClient();

AdminClient admin = client.admin();

ClusterAdminClient cluster = admin.cluster();

IndicesAdminClient indices = admin.indices();


IndicesAliasesRequestBuilder aliases = new IndicesAliasesRequestBuilder(indices);

IndicesAliasesResponse response = aliases.addAlias("blog", "aliases_blog2")

.removeAlias("blog",  "aliases_blog1")

.execute()

.actionGet();


log.debug("{}", response);        // slf4j logger


[Filtered Aliases]

curl -XPOST 'http://localhost:9200/_aliases' -d ' { "actions" : [ { "add" : { "index" : "test1", "alias" : "alias2", "filter" : { "term" : { "user" : "kimchy" } } } } ]

}'

- 이미 위에서 언급 했듯이 RDBMS 에서 사용하는 view table 과 비슷한 목적으로 사용이 가능 하다고 이해 하면 쉽다.

:

[elasticsearch] Core API - More Like This

Elastic/Elasticsearch 2013. 4. 16. 22:13

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

정보 교환이 목적입니다.


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

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



[elasticsearch API 리뷰]

원문 링크 : http://www.elasticsearch.org/guide/reference/api/more-like-this/


이 기능은 like  검색과 같은 기능을 제공해 줍니다.

단,  match 단위는 term 이라는 점에 유의 하셔야 합니다.

좀더 상세한 내용은 아래 링크를 참고 하시기 바라며, 관련 코드는 MoreLikeThisQueryBuilder.java 를 보시기 바랍니다.


[More Like This 상세]

http://www.elasticsearch.org/guide/reference/query-dsl/mlt-query/


:

[elasticsearch] Core API - Search

Elastic/Elasticsearch 2013. 4. 16. 18:43

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

정보 교환이 목적입니다.


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

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



[elasticsearch API 리뷰]

원문 링크 : http://www.elasticsearch.org/guide/reference/api/search/


[Filter]

- http://www.elasticsearch.org/guide/reference/api/search/filter/

- 실행한 query 결과를 바탕으로 filtering 할 수 있는 옵션


[Rescore]

- http://www.elasticsearch.org/guide/reference/api/search/rescore/

- search_type 이 scan 또는 count 일 경우 실행 되지 않음

- query 와 filter 를 통해서 결과를 return 함.


[Highlight]

- http://www.elasticsearch.org/guide/reference/api/search/highlighting.html

- store : yes 와 term_vector : with_positions_offsets 설정이 되어 있어야 함.

- query 생성 시 아래와 같은 속성으로 설정

highlight

    .pre_tags

    .post_tags

    .tags_schema

    .fields


[Highlighted Fragments]

{
    "query" : {...},
    "highlight" : {
        "order" : "score",
        "fields" : {
            "content" : {"fragment_size" : 150, "number_of_fragments" : 3}
        }
    } 

}

{
    "query" : {...},
    "highlight" : {
        "fields" : {
            "_all" : {},
            "bio.title" : {"number_of_fragments" : 0}
        }
    }
}

- highlight character size = fragment_size (기본 100)

- highlight size = number_of_fragments (기본 5)

- number_of_fragments=0 이면 highlight 된 전체 내용을 return 함.

- boundary characters 는

    . boundary_chars 와 boundary_max_scan 속성을 갖는다.


[Fields]

- http://www.elasticsearch.org/guide/reference/api/search/fields.html

- 검색 결과에 화면에 보여주기 위한 field 를 정의 함

- 기본 store : yes 설정이 되어야 하면 no 라면 _source  값을 load 하게 됨.


[Script Fields]

- http://www.elasticsearch.org/guide/reference/api/search/script-fields/

- http://www.elasticsearch.org/guide/reference/modules/scripting/

- 쿼리 결과에 대한 별도의 연산 작업을 통해 지정한 field 명으로 연산된 값을 return 한다.

{

"query" : { ... }, "script_fields" : { "test1" : { "script" : "doc['my_field_name'].value * 2" }, "test2" : { "script" : "doc['my_field_name'].value * factor", "params" : { "factor" : 2.0 } } } 

}


Its important to understand the difference between doc['my_field'].value and _source.my_field.


[Preference]

- http://www.elasticsearch.org/guide/reference/api/search/preference/

- 검색 요청 시 shard control 을 통해서 사용


[Term Facet]

- http://www.elasticsearch.org/guide/reference/api/search/facets/terms-facet/

{ "query" : { "match_all" : { } }, "facets" : { "tag" : { "terms" : { "field" : "tag", "size" : 10, "order" : "term" } } }

}

- tag field 에서 가장 빈번한 term(size) 10 개, ordering 은 term 으로 수행.

- ordering option 은 count, term, reverse_count, reverse_term (기본 count)


[Range Facet]

- http://www.elasticsearch.org/guide/reference/api/search/facets/range-facet/

- range facet 을 사용하기 위해서는 IndexNumericFieldData(RangeFacetExecutor.java) 를 가져야 함.

- key and value 에서는 key 는 range 비교 항목으로 사용하고, value 는 비교된 결과에 aggregate 연산(total)을 함

- script key and value 사용 가능 함

{ "query" : { "match_all" : {} }, "facets" : { "range1" : { "range" : { "key_script" : "doc['date'].date.minuteOfHour", "value_script" : "doc['num1'].value", "ranges" : [ { "to" : 50 }, { "from" : 20, "to" : 70 }, { "from" : 70, "to" : 120 }, { "from" : 150 } ] } } }

}


[Statistical Facet]

Statistical facet allows to compute statistical data on a numeric fields. The statistical data include count, total, sum of squares, mean (average), minimum, maximum, variance, and standard deviation. 

- numeric fields 에 대해서 통계적 데이터를 계산함.

- script field 와 multi field 지원 함.


[Term Stats Facet]

- term 과 statistical 조합

- size 속성의 기본 값은 10

- size 가 0 인 경우 전체 matching term 을 return 한다. (주의, 너무 많은 결과가 나올 수 있음)

- ordering 옵션은 아래와 같다.

term, reverse_term, count, reverse_count, total, reverse_total, min, reverse_min, max, reverse_max, mean, reverse_mean. Defaults to count.



:

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

Elastic/Elasticsearch 2013. 4. 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 를 사용할 것을 추천 합니다.

:

[elasticsearch] Core API - Delete

Elastic/Elasticsearch 2013. 4. 16. 15:03

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

정보 교환이 목적입니다.


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

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



[elasticsearch 리뷰]

원문 링크 : http://www.elasticsearch.org/guide/reference/api/delete/


Parent

- routing 설정과 동일하게 동작 함

Replication Type
- 기본 sync 로 동작 하면 async 설정 가능 함
- async 설정 시 primary shard 만 적용 되면 성공

:

[elasticsearch] Core API - Index

Elastic/Elasticsearch 2013. 4. 16. 14:56

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

정보 교환이 목적입니다.


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

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



[elasticsearch 리뷰]

원문 링크 : http://www.elasticsearch.org/guide/reference/api/index_/


Automatic Index Creation

- 자동으로 인덱스를 생성 하거나 field 를 생성 할수 있도록 하는 옵션


Versioning

- 본문에 나와 있듯이 read-then-update transaction 에 좋은 사례로 사용됨

- http://en.wikipedia.org/wiki/Optimistic_concurrency_control


Operation Type

- 강제로 create 하도록 설정 가능 함 

Automatic ID Generation

- _id 에 해당 하는 값이 자동으로 생성 됨


Routing

- document 의 id 값을 hashing 해서 shard 에 저장함


Parents & Children

- indexing 시에 명시적으로 parent 를 이용해서 child document 를 색인 할 수 있다.

- _parent 참고


Timestamp

- mapping 설정에서 _tmestamp 참고


TTL

- 문서의 expiration 시간을 설정 함

- mapping 설정에서 _ttl 참고


Distributed

- 기본 primary shard 로 저장을 하는데 routing 설정을 통해서 분산 저장 설정을 함


Write Consistency

- 쓰기 동작에 대한 유효성 설정정

- success 조건은 quorum (>replicas/2+1)


Asynchronous Replication

- 기본 sync 방식으로 동작하나, async 설정이 가능 함.

- async 설정 시 primary shard 에 저장이 되면 성공 임.


Refresh

- 검색과 색인 관점에서 성능에 문제가 되지 않는지 검증 하고 설정 해야 함.

- true 설정 시 realtime 적용됨


Timeout

- 간혹 primary shard 가 응답하지 못할 수가 있기 때문에 timeout 값을 설정 함.

: