InfraMongoDB

MongoDB Data Lake 설정 하기

  • AWS S3 와 Atlas Data Lake 간의 매핑의 정의
  • MongoDb의 Database 와 Collection 처럼 사용하기 위하여 데이터가 저장된 위치 및 데이터 파일에 대한 매핑을 정의함
  • 구성을 통해서 데이터 조회시 필터로 사용가능한 추가 필드를 얻을 수 있고, 스캔되는 데이터의 양을 줄여서 데이터 스캔 비용을 줄일 수 있음

구성 조회 및 설정을 위한 기본 명령 및 구조

  • Data Lake 설정 조회

     use admin
     db.runCommand( { "storageGetConfig" : 1 } )
    
  • Data Lake 설정 하기

     use admin
     db.runCommand( { "storageSetConfig" : <config> } )
    
    • <config> 기본 구성
     {
        "stores": [
           {
                 "s3": {
                    "name": "<string>",
                    "region": "<string>",
                    "bucket": "<string>",
                    "prefix": "<string>",
                    "delimiter": "<string>"
                 }
           }
        ],
        "databases": {
           "<database>": {
                 "<collection>": [
                    {
                       "store": "<string>",
                       "defaultFormat": "<string>",
                       "definition": "<string>"
                    }
                 ]
           }
        }
     }
    

Stores

stores 객체는 Data Lake와 관련된 데이터 저장소 배열을 정의 합니다. 데이터 저장소는 S3 버킷의 파일을 나타 냅니다.
Data Lake 는 stores 객체에 정의된 데이터 저장소에만 엑세스 가능 합니다.

  • stores.[n].s3
    • S3 Bucket 및 데이터에 대한 정의
  • stores.[n].s3.name
    • Store 이름으로 databases.database.collection.store 필드에 매핑 하기 위한 이름
  • stores.[n].s3.region
  • stores.[n].s3.bucket
    • AWS S3 버킷 이름, DataLake 구성시 설정한 AWS IAM 자격 증명을 통해 Data Lake 가 엑세스 할 수 있는 s3 버킷의 이름과 정확히 일치 해야 함
  • stores.[n].s3.prefix
    • 선택적으로 사용 할 수 있으며, S3 버킷의 접두사를 두어 database 설정시 definition의 루트가 됨
    • prefix를 지정하지 않을 경우 S3 버킷의 루트를 사용함
  • stores.[n].s3.delimiter
    • 선택적으로 사용 할 수 있으며, prefix 에서 요소들을 구분하는 구분문자
    • 생략 할 경우 기본 /를 사용함

Databases

