From 457fb88748f75e34f0954f97f587a2d18b463eb5 Mon Sep 17 00:00:00 2001 From: del-zhenwu <56623710+del-zhenwu@users.noreply.github.com> Date: Mon, 16 Aug 2021 11:06:10 +0800 Subject: [PATCH] [skip ci] add argo.yaml and update readme for benchmark (#7094) Signed-off-by: del-zhenwu --- tests/milvus_benchmark/Dockerfile | 6 +- tests/milvus_benchmark/README.md | 171 +++++++++++-- tests/milvus_benchmark/asserts/uml.jpg | Bin 0 -> 140944 bytes tests/milvus_benchmark/ci/argo.yaml | 232 ++++++++++++++++++ .../milvus_benchmark/chaos/chaos_opt.py | 9 +- .../milvus_benchmark/chaos/utils.py | 1 - .../milvus_benchmark/client.py | 20 +- .../milvus_benchmark/milvus_benchmark/main.py | 12 +- .../milvus_benchmark/metrics/models/server.py | 3 +- .../milvus_benchmark/runners/__init__.py | 3 +- .../milvus_benchmark/runners/accuracy.py | 2 +- .../milvus_benchmark/runners/get.py | 4 +- .../milvus_benchmark/runners/insert.py | 118 +++++++++ .../milvus_benchmark/runners/locust.py | 15 +- .../milvus_benchmark/runners/locust_tasks.py | 8 +- .../milvus_benchmark/runners/search.py | 6 +- .../milvus_benchmark/runners/test.py | 40 +++ .../milvus_benchmark/update.py | 4 +- tests/milvus_benchmark/requirements.txt | 10 +- 19 files changed, 605 insertions(+), 59 deletions(-) create mode 100644 tests/milvus_benchmark/asserts/uml.jpg create mode 100644 tests/milvus_benchmark/ci/argo.yaml create mode 100644 tests/milvus_benchmark/milvus_benchmark/runners/test.py diff --git a/tests/milvus_benchmark/Dockerfile b/tests/milvus_benchmark/Dockerfile index 55f03c113..08b14b96b 100644 --- a/tests/milvus_benchmark/Dockerfile +++ b/tests/milvus_benchmark/Dockerfile @@ -14,7 +14,7 @@ FROM python:3.6.8-jessie SHELL ["/bin/bash", "-o", "pipefail", "-c"] RUN apt-get update && apt-get install -y --no-install-recommends wget apt-transport-https && \ - wget -qO- "https://get.helm.sh/helm-v3.0.2-linux-amd64.tar.gz" | tar --strip-components=1 -xz -C /usr/local/bin linux-amd64/helm && \ + wget -qO- "https://get.helm.sh/helm-v3.6.1-linux-amd64.tar.gz" | tar --strip-components=1 -xz -C /usr/local/bin linux-amd64/helm && \ wget -P /tmp https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg && \ apt-key add /tmp/apt-key.gpg && \ sh -c 'echo deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main > /etc/apt/sources.list.d/kubernetes.list' && \ @@ -25,6 +25,6 @@ RUN apt-get update && apt-get install -y --no-install-recommends wget apt-transp COPY requirements.txt /requirements.txt -RUN python3 -m pip install -r /requirements.txt +RUN python3 -m pip install --no-cache-dir -r /requirements.txt -WORKDIR /root \ No newline at end of file +WORKDIR /root diff --git a/tests/milvus_benchmark/README.md b/tests/milvus_benchmark/README.md index b9cddafbd..37c836b1e 100644 --- a/tests/milvus_benchmark/README.md +++ b/tests/milvus_benchmark/README.md @@ -1,45 +1,184 @@ -`milvus_benchmark` is a non-functional testing tool which allows users to run tests on k8s cluster or at local, the primary use case is performance/load/stability testing, the objective is to expose problems in milvus project. +The milvus_benchmark is a non-functional testing tool or service which allows users to run tests on k8s cluster or at local, the primary use case is performance/load/stability testing, the objective is to expose problems in milvus project. ## Quick start -### Description: +### Description - Test cases in `milvus_benchmark` can be organized with `yaml` - Test can run with local mode or helm mode - local: install and start your local server, and pass the host/port param when start the tests - helm: install the server by helm, which will manage the milvus in k8s cluster, and you can interagte the test stage into argo workflow or jenkins pipeline + +### Usage -### Usage: - -1. Using jenkins: +- Using jenkins: Use `ci/main_jenkinsfile` as the jenkins pipeline file -2. Using argo: +- Using argo: example argo workflow yaml configuration: `ci/argo.yaml` -3. Local test: +- Local test: - 1). set PYTHONPATH: + 1. set PYTHONPATH: `export PYTHONPATH=/your/project/path/milvus_benchmark` - 2). prepare data: + 2. prepare data: if we need to use the sift/deep dataset as the raw data input, we need to mount NAS and update `RAW_DATA_DIR` in `config.py`, the example mount command: `sudo mount -t cifs -o username=test,vers=1.0 //172.16.70.249/test /test` - 3). install requirements: + 3. install requirements: `pip install -r requirements.txt` - 4). write test yaml and run with the yaml param: + 4. write test yaml and run with the yaml param: `cd milvus-benchmark/ && python main.py --local --host=* --port=19530 --suite=suites/2_insert_data.yaml` -### Definitions of test suite: +### Test suite + +#### Description + +Test suite yaml defines the test process, users need to add test suite yaml if adding a customized test into the current test framework. + +#### Example + +Take the test file `2_insert_data.yaml` as an example +``` +insert_performance: + collections: + - + milvus: + db_config.primary_path: /test/milvus/db_data_2/cluster/sift_1m_128_l2 + wal_enable: true + collection_name: sift_1m_128_l2 + ni_per: 50000 + build_index: false + index_type: ivf_sq8 + index_param: + nlist: 1024 +``` +- `insert_performance` + + The top level is the runner type: the other test types including: `search_performance/build_performance/insert_performance/accuracy/locust_insert/...`, each test type corresponds to the different runner conponent defined in directory `runnners` + +- other fields under runner type + + The other parts in the test yaml is the params pass to the runner, such as: + - The field `collection_name` means which kind of collection will be created in milvus + - The field `ni_per` means the batch size + - The filed `build_index` means that whether to create index during inserting + +While using argo workflow as benchmark pipeline, the test suite is made of both `client` and `server` configmap, an example will be like this: + +`server` +``` +kind: ConfigMap +apiVersion: v1 +metadata: + name: server-cluster-8c16m + namespace: qa + uid: 3752f85c-c840-40c6-a5db-ae44146ad8b5 + resourceVersion: '42213135' + creationTimestamp: '2021-05-14T07:00:53Z' + managedFields: + - manager: dashboard + operation: Update + apiVersion: v1 + time: '2021-05-14T07:00:53Z' + fieldsType: FieldsV1 + fieldsV1: + 'f:data': + .: {} + 'f:config.yaml': {} +data: + config.yaml: | + server: + server_tag: "8c16m" + milvus: + deploy_mode: "cluster" +``` +`client` +``` +kind: ConfigMap +apiVersion: v1 +metadata: + name: client-insert-batch-1000 + namespace: qa + uid: 8604c277-f00f-47c7-8fcb-9b3bc97efa74 + resourceVersion: '42988547' + creationTimestamp: '2021-07-09T08:33:02Z' + managedFields: + - manager: dashboard + operation: Update + apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + 'f:data': + .: {} + 'f:config.yaml': {} +data: + config.yaml: | + insert_performance: + collections: + - + milvus: + wal_enable: true + collection_name: sift_1m_128_l2 + ni_per: 1000 + build_index: false + index_type: ivf_sq8 + index_param: + nlist: 1024 +``` + +## Overview of the benchmark + +### Conponents + +- `main.py` + + The entry file: parse the input params and initialize the other conponent: `metric`, `env`, `runner` + +- `metric` + + The test result can be used to analyze the regression or improvement of the milvus system, so we upload the metrics of the test result when a test suite run finished, and then use `redash` to make sense of our data -Test suite yaml defines the test process, users need to write test suite yaml if adding a customized test into the current test framework. +- `db` -Take the test file `2_insert_data.yaml` as an example, the top level is the test type: `insert_performance`, there are lots of test types including: `search_performance/build_performance/insert_performance/accuracy/locust_insert/...`, each test type corresponds to this different runner defined in directory `runnners`, the other parts in the test yaml is the params pass to the runner, such as the field `collection_name` means which kind of collection will be created in milvus. + Currently we use the `mongodb` to store the test result -### Test result: +- `env` -Test result will be uploaded if run with the helm mode, which will be used to judge if the test run pass or failed. + The `env` component defines the server environment and environment management, the instance of the `env` corresponds to the run mode of the benchmark + + - `local`: Only defines the host and port for testing + + - `helm/docker`: Install and uninstall the server in benchmark stage + +- `runner` + + The actual executor in benchmark, each test type defined in test suite will generate the corresponding runner instance, there are three stages in `runner`: + + - `extract_cases`: There are several test cases defined in each test suite yaml, and each case shares the same server environment and shares the same `prepare` stage, but the `metric` for each case is different, so we need to extract cases from the test suite before the cases runs + + - `prepare`: Prepare the data and operations, for example, before running searching, index needs to be created and data needs to be loaded + + - `run_case`: Do the core operation and set `metric` value + +- `suites`: There are two ways to take the content to be tested as input parameters: + - Test suite files under `suites` directory + - Test suite configmap name including `server_config_map` and `client_config_map` if using argo workflow + +- `update.py`: While using argo workflow as benchmark pipeline, we have two steps in workflow template: `install-milvus` and `client-test` + - In stage `install-milvus`, `update.py` is used to generate a new `values.yaml` which will be a param while in `helm install` operation + - In stage `client-test`, it runs `main.py` and receives the milvus host and port as the cmd params, with the run mode `local` + +### Conceptual overview + + The following diagram shows the runtime execution graph of the benchmark (local mode based on argo workflow) + + + + + + diff --git a/tests/milvus_benchmark/asserts/uml.jpg b/tests/milvus_benchmark/asserts/uml.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d88937b6c557584af8d63be2491f991344c46b7f GIT binary patch literal 140944 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 literal 0 HcmV?d00001 diff --git a/tests/milvus_benchmark/ci/argo.yaml b/tests/milvus_benchmark/ci/argo.yaml new file mode 100644 index 000000000..d9a43dda5 --- /dev/null +++ b/tests/milvus_benchmark/ci/argo.yaml @@ -0,0 +1,232 @@ +metadata: + name: benchmark + namespace: qa + uid: e8a51212-9b27-441d-b357-e73c63854ccf + resourceVersion: '63697833' + generation: 41 + creationTimestamp: '2021-05-25T11:04:40Z' + labels: + workflows.argoproj.io/creator: system-serviceaccount-argo-argo-server + managedFields: + - manager: argo + operation: Update + apiVersion: argoproj.io/v1alpha1 + fieldsType: FieldsV1 + fieldsV1: + 'f:metadata': + 'f:labels': + .: {} + 'f:workflows.argoproj.io/creator': {} + 'f:spec': + .: {} + 'f:arguments': + .: {} + 'f:parameters': {} + 'f:entrypoint': {} + 'f:nodeSelector': + .: {} + 'f:node-role.kubernetes.io/benchmark': {} + 'f:onExit': {} + 'f:serviceAccountName': {} + 'f:templates': {} + 'f:tolerations': {} + 'f:volumes': {} +spec: + templates: + - name: benchmark-loop + inputs: {} + outputs: {} + metadata: {} + steps: + - - name: call-benchmark-test + template: benchmark + arguments: + parameters: + - name: server-instance + value: '{{workflow.name}}-{{item.instanceId}}' + - name: server-configmap + value: '{{item.server-configmap}}' + - name: client-configmap + value: '{{item.client-configmap}}' + withParam: '{{workflow.parameters.configmaps}}' + - name: uninstall-all + inputs: {} + outputs: {} + metadata: {} + steps: + - - name: uninstall-milvus + template: uninstall-milvus + arguments: + parameters: + - name: server-instance + value: '{{workflow.name}}-{{item.instanceId}}' + withParam: '{{workflow.parameters.configmaps}}' + - name: benchmark + inputs: + parameters: + - name: server-instance + - name: server-configmap + - name: client-configmap + outputs: {} + metadata: {} + steps: + - - name: install-milvus + template: install-milvus + arguments: + parameters: + - name: server-instance + value: '{{inputs.parameters.server-instance}}' + - name: server-configmap + value: '{{inputs.parameters.server-configmap}}' + - - name: client-test + template: client-test + arguments: + parameters: + - name: server-instance + value: '{{inputs.parameters.server-instance}}' + - name: server-configmap + value: '{{inputs.parameters.server-configmap}}' + - name: client-configmap + value: '{{inputs.parameters.client-configmap}}' + - name: uninstall-milvus + inputs: + parameters: + - name: server-instance + outputs: {} + metadata: {} + container: + name: '' + image: 'registry.zilliz.com/milvus/milvus-test-env:v0.5' + command: + - /bin/sh + - '-c' + args: + - ' helm uninstall -n qa-milvus {{inputs.parameters.server-instance}} && kubectl delete pvc -l app.kubernetes.io/instance={{inputs.parameters.server-instance}} -n qa-milvus ' + resources: {} + volumeMounts: + - name: kube-config + mountPath: /root/.kube + - name: install-milvus + inputs: + parameters: + - name: server-instance + - name: server-configmap + artifacts: + - name: charts + path: /src/helm + git: + repo: 'git@github.com:milvus-io/milvus-helm.git' + revision: master + sshPrivateKeySecret: + name: github-key + key: ssh-private-key + - name: benchmark-src + path: /src/benchmark + git: + repo: 'git@github.com:zilliztech/milvus_benchmark.git' + revision: '{{workflow.parameters.test-client-branch}}' + sshPrivateKeySecret: + name: github-key + key: ssh-private-key + outputs: {} + metadata: {} + container: + name: '' + image: 'registry.zilliz.com/milvus/milvus-test-env:v0.5' + command: + - /bin/sh + - '-c' + args: + - ' cd /src/helm/charts/milvus && cp -r /src/benchmark/milvus_benchmark/* . && cp /configmap-server/config.yaml . && python update.py --src-values=values.yaml --deploy-params=config.yaml && cat values.yaml && helm install -n qa-milvus --set image.all.repository={{workflow.parameters.milvus-image-repository}} --set image.all.tag={{workflow.parameters.milvus-image-tag}} --set image.all.pullPolicy=Always --set etcd.persistence.enabled=false --set servicemonitor.enabled=true --wait --timeout 15m {{inputs.parameters.server-instance}} . && kubectl get pods -n qa-milvus -l app.kubernetes.io/instance={{inputs.parameters.server-instance}} ' + resources: {} + volumeMounts: + - name: kube-config + readOnly: true + mountPath: /root/.kube + - name: benchmark-server-configmap + mountPath: /configmap-server + volumes: + - name: benchmark-server-configmap + configMap: + name: '{{inputs.parameters.server-configmap}}' + - name: client-test + inputs: + parameters: + - name: server-instance + - name: server-configmap + - name: client-configmap + artifacts: + - name: source + path: /src + git: + repo: 'git@github.com:zilliztech/milvus_benchmark.git' + revision: '{{workflow.parameters.test-client-branch}}' + sshPrivateKeySecret: + name: github-key + key: ssh-private-key + outputs: {} + metadata: {} + container: + name: '' + image: 'registry.zilliz.com/milvus/milvus-test-env:v0.5' + command: + - /bin/sh + - '-c' + args: + - ' cd /src && pip install -r requirements.txt -i https://pypi.doubanio.com/simple/ --trusted-host pypi.doubanio.com && pip install -i https://test.pypi.org/simple/ pymilvus=={{workflow.parameters.test-sdk-version}} && cd milvus_benchmark && export PYTHONPATH=/src && python main.py --host={{inputs.parameters.server-instance}}-milvus.qa-milvus.svc.cluster.local --local --suite=/configmap-client/config.yaml --server-config=/configmap-server/config.yaml' + resources: + limits: + cpu: '4' + memory: 4Gi + volumeMounts: + - name: kube-config + readOnly: true + mountPath: /root/.kube + - name: benchmark-server-configmap + mountPath: /configmap-server + - name: benchmark-client-configmap + mountPath: /configmap-client + - name: db-data-path + mountPath: /test + volumes: + - name: benchmark-server-configmap + configMap: + name: '{{inputs.parameters.server-configmap}}' + - name: benchmark-client-configmap + configMap: + name: '{{inputs.parameters.client-configmap}}' + - name: db-data-path + flexVolume: + driver: fstab/cifs + fsType: cifs + secretRef: + name: cifs-test-secret + options: + mountOptions: vers=1.0 + networkPath: //172.16.70.249/test + activeDeadlineSeconds: 21600 + entrypoint: benchmark-loop + arguments: + parameters: + - name: milvus-image-repository + value: harbor.zilliz.cc/dockerhub/milvusdb/milvus-dev + - name: milvus-image-tag + value: master-latest + - name: test-client-branch + value: master + - name: test-sdk-version + value: 2.0.0rc4.dev1 + - name: configmaps + value: ' [ {"instanceId":"1", "server-configmap": "server-single-8c16m", "client-configmap": "client-acc-sift-ivf-flat" } ]' + serviceAccountName: qa-admin + volumes: + - name: kube-config + secret: + secretName: qa-admin-config + nodeSelector: + node-role.kubernetes.io/benchmark: '' + tolerations: + - key: node-role.kubernetes.io/benchmark + operator: Exists + effect: NoSchedule + onExit: uninstall-all diff --git a/tests/milvus_benchmark/milvus_benchmark/chaos/chaos_opt.py b/tests/milvus_benchmark/milvus_benchmark/chaos/chaos_opt.py index 76965a6ef..a502f00ee 100644 --- a/tests/milvus_benchmark/milvus_benchmark/chaos/chaos_opt.py +++ b/tests/milvus_benchmark/milvus_benchmark/chaos/chaos_opt.py @@ -6,11 +6,8 @@ from kubernetes import client, config from kubernetes.client.rest import ApiException from milvus_benchmark import config as cf -config.load_kube_config() -api_instance = client.CustomObjectsApi() logger = logging.getLogger("milvus_benchmark.chaos.chaosOpt") - class ChaosOpt(object): def __init__(self, kind, group=cf.DEFAULT_GROUP, version=cf.DEFAULT_VERSION, namespace=cf.CHAOS_NAMESPACE): self.group = group @@ -25,6 +22,8 @@ class ChaosOpt(object): # body = create_chaos_config(self.plural, self.metadata_name, spec_params) # logger.info(body) pretty = 'true' + config.load_kube_config() + api_instance = client.CustomObjectsApi() try: api_response = api_instance.create_namespaced_custom_object(self.group, self.version, self.namespace, plural=self.plural, body=body, pretty=pretty) @@ -37,6 +36,8 @@ class ChaosOpt(object): def delete_chaos_object(self, metadata_name): print(metadata_name) try: + config.load_kube_config() + api_instance = client.CustomObjectsApi() data = api_instance.delete_namespaced_custom_object(self.group, self.version, self.namespace, self.plural, metadata_name) logger.info(data) @@ -46,6 +47,8 @@ class ChaosOpt(object): def list_chaos_object(self): try: + config.load_kube_config() + api_instance = client.CustomObjectsApi() data = api_instance.list_namespaced_custom_object(self.group, self.version, self.namespace, plural=self.plural) # pprint(data) diff --git a/tests/milvus_benchmark/milvus_benchmark/chaos/utils.py b/tests/milvus_benchmark/milvus_benchmark/chaos/utils.py index 8f41838f2..6ab89fcc8 100644 --- a/tests/milvus_benchmark/milvus_benchmark/chaos/utils.py +++ b/tests/milvus_benchmark/milvus_benchmark/chaos/utils.py @@ -4,7 +4,6 @@ from operator import methodcaller from kubernetes import client, config from milvus_benchmark import config as cf - logger = logging.getLogger("milvus_benchmark.chaos.utils") diff --git a/tests/milvus_benchmark/milvus_benchmark/client.py b/tests/milvus_benchmark/milvus_benchmark/client.py index 2a554f721..41a66964e 100644 --- a/tests/milvus_benchmark/milvus_benchmark/client.py +++ b/tests/milvus_benchmark/milvus_benchmark/client.py @@ -145,10 +145,10 @@ class MilvusClient(object): self._milvus.create_partition(collection_name, tag) @time_wrapper - def insert(self, entities, collection_name=None): + def insert(self, entities, collection_name=None, timeout=None): tmp_collection_name = self._collection_name if collection_name is None else collection_name try: - insert_res = self._milvus.insert(tmp_collection_name, entities) + insert_res = self._milvus.insert(tmp_collection_name, entities, timeout=timeout) return insert_res.primary_keys except Exception as e: logger.error(str(e)) @@ -234,9 +234,9 @@ class MilvusClient(object): # raise Exception("Error occured") @time_wrapper - def flush(self,_async=False, collection_name=None): + def flush(self, _async=False, collection_name=None, timeout=None): tmp_collection_name = self._collection_name if collection_name is None else collection_name - self._milvus.flush([tmp_collection_name], _async=_async) + self._milvus.flush([tmp_collection_name], _async=_async, timeout=timeout) @time_wrapper def compact(self, collection_name=None): @@ -246,11 +246,11 @@ class MilvusClient(object): # only support "in" in expr @time_wrapper - def get(self, ids, collection_name=None): + def get(self, ids, collection_name=None, timeout=None): tmp_collection_name = self._collection_name if collection_name is None else collection_name # res = self._milvus.get(tmp_collection_name, ids, output_fields=None, partition_names=None) ids_expr = "id in %s" % (str(ids)) - res = self._milvus.query(tmp_collection_name, ids_expr, output_fields=None, partition_names=None) + res = self._milvus.query(tmp_collection_name, ids_expr, output_fields=None, partition_names=None, timeout=timeout) return res @time_wrapper @@ -343,7 +343,7 @@ class MilvusClient(object): ids.append(res.ids) return ids - def query_rand(self, nq_max=100): + def query_rand(self, nq_max=100, timeout=None): # for ivf search dimension = 128 top_k = random.randint(1, 100) @@ -360,9 +360,9 @@ class MilvusClient(object): "metric_type": utils.metric_type_trans(metric_type), "params": search_param} }} - self.query(vector_query) + self.query(vector_query, timeout=timeout) - def load_query_rand(self, nq_max=100): + def load_query_rand(self, nq_max=100, timeout=None): # for ivf search dimension = 128 top_k = random.randint(1, 100) @@ -379,7 +379,7 @@ class MilvusClient(object): "metric_type": utils.metric_type_trans(metric_type), "params": search_param} }} - self.load_and_query(vector_query) + self.load_and_query(vector_query, timeout=timeout) # TODO: need to check def count(self, collection_name=None): diff --git a/tests/milvus_benchmark/milvus_benchmark/main.py b/tests/milvus_benchmark/milvus_benchmark/main.py index 9219ed7f4..d97c3f8be 100644 --- a/tests/milvus_benchmark/milvus_benchmark/main.py +++ b/tests/milvus_benchmark/milvus_benchmark/main.py @@ -1,5 +1,6 @@ import os import sys +import time import argparse import logging import traceback @@ -45,16 +46,17 @@ def get_image_tag(image_version): # back_scheduler.shutdown(wait=False) -def run_suite(run_type, suite, env_mode, env_params): +def run_suite(run_type, suite, env_mode, env_params, timeout=None): try: start_status = False metric = api.Metric() deploy_mode = env_params["deploy_mode"] + deploy_opology = env_params["deploy_opology"] if "deploy_opology" in env_params else None env = get_env(env_mode, deploy_mode) metric.set_run_id() metric.set_mode(env_mode) metric.env = Env() - metric.server = Server(version=config.SERVER_VERSION, mode=deploy_mode) + metric.server = Server(version=config.SERVER_VERSION, mode=deploy_mode, deploy_opology=deploy_opology) logger.info(env_params) if env_mode == "local": metric.hardware = Hardware("") @@ -228,7 +230,8 @@ def main(): "host": args.host, "port": args.port, "deploy_mode": deploy_mode, - "server_tag": server_tag + "server_tag": server_tag, + "deploy_opology": deploy_params_dict } suite_file = args.suite with open(suite_file) as f: @@ -242,8 +245,9 @@ def main(): # ensure there is only one case in suite # suite = {"run_type": run_type, "run_params": collections[0]} suite = collections[0] + timeout = suite["timeout"] if "timeout" in suite else None env_mode = "local" - return run_suite(run_type, suite, env_mode, env_params) + return run_suite(run_type, suite, env_mode, env_params, timeout=timeout) # job = back_scheduler.add_job(run_suite, args=[run_type, suite, env_mode, env_params], misfire_grace_time=36000) # logger.info(job) # logger.info(job.id) diff --git a/tests/milvus_benchmark/milvus_benchmark/metrics/models/server.py b/tests/milvus_benchmark/milvus_benchmark/metrics/models/server.py index 2c8fe9e97..c4aa9ea06 100644 --- a/tests/milvus_benchmark/milvus_benchmark/metrics/models/server.py +++ b/tests/milvus_benchmark/milvus_benchmark/metrics/models/server.py @@ -13,12 +13,13 @@ class Server: } """ - def __init__(self, version=None, mode=None, build_commit=None): + def __init__(self, version=None, mode=None, build_commit=None, deploy_opology=None): self._version = '0.1' self._type = 'server' self.version = version self.mode = mode self.build_commit = build_commit + self.deploy_opology = deploy_opology # self.md5 = md5 def json_md5(self): diff --git a/tests/milvus_benchmark/milvus_benchmark/runners/__init__.py b/tests/milvus_benchmark/milvus_benchmark/runners/__init__.py index 6bd372859..eeb734d39 100644 --- a/tests/milvus_benchmark/milvus_benchmark/runners/__init__.py +++ b/tests/milvus_benchmark/milvus_benchmark/runners/__init__.py @@ -1,4 +1,4 @@ -from .insert import InsertRunner +from .insert import InsertRunner, BPInsertRunner from .locust import LocustInsertRunner, LocustSearchRunner, LocustRandomRunner from .search import SearchRunner, InsertSearchRunner from .build import BuildRunner, InsertBuildRunner @@ -11,6 +11,7 @@ from .chaos import SimpleChaosRunner def get_runner(name, env, metric): return { "insert_performance": InsertRunner(env, metric), + "bp_insert_performance": BPInsertRunner(env, metric), "search_performance": SearchRunner(env, metric), "insert_search_performance": InsertSearchRunner(env, metric), "locust_insert_performance": LocustInsertRunner(env, metric), diff --git a/tests/milvus_benchmark/milvus_benchmark/runners/accuracy.py b/tests/milvus_benchmark/milvus_benchmark/runners/accuracy.py index a56ebcfc6..0ec2a1aaa 100644 --- a/tests/milvus_benchmark/milvus_benchmark/runners/accuracy.py +++ b/tests/milvus_benchmark/milvus_benchmark/runners/accuracy.py @@ -90,7 +90,7 @@ class AccuracyRunner(BaseRunner): self.milvus.set_collection(collection_name) if not self.milvus.exists_collection(): logger.info("collection not exist") - self.milvus.load_collection() + self.milvus.load_collection(timeout=600) def run_case(self, case_metric, **case_param): collection_size = case_param["collection_size"] diff --git a/tests/milvus_benchmark/milvus_benchmark/runners/get.py b/tests/milvus_benchmark/milvus_benchmark/runners/get.py index 10e2b7987..4a95a668d 100644 --- a/tests/milvus_benchmark/milvus_benchmark/runners/get.py +++ b/tests/milvus_benchmark/milvus_benchmark/runners/get.py @@ -116,4 +116,6 @@ class InsertGetRunner(GetRunner): flush_time = round(time.time() - start_time, 2) logger.debug({"collection count": self.milvus.count()}) logger.debug({"flush_time": flush_time}) - self.milvus.load_collection() + logger.debug("Start load collection") + self.milvus.load_collection(timeout=1200) + logger.debug("Load collection end") diff --git a/tests/milvus_benchmark/milvus_benchmark/runners/insert.py b/tests/milvus_benchmark/milvus_benchmark/runners/insert.py index 0f5119e19..236fe68e1 100644 --- a/tests/milvus_benchmark/milvus_benchmark/runners/insert.py +++ b/tests/milvus_benchmark/milvus_benchmark/runners/insert.py @@ -123,3 +123,121 @@ class InsertRunner(BaseRunner): build_time = round(time.time()-start_time, 2) tmp_result.update({"flush_time": flush_time, "build_time": build_time}) return tmp_result + + +class BPInsertRunner(BaseRunner): + """run insert""" + name = "bp_insert_performance" + + def __init__(self, env, metric): + super(BPInsertRunner, self).__init__(env, metric) + + def extract_cases(self, collection): + collection_name = collection["collection_name"] if "collection_name" in collection else None + (data_type, collection_size, dimension, metric_type) = parser.collection_parser(collection_name) + ni_pers = collection["ni_pers"] + build_index = collection["build_index"] if "build_index" in collection else False + index_info = None + vector_type = utils.get_vector_type(data_type) + other_fields = collection["other_fields"] if "other_fields" in collection else None + index_field_name = None + index_type = None + index_param = None + if build_index is True: + index_type = collection["index_type"] + index_param = collection["index_param"] + index_info = { + "index_type": index_type, + "index_param": index_param + } + index_field_name = utils.get_default_field_name(vector_type) + flush = True + if "flush" in collection and collection["flush"] == "no": + flush = False + case_metrics = list() + case_params = list() + + for ni_per in ni_pers: + collection_info = { + "dimension": dimension, + "metric_type": metric_type, + "dataset_name": collection_name, + "collection_size": collection_size, + "other_fields": other_fields, + "ni_per": ni_per + } + self.init_metric(self.name, collection_info, index_info, None) + case_metric = copy.deepcopy(self.metric) + case_metric.set_case_metric_type() + case_metrics.append(case_metric) + case_param = { + "collection_name": collection_name, + "data_type": data_type, + "dimension": dimension, + "collection_size": collection_size, + "ni_per": ni_per, + "metric_type": metric_type, + "vector_type": vector_type, + "other_fields": other_fields, + "build_index": build_index, + "flush_after_insert": flush, + "index_field_name": index_field_name, + "index_type": index_type, + "index_param": index_param, + } + case_params.append(case_param) + return case_params, case_metrics + + def prepare(self, **case_param): + collection_name = case_param["collection_name"] + dimension = case_param["dimension"] + vector_type = case_param["vector_type"] + other_fields = case_param["other_fields"] + index_field_name = case_param["index_field_name"] + build_index = case_param["build_index"] + + self.milvus.set_collection(collection_name) + if self.milvus.exists_collection(): + logger.debug("Start drop collection") + self.milvus.drop() + time.sleep(utils.DELETE_INTERVAL_TIME) + self.milvus.create_collection(dimension, data_type=vector_type, + other_fields=other_fields) + # TODO: update fields in collection_info + # fields = self.get_fields(self.milvus, collection_name) + # collection_info = { + # "dimension": dimension, + # "metric_type": metric_type, + # "dataset_name": collection_name, + # "fields": fields + # } + if build_index is True: + if case_param["index_type"]: + self.milvus.create_index(index_field_name, case_param["index_type"], case_param["metric_type"], index_param=case_param["index_param"]) + logger.debug(self.milvus.describe_index(index_field_name)) + else: + build_index = False + logger.warning("Please specify the index_type") + + # TODO: error handler + def run_case(self, case_metric, **case_param): + collection_name = case_param["collection_name"] + dimension = case_param["dimension"] + index_field_name = case_param["index_field_name"] + build_index = case_param["build_index"] + # TODO: + tmp_result = self.insert(self.milvus, collection_name, case_param["data_type"], dimension, case_param["collection_size"], case_param["ni_per"]) + flush_time = 0.0 + build_time = 0.0 + if case_param["flush_after_insert"] is True: + start_time = time.time() + self.milvus.flush() + flush_time = round(time.time()-start_time, 2) + logger.debug(self.milvus.count()) + if build_index is True: + logger.debug("Start build index for last file") + start_time = time.time() + self.milvus.create_index(index_field_name, case_param["index_type"], case_param["metric_type"], index_param=case_param["index_param"]) + build_time = round(time.time()-start_time, 2) + tmp_result.update({"flush_time": flush_time, "build_time": build_time}) + return tmp_result diff --git a/tests/milvus_benchmark/milvus_benchmark/runners/locust.py b/tests/milvus_benchmark/milvus_benchmark/runners/locust.py index 1ebfc4c6e..4bf268fa0 100644 --- a/tests/milvus_benchmark/milvus_benchmark/runners/locust.py +++ b/tests/milvus_benchmark/milvus_benchmark/runners/locust.py @@ -269,13 +269,14 @@ class LocustSearchRunner(LocustRunner): load_start_time = time.time() self.milvus.load_collection() logger.debug({"load_time": round(time.time()-load_start_time, 2)}) - search_param = None - for op in case_param["task"]["types"]: - if op["type"] == "query": - search_param = op["params"]["search_param"] - break - logger.info("index_field_name: {}".format(index_field_name)) - self.milvus.warm_query(index_field_name, search_param, metric_type, times=2) + # search_param = None + # for op in case_param["task"]["types"]: + # if op["type"] == "query": + # search_param = op["params"]["search_param"] + # break + # logger.info("index_field_name: {}".format(index_field_name)) + # TODO: enable warm query + # self.milvus.warm_query(index_field_name, search_param, metric_type, times=2) class LocustRandomRunner(LocustRunner): diff --git a/tests/milvus_benchmark/milvus_benchmark/runners/locust_tasks.py b/tests/milvus_benchmark/milvus_benchmark/runners/locust_tasks.py index 1f18c580d..b00cc538c 100644 --- a/tests/milvus_benchmark/milvus_benchmark/runners/locust_tasks.py +++ b/tests/milvus_benchmark/milvus_benchmark/runners/locust_tasks.py @@ -28,20 +28,20 @@ class Tasks(TaskSet): if isinstance(filter, dict) and "term" in filter: filter_query.append(eval(filter["term"])) # logger.debug(filter_query) - self.client.query(vector_query, filter_query=filter_query, log=False, timeout=120) + self.client.query(vector_query, filter_query=filter_query, log=False, timeout=30) @task def flush(self): - self.client.flush(log=False) + self.client.flush(log=False, timeout=30) @task def load(self): - self.client.load_collection() + self.client.load_collection(timeout=30) @task def release(self): self.client.release_collection() - self.client.load_collection() + self.client.load_collection(timeout=30) # @task # def release_index(self): diff --git a/tests/milvus_benchmark/milvus_benchmark/runners/search.py b/tests/milvus_benchmark/milvus_benchmark/runners/search.py index 03a0f1875..29b7d0eb2 100644 --- a/tests/milvus_benchmark/milvus_benchmark/runners/search.py +++ b/tests/milvus_benchmark/milvus_benchmark/runners/search.py @@ -96,7 +96,7 @@ class SearchRunner(BaseRunner): return False logger.debug(self.milvus.count()) logger.info("Start load collection") - self.milvus.load_collection() + self.milvus.load_collection(timeout=1200) # TODO: enable warm query # self.milvus.warm_query(index_field_name, search_params[0], times=2) @@ -262,7 +262,7 @@ class InsertSearchRunner(BaseRunner): logger.info(self.milvus.count()) logger.info("Start load collection") load_start_time = time.time() - self.milvus.load_collection() + self.milvus.load_collection(timeout=1200) logger.debug({"load_time": round(time.time()-load_start_time, 2)}) def run_case(self, case_metric, **case_param): @@ -284,7 +284,7 @@ class InsertSearchRunner(BaseRunner): tmp_result = {"insert": self.insert_result, "build_time": self.build_time, "search_time": min_query_time, "avc_search_time": avg_query_time} # # logger.info("Start load collection") - # self.milvus.load_collection() + # self.milvus.load_collection(timeout=1200) # logger.info("Release load collection") # self.milvus.release_collection() return tmp_result \ No newline at end of file diff --git a/tests/milvus_benchmark/milvus_benchmark/runners/test.py b/tests/milvus_benchmark/milvus_benchmark/runners/test.py new file mode 100644 index 000000000..9ece3b042 --- /dev/null +++ b/tests/milvus_benchmark/milvus_benchmark/runners/test.py @@ -0,0 +1,40 @@ +import math +from locust import User, TaskSet, task, constant +from locust import LoadTestShape + + +class StepLoadShape(LoadTestShape): + """ + A step load shape + Keyword arguments: + step_time -- Time between steps + step_load -- User increase amount at each step + spawn_rate -- Users to stop/start per second at every step + time_limit -- Time limit in seconds + """ + + step_time = 30 + step_load = 10 + spawn_rate = 10 + time_limit = 600 + + def tick(self): + run_time = self.get_run_time() + + if run_time > self.time_limit: + return None + + current_step = math.floor(run_time / self.step_time) + 1 + return (current_step * self.step_load, self.spawn_rate) + + +class UserTasks(TaskSet): + @task + def get_root(self): + print("in usertasks") + + +class WebsiteUser(User): + wait_time = constant(0.5) + tasks = [UserTasks] + shape = StepLoadShape diff --git a/tests/milvus_benchmark/milvus_benchmark/update.py b/tests/milvus_benchmark/milvus_benchmark/update.py index 78f08e5dd..db0b9474f 100644 --- a/tests/milvus_benchmark/milvus_benchmark/update.py +++ b/tests/milvus_benchmark/milvus_benchmark/update.py @@ -113,7 +113,7 @@ def update_values(src_values_file, deploy_params_file): logging.info("TODO: Need to schedule pod on GPU server") logging.debug("Add tolerations into standalone server") values_dict['standalone']['tolerations'] = perf_tolerations - # values_dict['minio']['tolerations'] = perf_tolerations + values_dict['minio']['tolerations'] = perf_tolerations values_dict['etcd']['tolerations'] = perf_tolerations else: # TODO: mem limits on distributed mode @@ -146,7 +146,7 @@ def update_values(src_values_file, deploy_params_file): values_dict['indexNode']['tolerations'] = perf_tolerations values_dict['dataNode']['tolerations'] = perf_tolerations values_dict['etcd']['tolerations'] = perf_tolerations - # values_dict['minio']['tolerations'] = perf_tolerations + values_dict['minio']['tolerations'] = perf_tolerations values_dict['pulsarStandalone']['tolerations'] = perf_tolerations # TODO: for distributed deployment # values_dict['pulsar']['autoRecovery']['tolerations'] = perf_tolerations diff --git a/tests/milvus_benchmark/requirements.txt b/tests/milvus_benchmark/requirements.txt index 8fa17d7f7..18546eeec 100644 --- a/tests/milvus_benchmark/requirements.txt +++ b/tests/milvus_benchmark/requirements.txt @@ -1,7 +1,13 @@ # pymilvus==0.2.14 # pymilvus-distributed>=0.0.61 ---extra-index-url https://test.pypi.org/simple/ -pymilvus==2.0.0rc2.dev12 + +# for local install +# --extra-index-url https://test.pypi.org/simple/ +# pymilvus==2.0.0rc3.dev8 + +grpcio==1.37.1 +grpcio-testing==1.37.1 +grpcio-tools==1.37.1 scipy==1.3.1 scikit-learn==0.19.1 -- GitLab