본문 바로가기
WIKI 기술 지식 베이스

Anatomy of a workload

원문 보기 위키 갱신

출처: 문서

본문

Anatomy of a workload

워크로드는 하나 이상의 벤치마킹 시나리오에 대한 명세예요. 모든 워크로드는 다음 파일과 디렉터리를 포함해요:

  • workload.json: 모든 워크로드 설정을 포함해요.
  • index.json: 문서 매핑, 파라미터, 인덱스 설정을 포함해요.
  • files.txt: 데이터 코퍼스 파일 이름을 포함해요.
  • _test-procedures: 대부분의 워크로드는 default.json에 구성된 하나의 기본 테스트 프로시저만 포함해요.
  • _operations: 테스트 프로시저에서 사용되는 모든 작업을 포함해요.
  • workload.py: 테스트에 더 동적인 기능을 추가해요.

workload.json

workload.json 파일은 보통 다음 요소를 포함해요:

  • indices: 워크로드에 사용되는 관련 인덱스와 인덱스 템플릿을 정의해요. 인덱스를 생성하려면 name을 지정하세요. 인덱스에 정의를 추가하려면 body 옵션을 사용하고 인덱스 정의가 포함된 JSON 파일을 가리키세요.
  • corpora: 워크로드에 사용되는 모든 문서 코퍼스를 정의해요. 여기에는 문서가 포함된 소스 파일과 각 파일의 문서 수가 포함돼요.
  • operations: 선택 사항. 워크로드가 수행하는 OpenSearch API 작업과 해당 작업이 매개변수화되는 방식을 나열해요. 예를 들어, OpenSearch Benchmark가 문서를 쓸 수 있는 벤치마크 클러스터에 인덱스를 생성하는 create-index라는 작업을 나열할 수 있어요.
  • schedule: 작업과 작업이 인라인으로 실행되는 순서를 정의해요. 또는 operations를 사용하여 작업을 그룹화하고 test_procedures 매개변수로 작업 순서를 지정할 수 있어요.

다음 예제 워크로드는 이러한 요소가 함께 작동하는 모습을 보여줘요. 이 워크로드를 자신의 벤치마크 구성에서 실행할 수 있어요:

{
  "description": "Tutorial benchmark for OpenSearch Benchmark",
  "indices": [
    {
      "name": "movies",
      "body": "index.json"
    }
  ],
  "corpora": [
    {
      "name": "movies",
      "documents": [
        {
          "source-file": "movies-documents.json",
          "document-count": 11658903, # Fetch document count from command line
          "uncompressed-bytes": 1544799789 # Fetch uncompressed bytes from command line
        }
      ]
    }
  ],
  "schedule": [
    {
      "operation": {
        "operation-type": "create-index"
      }
    },
    {
      "operation": {
        "operation-type": "cluster-health",
        "request-params": {
          "wait_for_status": "green"
        },
        "retry-until-success": true
      }
    },
    {
      "operation": {
        "operation-type": "bulk",
        "bulk-size": 5000
      },
      "warmup-time-period": 120,
      "clients": 8
    },
    {
      "operation": {
        "name": "query-match-all",
        "operation-type": "search",
        "body": {
          "query": {
            "match_all": {}
          }
        }
      },
      "iterations": 1000,
      "target-throughput": 100
    }
  ]
}

index.json

index.json 파일은 create-index 작업 중 워크로드 문서에 대한 데이터 매핑, 인덱싱 파라미터, 인덱스 설정을 정의해요.

OpenSearch Benchmark가 워크로드용 인덱스를 생성할 때 index.json 파일의 인덱스 설정과 매핑 템플릿을 사용해요. index.json 파일의 매핑은 files.txt 파일에 저장된 워크로드 코퍼스의 단일 문서 매핑을 기반으로 해요. 다음은 nyc_taxis 워크로드의 index.json 파일 예시예요. number_of_shards, number_of_replicas, query_cache_enabled, requests_cache_enabled 같은 필드를 사용자 지정할 수 있어요.