데이터 베이스 및 콜렉션에 대한 정의를 나타내며, 각 콜렉션은 데이터 저장소의 store 객체와 매핑되어 집니다.

  • databases.<database>
    • Data Lake가 데이터 저장소의 데이터를 매핑하는 데이터 베이스의 이름
    • 데이터 베이스에는 여러개의 중첩된 <collection> 객체가 있을 수 있음
  • databases.<database>.<collection>
    • Data Lake가 데이터를 매핑하는 컬렉션의 이름으로 각 데이터베이스에 포함됨
    • 콜렉션에 정의되는 store 배열의 각 오브젝트는 콜렉션과 store의 오브젝트간의 매핑 된 정보
    • 콜렉션 이름을 직접 지정할 수 있지만, collectionName()을 통해 자동으로 콜렉션 이름을 지정 할 수 있음, 이 경우 콜렉션 이름은 *로 지정
      • 동적으로 콜렉션 이름을 지정하는 방법은 하단의 예제 참고
  • databases.<database>.<collection>.[n].store
    • 콜렉션에 매핑할 데이터 저장소의 이름입니다. stores 배열의 객체 이름과 일치 해야 합니다.
  • databases.<database>.<collection>.[n].defaultFormat
    • 선택 사항으로 store에 저장된 데이터를 검색 하는 동안 확장자가 없는 파일이 발견되면 Data Lake 가 가정하는 기본 형식을 지정합니다.
    • 생략할 경우 Data Lake는 파일의 몇 바이트를 스캔하여 파일 유형을 감지하려고 합니다.
      파일 형식이 CSV 또는 TVS 인 경우 데이터에 헤더행을 포함해야 합니다.
      • 지정 가능한 값은 아래와 같습니다.

        .json, .json.gz, .bson, .bson.gz, .avro, .avro.gz, .tsv, .tsv.gz, .csv, .csv.gz, .parquet
        
  • databases.<database>.<collection>.[n].definition
    • Data Lake 가 콜렉션에 매핑하기 전에 저장소에서 파일을 검색하고 구문 분석하는 방법을 제어 합니다.
    • Data Lake는 stores.[n].s3.prefix에 정의된 접두사를 포함하여 전체 경로를 만듭니다. 접두사의 경로에서의 모든 파일과 폴더를 사용하려면 /를 지정 합니다.
    • 예를 들어 S3에 metrics 라는 버킷이 아래의 구조로 구성 되어 있을 경우

      metrics
        |-- hardware
        |-- software
            |-- computed
      
    • definition/일 경우 metrics 하위 모든 폴더와 파일을 검색 합니다.
    • definition/hardware일 경우 hardware 하위의 모든 폴더와 파일을 검색 합니다.
    • 만약, store의 prefix 설정이 /software 일 경우 definition은 software 하위 경로만 지정 할 수 있습니다.
    • * 와일드 카드 문자를 정의에 추가 할 경우 Data Lake는 해당 지점의 모든 파일과 폴더를 경로에 포함하도록 지정 합니다.
      • 예를 들어 /software/computed*definition을 설정 한 경우 /software/computed-detailed, /software/computedArchive, /software/computed/errors와 같은 경로를 포함 하게 됩니다.
    • definition은 다음을 포함하여 구문 분석을 위한 추가 구문(Syntax)을 지원 합니다.
      • 파일 경로에서 데이터의 추가 필드를 지정 할 수 있습니다.
      • 정규식을 사용하여 필드 생성을 제어 할 수 있습니다.
      • 타임스템프별로 버킷의 파일 경계를 설정 할 수 있습니다.
        definition의 추가 구문을 이용하여 콜렉션 도큐먼트에 추가된 필드를 이용하여 Data Lake 가 스캔 해야 하는 폴더 및 파일의 범위를 축소 할 수 있습니다. 이는 비용을 절감 할 수 있는 방법 입니다.

Definition Syntax

  • 파일명을 구문 분석하여 필드로 추가 하기 위한 추가 구문 입니다.
  • Data Lake는 분석한 구문을 각각의 document 에 추가적인 field로 제공합니다.
  • Data Lake는 계산된 필드 값에 대한 쿼리를 파일 이름이 일치하는 파일에만 대상으로 지정 할 수 있습니다.
  • 파일 이름을 단일 구문 분석으로 사용 할 수 있습니다.

    /path/to/files/{<fieldA> <data-type>}
    
  • 파일 이름을 여러개의 구문 분석으로 사용 할 수 있습니다.

    /path/to/files/{<fieldA> <data-type>}-{fieldB> <data-type>}
    
  • 파일 이름을 정규식으로 이용하여 구문 분석으로 사용 할 수 있습니다.

    /path/to/files/prefix-{<faildA> <data-type>}-suffix
    
  • 구문 분석에서 사용 가능한 <data-type>int, string, date, isodate 가 있으면 자세한 내용은 https://docs.atlas.mongodb.com/reference/data-lake-configuration/#datalake-definition-data-types 를 참고하세요.

단일 구문 분석

  • accountingArchive 라는 스토어에 Unix 타임스템프 형식의 파일명의 데이터가 존재 한다면, 아래와 같이 구문 분석을 사용하여 invoiceDate 라는 필드를 추가로 생성 할 수 있습니다.
    • /invoices/1564671291998.json

      "databases": {
        "accounting": {
          "invoices": [
            {
              "store": "accountingArchive",
              "definition": "/invoices/{invoiceDate date}"
            }
          ]
        }
      }
      
    • Data Lake가 1564671291998.json 파일의 데이터를 각각의 document 로 만들 때 invoiceDate 라는 필드를 추가로 생성하고 ISODate("2019-08-01T14:54:51Z") 값을 삽입 합니다.
    • invoiceDate 필드를 쿼리로 사용할 경우 쿼리에 해당하는 파일만 스캔 대상으로 삼을 수 있습니다.

