2.X/6. Modeling Your Data

6-1-4. Denormalization and Concurrency

drscg 2017. 9. 23. 15:16

Of course, data denormalization has downsides too. The first disadvantage is that the index will be bigger because the _source document for every blog post is bigger, and there are more indexed fields. This usually isn’t a huge problem. The data written to disk is highly compressed, and disk space is cheap. Elasticsearch can happily cope with the extra data.

물론, 데이터 비정규화도 단점이 있다. 첫 번째 단점은 모든 블로그 포스트에 대한 _source document가 더 커지고, 더 많은 색인된 field가 있기 때문에, index가 더 커진다는 점이다. 이것은 일반적으로 큰 문제가 아니다. 디스크에 기록된 데이터는 많이 압축되고, 디스크 공간은 가격이 싸다. Elasticsearch는 별 문제없이 추가 데이터에 대응할 수 있다.

The more important issue is that, if the user were to change his name, all of his blog posts would need to be updated too. Fortunately, users don’t often change names. Even if they did, it is unlikely that a user would have written more than a few thousand blog posts, so updating blog posts with the scroll and bulk APIs would take less than a second.

더 중요한 문제는, 사용자가 자신의 이름을 변경하면, 그의 모든 블로그 게시물도 업데이트해야 한다는 것이다. 다행스럽게도, 사용자들은 이름을 자주 바꾸지는 않는다. 이름을 변경했다 하더라도, 한 사용자가 수천 개 이상의 블로그 게시물을 작성하지는 않았을 것이다. 따라서, scroll 과 bulk API를 이용해, 블로그 게시물을 업데이트하는 것은 약간의 시간으로 가능할 것이다.

However, let’s consider a more complex scenario in which changes are common, far reaching, and, most important, concurrent.

하지만, 지금까지의 일반적인 변화보다 더 복잡한 시나리오와, 가장 중요한 동시성을 고려해 보자.

In this example, we are going to emulate a filesystem with directory trees in Elasticsearch, much like a filesystem on Linux: the root of the directory is /, and each directory can contain files and subdirectories.

이 예제에서, Linux의 filesystem처럼, Elasticsearch에서 디렉토리 tree를 가지고, file system을 모방해 볼 것이다. root 디렉토리는 / 이고, 각 디렉토리는 파일과 하위 디렉토리를 가질 수 있다.

We want to be able to search for files that live in a particular directory, the equivalent of this:

아래의 명령과 동일한 기능을 가지도록, 특정 디렉토리에 있는 파일을 검색할 수 있어야 한다.