{
  "settings": {
    "index.number_of_shards": {% raw %}{{number_of_shards | default(1)}}{% endraw %},
    "index.number_of_replicas": {% raw %}{{number_of_replicas | default(0)}}{% endraw %},
    "index.queries.cache.enabled": {% raw %}{{query_cache_enabled | default(false) | tojson}}{% endraw %},
    "index.requests.cache.enable": {% raw %}{{requests_cache_enabled | default(false) | tojson}}{% endraw %}
  },
  "mappings": {
    "_source": {
      "enabled": {% raw %}{{ source_enabled | default(true) | tojson }}{% endraw %}
    },
    "properties": {
      "surcharge": {
        "scaling_factor": 100,
        "type": "scaled_float"
      },
      "dropoff_datetime": {
        "type": "date",
        "format": "yyyy-MM-dd HH:mm:ss"
      },
      "trip_type": {
        "type": "keyword"
      },
      "mta_tax": {
        "scaling_factor": 100,
        "type": "scaled_float"
      },
      "rate_code_id": {
        "type": "keyword"
      },
      "passenger_count": {
        "type": "integer"
      },
      "pickup_datetime": {
        "type": "date",
        "format": "yyyy-MM-dd HH:mm:ss"
      },
      "tolls_amount": {
        "scaling_factor": 100,
        "type": "scaled_float"
      },
      "tip_amount": {
        "type": "half_float"
      },
      "payment_type": {
        "type": "keyword"
      },
      "extra": {
        "scaling_factor": 100,
        "type": "scaled_float"
      },
      "vendor_id": {
        "type": "keyword"
      },
      "store_and_fwd_flag": {
        "type": "keyword"
      },
      "improvement_surcharge": {
        "scaling_factor": 100,
        "type": "scaled_float"
      },
      "fare_amount": {
        "scaling_factor": 100,
        "type": "scaled_float"
      },
      "ehail_fee": {
        "scaling_factor": 100,
        "type": "scaled_float"
      },
      "cab_color": {
        "type": "keyword"
      },
      "dropoff_location": {
        "type": "geo_point"
      },
      "vendor_name": {
        "type": "text"
      },
      "total_amount": {
        "scaling_factor": 100,
        "type": "scaled_float"
      },
      "trip_distance": {% raw %}{%- if trip_distance_mapping is defined %} {{ trip_distance_mapping | tojson }} {%- else %}{% endraw %} {
        "scaling_factor": 100,
        "type": "scaled_float"
      }{% raw %}{%- endif %}{% endraw %},
      "pickup_location": {
        "type": "geo_point"
      }
    },
    "dynamic": "strict"
  }
}

files.txt

files.txt 파일은 워크로드 데이터를 저장하는 파일을 나열해요. 이 파일들은 일반적으로 압축된 JSON 파일로 저장돼요.

_operations and _test-procedures

워크로드를 더 읽기 쉽게 만들기 위해 _operations와 _test-procedures가 두 개의 디렉터리로 분리되어 있어요.