멀티 구문 분석

  • accountingArchive 라는 스토어에 invoice number 와 invoice date를 조합한 파일명의 데이터 파일이 존재 한 경우, 아래와 같이 구문 분석을 사용하여 invoiceNumber, invoiceDate 라는 필드를 추가로 생성 할 수 있습니다.
    • /invoices/MONGO12345-1564671291998.json

      "databases": {
        "accounting": {
          "invoices": [
            {
              "store": "accountingArchive",
              "definition": "/invoices/{invoiceNumber string}-{invoiceDate date}"
            }
          ]
        }
      }
      
    • Data Lake 가 /invoices/MONGO12345-1564671291998.json 파일의 데이터를 각각의 document 로 만들 때 invoiceNumber, invoiceDate 필드를 추가 합니다.
      • invoiceNumber : “MONGO12345”
      • invoiceDate: ISODate(“2019-08-01T14:54:51Z”)
    • 데이터 스캔시 invoiceNumber 와 invoiceDate를 포함하는 쿼리는 지정된 값과 일치하는 파일만 대상으로 할 수 있습니다.

정규식을 이용하여 구문 분석

  • accountingArchive 라는 스토어에 invoice number 와 invoice date를 조합한 파일명의 데이터 파일이 존재 한 경우, 아래와 같이 구문 분석을 사용 할 수 있습니다.
    • /invoices/MONGO12345-20190102.json
     "databases": {
        "accounting": {
           "invoices": [
              {
                 "store": "accountingArchive",
                 "definition": "/invoices/{invoiceNumber string}-{year int:\\d{4}}{month int:\\d{2}}{day int:\\d{2}}"
              }
           ]
        }
     }
    
    • 첫번째 세그먼트에서 String 타입의 invoiceNumber 를 파싱하여 invoiceNumber 필드에 추가 합니다.
    • 두번째 세그먼트에서 첫번재 숫자로 부터 4자리만 파싱하여 Int 타입의 year 필드에 추가 합니다.
    • 두번째 세그먼트에서 다음 2자리의 숫자를 파싱하여 Int 타입의 month 필드에 추가 합니다.
    • 두번째 세그먼트에서 그 다음 2자리의 숫자를 파싱하여 Int 타입의 day 필드에 추가 합니다.

           - invoiceNumber: "MONGO12345"
           - year: 2019
           - month: 01
           - day: 02
      

    정규식 문자열은 반드시 이스케이프 해야 합니다. 예를 들어 큰 따음표가 포함된 경우 또는 정규 표현문자(ex: \d, \s 등)를 사용한 경우 이스케이프(\)해야 합니다.

    • 생성된 모든 필드를 쿼리에 이용할 경우 해당 쿼리에 일치하는 파일만 스캔 대상으로 지정 합니다.
  • 정규식 표현은 string, int 데이터 타입에서만 사용 가능합니다.

Identify Ranges of Queryable Data from Filename

https://docs.atlas.mongodb.com/reference/data-lake-configuration/#datalake-advanced-definition-parse-range 참고

동적 콜렉션 생성

  • 다음 디렉토리 구조를 가지는 accountingArchive 저장소가 있는 경우

    invoices
      |-- SuperSoftware
      |-- UltraSoftware
      |-- MegaSoftware
    
  • 아래와 같이 정의 하여 콜렉션 이름을 지정 할 수 있습니다.

    "databases": {
      "invoices": {
        "*": [
          {
            "store": "accountingArchive",
            "definition": "/invoices/{collectionName()}/"
          }
        ]
      }
    }
    
    • 정의를 저장하면 다음과 같은 콜렉션을 얻을 수 있습니다.
      • SuperSoftware
      • UltraSoftware
      • MegaSoftware

파일 이름에서 콜렉션을 동적으로 생성할 경우 컬렉션 수는 Data Lake 에서 정확하게 보고 되지 않습니다.