grep "some text" /clinton/projects/elasticsearch/*

This requires us to index the path of the directory where the file lives:

이를 위해서, 파일이 존재하는 디렉토리의 경로를 색인해야 한다.

PUT /fs/file/1
{
  "name":     "README.txt", 
  "path":     "/clinton/projects/elasticsearch", 
  "contents": "Starting a new Elasticsearch project is easy..."
}

파일의 이름

파일을 가지고 있는 디렉토리의 전체 경로

Note

Really, we should also index directory documents so we can list all files and subdirectories within a directory, but for brevity’s sake, we will ignore that requirement.

실제로는, 디렉토리 내의 모든 파일과 하위 디렉토리를 나열하도록, directory document도 색인해야 하나, 간단하게 하기 위해, 그런 요구 사항을 무시한다.

We also want to be able to search for files that live anywhere in the directory tree below a particular directory, the equivalent of this:

또한, 아래의 명령과 동일한 기능을 가지도록, 특정 디렉토리 아래, 디렉토리 tree 어딘가에 있는 파일을 검색할 수 있어야 한다.

grep -r "some text" /clinton

To support this, we need to index the path hierarchy:

이를 지원하기 위해, 경로 체계를 색인 해야 한다.

  • /clinton
  • /clinton/projects
  • /clinton/projects/elasticsearch

This hierarchy can be generated automatically from the path field using the path_hierarchytokenizer:

이 체계는 path_hierarchy tokenizer를 사용하여, path field에 자동으로 생성되게 할 수 있다.

PUT /fs
{
  "settings": {
    "analysis": {
      "analyzer": {
        "paths": { 
          "tokenizer": "path_hierarchy"
        }
      }
    }
  }
}

사용자 정의 paths analyzer는 기본 설정으로 path_hierarchy tokenizer를 사용한다.

The mapping for the file type would look like this:

file type에 대한 mapping은 아래와 같다.

PUT /fs/_mapping/file
{
  "properties": {
    "name": { 
      "type":  "string",
      "index": "not_analyzed"
    },
    "path": { 
      "type":  "string",
      "index": "not_analyzed",
      "fields": {
        "tree": { 
          "type":     "string",
          "analyzer": "paths"
        }
      }
    }
  }
}

name field은 정확한(exact) 이름을 가진다.

 

path field는 정확한(exact) 디렉토리 이름을 가진다. 반면에, path.tree field는 경로 체계를 포함하고 있다.

Once the index is set up and the files have been indexed, we can perform a search for files containing elasticsearch in just the /clinton/projects/elasticsearch directory like this:

index가 설정되고, 파일이 색인되면, /clinton/projects/elasticsearch 디렉토리에서 elasticsearch 를 포함하는 파일을 검색할 수 있다. 아래처럼.

GET /fs/file/_search
{
  "query": {
    "filtered": {
      "query": {
        "match": {
          "contents": "elasticsearch"
        }
      },
      "filter": {
        "term": { 
          "path": "/clinton/projects/elasticsearch"
        }
      }
    }
  }
}

이 디렉토리에서만 파일을 찾는다.

Every file that lives in any subdirectory under /clinton will include the term /clinton in the path.tree field. So we can search for all files in any subdirectory of /clinton as follows:

/clinton 아래의 모든 하위 디렉토리에 존재하는 모든 파일은, path.tree field에 /clinton 이라는 단어를 포함하고 있다. 따라서, 다음처럼, /clinton 의 모든 하위 디렉토리에서 모든 파일에 대해 검색할 수 있다.

GET /fs/file/_search
{
  "query": {
    "filtered": {
      "query": {
        "match": {
          "contents": "elasticsearch"
        }
      },
      "filter": {
        "term": { 
          "path.tree": "/clinton"
        }
      }
    }
  }
}

이 디렉토리나 그것의 하위 디렉토리에서 파일을 찾는다.

Renaming Files and Directoriesedit

So far, so good. Renaming a file is easy—a simple update or index request is all that is required. You can even use optimistic concurrency control to ensure that your change doesn’t conflict with the changes from another user:

지금까지는 아주 좋다. 파일의 이름을 변경하는 것은 간단하다. 간단한 update 나 index request가 필요한 전부이다. 이 변경이 다른 사용자의 변경과 충돌하지 않도록, 낙관적인 동시성 제어(optimistic concurrency control)를 사용해야 할 수도 있다.

PUT /fs/file/1?version=2 
{
  "name":     "README.asciidoc",
  "path":     "/clinton/projects/elasticsearch",
  "contents": "Starting a new Elasticsearch project is easy..."
}

version number는, index에 있는 document가, 동일한 version number를 가지고 있는 경우에만, 변경이 적용된다는 것을, 보장한다.

We can even rename a directory, but this means updating all of the files that exist anywhere in the path hierarchy beneath that directory. This may be quick or slow, depending on how many files need to be updated. All we would need to do is to use scroll to retrieve all the files, and the bulk API to update them. The process isn’t atomic, but all files will quickly move to their new home.

디렉토리 이름을 변경할 수도 있지만, 이것은 해당 디렉토리 아래, 경로 체계에 존재하는, 파일 모두를 업데이트하는 것을 의미한다. 이것은 업데이트해야 할 파일의 수에 따라, 느리거나 빠를 것이다. 파일 모두를 가져오기 위해, scroll 을 사용하고, 그것을 업데이트하기 위해 bulk API를 사용한다. 이 프로세스는 원자성(atomic)을 보장하지 않지만, 모든 파일은 빠르게 그들의 새로운 경로로 이동할 것이다.


'2.X > 6. Modeling Your Data' 카테고리의 다른 글

6-1-2. Denormalizing Your Data  (0) 2017.09.23
6-1-3. Field Collapsing  (0) 2017.09.23
6-1-5. Solving Concurrency Issues  (0) 2017.09.23
6-2. Nested Objects  (0) 2017.09.23
6-2-1. Nested Object Mapping  (0) 2017.09.23