_operations 디렉터리에는 테스트 프로시저가 사용할 수 있는 모든 지원 작업을 나열하는 default.json 파일이 포함되어 있어요. nyc_taxis 같은 일부 워크로드는 snapshot 작업 같은 기능별 작업을 나열하는 추가 .json 파일을 포함해요. 다음 JSON 예제는 nyc_taxis 워크로드의 작업 목록을 보여줘요:

    {
      "name": "index",
      "operation-type": "bulk",
      "bulk-size": {% raw %}{{bulk_size | default(10000)}}{% endraw %},
      "ingest-percentage": {% raw %}{{ingest_percentage | default(100)}}{% endraw %}
    },
    {
      "name": "update",
      "operation-type": "bulk",
      "bulk-size": {% raw %}{{bulk_size | default(10000)}},
      "ingest-percentage": {{ingest_percentage | default(100)}},
      "conflicts": "{{conflicts | default('random')}}",
      "on-conflict": "{{on_conflict | default('update')}}",
      "conflict-probability": {{conflict_probability | default(25)}},
      "recency": {{recency | default(0)}}{% endraw %}
    },
    {
      "name": "wait-until-merges-finish",
      "operation-type": "index-stats",
      "index": "_all",
      "condition": {
        "path": "_all.total.merges.current",
        "expected-value": 0
      },
      "retry-until-success": true,
      "include-in-reporting": false
    },
    {
      "name": "default",
      "operation-type": "search",
      "body": {
        "query": {
          "match_all": {}
        }
      }
    },
    {
      "name": "range",
      "operation-type": "search",
      "body": {
        "query": {
          "range": {
            "total_amount": {
              "gte": 5,
              "lt": 15
            }
          }
        }
      }
    },
    {
      "name": "distance_amount_agg",
      "operation-type": "search",
      "body": {
        "size": 0,
        "query": {
          "bool": {
            "filter": {
              "range": {
                "trip_distance": {
                  "lt": 50,
                  "gte": 0
                }
              }
            }
          }
        },
        "aggs": {
          "distance_histo": {
            "histogram": {
              "field": "trip_distance",
              "interval": 1
            },
            "aggs": {
              "total_amount_stats": {
                "stats": {
                  "field": "total_amount"
                }
              }
            }
          }
        }
      }
    },
    {
      "name": "autohisto_agg",
      "operation-type": "search",
      "body": {
        "size": 0,
        "query": {
          "range": {
            "dropoff_datetime": {
              "gte": "01/01/2015",
              "lte": "21/01/2015",
              "format": "dd/MM/yyyy"
            }
          }
        },
        "aggs": {
          "dropoffs_over_time": {
            "auto_date_histogram": {
              "field": "dropoff_datetime",
              "buckets": 20
            }
          }
        }
      }
    },
    {
      "name": "date_histogram_agg",
      "operation-type": "search",
      "body": {
        "size": 0,
        "query": {
          "range": {
              "dropoff_datetime": {
              "gte": "01/01/2015",
              "lte": "21/01/2015",
              "format": "dd/MM/yyyy"
            }
          }
        },
        "aggs": {
          "dropoffs_over_time": {
            "date_histogram": {
              "field": "dropoff_datetime",
              "calendar_interval": "day"
            }
          }
        }
      }
    },
    {
      "name": "date_histogram_calendar_interval",
      "operation-type": "search",
      "body": {
        "size": 0,
        "query": {
          "range": {
            "dropoff_datetime": {
              "gte": "2015-01-01 00:00:00",
              "lt": "2016-01-01 00:00:00"
            }
          }
        },
        "aggs": {
          "dropoffs_over_time": {
            "date_histogram": {
              "field": "dropoff_datetime",
              "calendar_interval": "month"
            }
          }
        }
      }
    },
    {
      "name": "date_histogram_calendar_interval_with_tz",
      "operation-type": "search",
      "body": {
        "size": 0,
        "query": {
          "range": {
            "dropoff_datetime": {
              "gte": "2015-01-01 00:00:00",
              "lt": "2016-01-01 00:00:00"
            }
          }
        },
        "aggs": {
          "dropoffs_over_time": {
            "date_histogram": {
              "field": "dropoff_datetime",
              "calendar_interval": "month",
              "time_zone": "America/New_York"
            }
          }
        }
      }
    },
    {
      "name": "date_histogram_fixed_interval",
      "operation-type": "search",
      "body": {
        "size": 0,
        "query": {
          "range": {
            "dropoff_datetime": {
              "gte": "2015-01-01 00:00:00",
              "lt": "2016-01-01 00:00:00"
            }
          }
        },
        "aggs": {
          "dropoffs_over_time": {
            "date_histogram": {
              "field": "dropoff_datetime",
              "fixed_interval": "60d"
            }
          }
        }
      }
    },
    {
      "name": "date_histogram_fixed_interval_with_tz",
      "operation-type": "search",
      "body": {
        "size": 0,
        "query": {
          "range": {
            "dropoff_datetime": {
              "gte": "2015-01-01 00:00:00",
              "lt": "2016-01-01 00:00:00"
            }
          }
        },
        "aggs": {
          "dropoffs_over_time": {
            "date_histogram": {
              "field": "dropoff_datetime",
              "fixed_interval": "60d",
              "time_zone": "America/New_York"
            }
          }
        }
      }
    },
    {
      "name": "date_histogram_fixed_interval_with_metrics",
      "operation-type": "search",
      "body": {
        "size": 0,
        "query": {
          "range": {
            "dropoff_datetime": {
              "gte": "2015-01-01 00:00:00",
              "lt": "2016-01-01 00:00:00"
            }
          }
        },
        "aggs": {
          "dropoffs_over_time": {
            "date_histogram": {
              "field": "dropoff_datetime",
              "fixed_interval": "60d"
            },
            "aggs": {
              "total_amount": { "stats": { "field": "total_amount" } },
              "tip_amount": { "stats": { "field": "tip_amount" } },
              "trip_distance": { "stats": { "field": "trip_distance" } }
            }
          }
        }
      }
    },
    {
      "name": "auto_date_histogram",
      "operation-type": "search",
      "body": {
        "size": 0,
        "query": {
          "range": {
            "dropoff_datetime": {
              "gte": "2015-01-01 00:00:00",
              "lt": "2016-01-01 00:00:00"
            }
          }
        },
        "aggs": {
          "dropoffs_over_time": {
            "auto_date_histogram": {
              "field": "dropoff_datetime",
              "buckets": "12"
            }
          }
        }
      }
    },
    {
      "name": "auto_date_histogram_with_tz",
      "operation-type": "search",
      "body": {
        "size": 0,
        "query": {
          "range": {
            "dropoff_datetime": {
              "gte": "2015-01-01 00:00:00",
              "lt": "2016-01-01 00:00:00"
            }
          }
        },
        "aggs": {
          "dropoffs_over_time": {
            "auto_date_histogram": {
              "field": "dropoff_datetime",
              "buckets": "13",
              "time_zone": "America/New_York"
            }
          }
        }
      }
    },
    {
      "name": "auto_date_histogram_with_metrics",
      "operation-type": "search",
      "body": {
        "size": 0,
        "query": {
          "range": {
            "dropoff_datetime": {
              "gte": "2015-01-01 00:00:00",
              "lt": "2016-01-01 00:00:00"
            }
          }
        },
        "aggs": {
          "dropoffs_over_time": {
            "auto_date_histogram": {
              "field": "dropoff_datetime",
              "buckets": "12"
            },
            "aggs": {
              "total_amount": { "stats": { "field": "total_amount" } },
              "tip_amount": { "stats": { "field": "tip_amount" } },
              "trip_distance": { "stats": { "field": "trip_distance" } }
            }
          }
        }
      }
    },
    {
      "name": "desc_sort_tip_amount",
      "operation-type": "search",
      "index": "nyc_taxis",
      "body": {
        "query": {
          "match_all": {}
        },
        "sort" : [
          {"tip_amount" : "desc"}
        ]
      }
    },
    {
      "name": "asc_sort_tip_amount",
      "operation-type": "search",
      "index": "nyc_taxis",
      "body": {
        "query": {
          "match_all": {}
        },
        "sort" : [
          {"tip_amount" : "asc"}
        ]
      }
    }

_test-procedures 디렉터리에는 워크로드가 수행하는 작업 순서를 설정하는 default.json 파일이 포함되어 있어요. _operations 디렉터리와 마찬가지로 _test-procedures 디렉터리에도 nyc_taxis의 searchable_snapshots.json 같은 기능별 테스트 프로시저가 포함될 수 있어요. 다음 예제는 nyc_taxis의 검색 가능한 스냅샷 테스트 프로시저를 보여줘요:

 {
      "name": "searchable-snapshot",
      "description": "Measuring performance for Searchable Snapshot feature. Based on the default test procedure 'append-no-conflicts'.",
      "schedule": [
        {
          "operation": "delete-index"
        },
        {
          "operation": {
            "operation-type": "create-index",
            "settings": {% raw %}{%- if index_settings is defined %} {{ index_settings | tojson }} {%- else %}{
              "index.codec": "best_compression",
              "index.refresh_interval": "30s",
              "index.translog.flush_threshold_size": "4g"
            }{%- endif %}{% endraw %}
          }
        },
        {
          "name": "check-cluster-health",
          "operation": {
            "operation-type": "cluster-health",
            "index": "nyc_taxis",
            "request-params": {
              "wait_for_status": {% raw %}"{{ cluster_health | default('green') }}"{% endraw %},
              "wait_for_no_relocating_shards": "true"
            },
            "retry-until-success": true
          }
        },
        {
          "operation": "index",
          "warmup-time-period": 240,
          "clients": {% raw %}{{ bulk_indexing_clients | default(8) }},
          "ignore-response-error-level": "{{ error_level | default('non-fatal') }}"{% endraw %}
        },
        {
          "name": "refresh-after-index",
          "operation": "refresh"
        },
        {
          "operation": {
            "operation-type": "force-merge",
            "request-timeout": 7200
            {% raw %}{%- if force_merge_max_num_segments is defined %}{% endraw %},
            "max-num-segments": {% raw %}{{ force_merge_max_num_segments | tojson }}{% endraw %}
            {% raw %}{%- endif %}{% endraw %}
          }
        },
        {
          "name": "refresh-after-force-merge",
          "operation": "refresh"
        },
        {
          "operation": "wait-until-merges-finish"
        },
        {
          "operation": "create-snapshot-repository"
        },
        {
          "operation": "delete-snapshot"
        },
        {
          "operation": "create-snapshot"
        },
        {
          "operation": "wait-for-snapshot-creation"
        },
        {
          "operation": {
            "name": "delete-local-index",
            "operation-type": "delete-index"
          }
        },
        {
          "operation": "restore-snapshot"
        },
        {
          "operation": "default",
          "warmup-iterations": 50,
          "iterations": 100
          {% raw %}{%- if not target_throughput %}{% endraw %}
          ,"target-throughput": 3
          {% raw %}{%- elif target_throughput is string and target_throughput.lower() == 'none' %}{% endraw %}
          {% raw %}{%- else %}{% endraw %}
          ,"target-throughput": {% raw %}{{ target_throughput | tojson }}{% endraw %}
          {% raw %}{%- endif %}{% endraw %}
          {% raw %}{%-if search_clients is defined and search_clients %}{% endraw %}
          ,"clients": {% raw %}{{ search_clients | tojson}}{% endraw %}
          {% raw %}{%- endif %}{% endraw %}
        },
        {
          "operation": "range",
          "warmup-iterations": 50,
          "iterations": 100
          {% raw %}{%- if not target_throughput %}{% endraw %}
          ,"target-throughput": 0.7
          {% raw %}{%- elif target_throughput is string and target_throughput.lower() == 'none' %}{% endraw %}
          {% raw %}{%- else %}{% endraw %}
          ,"target-throughput": {% raw %}{{ target_throughput | tojson }}{% endraw %}
          {% raw %}{%- endif %}{% endraw %}
          {% raw %}{%-if search_clients is defined and search_clients %}{% endraw %}
          ,"clients": {% raw %}{{ search_clients | tojson}}{% endraw %}
          {% raw %}{%- endif %}{% endraw %}
        },
        {
          "operation": "distance_amount_agg",
          "warmup-iterations": 50,
          "iterations": 50
          {% raw %}{%- if not target_throughput %}{% endraw %}
          ,"target-throughput": 2
          {% raw %}{%- elif target_throughput is string and target_throughput.lower() == 'none' %}{% endraw %}
          {% raw %}{%- else %}{% endraw %}
          ,"target-throughput": {% raw %}{{ target_throughput | tojson }}{% endraw %}
          {% raw %}{%- endif %}{% endraw %}
          {% raw %}{%-if search_clients is defined and search_clients %}{% endraw %}
          ,"clients": {% raw %}{{ search_clients | tojson}}{% endraw %}
          {% raw %}{%- endif %}{% endraw %}
        },
        {
          "operation": "autohisto_agg",
          "warmup-iterations": 50,
          "iterations": 100
          {% raw %}{%- if not target_throughput %}{% endraw %}
          ,"target-throughput": 1.5
          {% raw %}{%- elif target_throughput is string and target_throughput.lower() == 'none' %}{% endraw %}
          {% raw %}{%- else %}{% endraw %}
          ,"target-throughput": {% raw %}{{ target_throughput | tojson }}{% endraw %}
          {% raw %}{%- endif %}{% endraw %}
          {% raw %}{%-if search_clients is defined and search_clients %}{% endraw %}
          ,"clients": {% raw %}{{ search_clients | tojson}}{% endraw %}
          {% raw %}{%- endif %}{% endraw %}
        },
        {
          "operation": "date_histogram_agg",
          "warmup-iterations": 50,
          "iterations": 100
          {% raw %}{%- if not target_throughput %}{% endraw %}
          ,"target-throughput": 1.5
          {% raw %}{%- elif target_throughput is string and target_throughput.lower() == 'none' %}{% endraw %}
          {% raw %}{%- else %}{% endraw %}
          ,"target-throughput": {% raw %}{{ target_throughput | tojson }}{% endraw %}
          {% raw %}{%- endif %}{% endraw %}
          {% raw %}{%-if search_clients is defined and search_clients %}{% endraw %}
          ,"clients": {% raw %}{{ search_clients | tojson}}{% endraw %}
          {% raw %}{%- endif %}{% endraw %}
        }
      ]
    }

Workload examples

다음 예제는 자신의 워크로드에 맞게 조정할 수 있는 완전한 workload.json 파일을 보여줘요.

Running unthrottled

다음 예제에서 OpenSearch Benchmark는 movies 인덱스에 대해 1시간 동안 제한 없는 벌크 인덱스 작업을 실행해요:

{
  "description": "Tutorial benchmark for OpenSearch Benchmark",
  "indices": [
    {
      "name": "movies",
      "body": "index.json"
    }
  ],
  "corpora": [
    {
      "name": "movies",
      "documents": [
        {
          "source-file": "movies-documents.json",
          "document-count": 11658903, # Fetch document count from command line
          "uncompressed-bytes": 1544799789 # Fetch uncompressed bytes from command line
        }
      ]
    }
  ],
  "schedule": [
  {
    "operation": "bulk",
    "warmup-time-period": 120,
    "time-period": 3600,
    "clients": 8
  }
]
}

Workload with a single task

다음 워크로드는 단일 작업(match_all 쿼리)으로 벤치마크를 실행해요. clients가 지정되지 않았으므로 하나의 클라이언트만 사용돼요. schedule에 따라 워크로드는 1개 클라이언트로 초당 10회 작업으로 match_all 쿼리를 실행하고, 100회 반복으로 워밍업한 후 다음 100회 반복으로 벤치마크를 측정해요:

{
  "description": "Tutorial benchmark for OpenSearch Benchmark",
  "indices": [
    {
      "name": "movies",
      "body": "index.json"
    }
  ],
  "corpora": [
    {
      "name": "movies",
      "documents": [
        {
          "source-file": "movies-documents.json",
          "document-count": 11658903, # Fetch document count from command line
          "uncompressed-bytes": 1544799789 # Fetch uncompressed bytes from command line
        }
      ]
    }
  ],
  "schedule": [
    {
      "operation": {
        "operation-type": "search",
        "index": "_all",
        "body": {
          "query": {
            "match_all": {}
          }
        }
      },
      "warmup-iterations": 100,
      "iterations": 100,
      "target-throughput": 10
    }
  ]
}

Next steps

  • 각 사전 패키지 워크로드의 데이터, 클러스터 요구 사항, 쿼리 유형은 Workload types를 참조하세요.
  • 자신의 워크로드를 생성하는 방법에 대한 정보는 Creating custom workloads를 참조하세요.

더 알아보기 (Learn more)