Skip to content

Commit 13bbc5f

Browse files
authored
Added SLO test
Added SLO test
2 parents 5e008d0 + 7086874 commit 13bbc5f

17 files changed

+1209
-4
lines changed

.github/workflows/slo.yml

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
on:
2+
push:
3+
branches: [main]
4+
pull_request:
5+
branches: [main]
6+
workflow_dispatch:
7+
8+
name: SLO
9+
10+
jobs:
11+
test-slo:
12+
concurrency:
13+
group: slo-${{ github.ref }}
14+
if: (!contains(github.event.pull_request.labels.*.name, 'no slo'))
15+
16+
runs-on: ubuntu-latest
17+
name: SLO test
18+
permissions:
19+
checks: write
20+
pull-requests: write
21+
contents: read
22+
issues: write
23+
24+
steps:
25+
- name: Checkout repository
26+
uses: actions/checkout@v3
27+
if: env.DOCKER_REPO != null # check permissions
28+
env:
29+
DOCKER_REPO: ${{ secrets.SLO_DOCKER_REPO }}
30+
31+
- name: Run SLO
32+
uses: ydb-platform/slo-tests@php-version
33+
if: env.DOCKER_REPO != null # check permissions
34+
env:
35+
DOCKER_REPO: ${{ secrets.SLO_DOCKER_REPO }}
36+
with:
37+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
38+
KUBECONFIG_B64: ${{ secrets.SLO_KUBE_CONFIG }}
39+
AWS_CREDENTIALS_B64: ${{ secrets.SLO_AWS_CREDENTIALS }}
40+
AWS_CONFIG_B64: ${{ secrets.SLO_AWS_CONFIG }}
41+
DOCKER_USERNAME: ${{ secrets.SLO_DOCKER_USERNAME }}
42+
DOCKER_PASSWORD: ${{ secrets.SLO_DOCKER_PASSWORD }}
43+
DOCKER_REPO: ${{ secrets.SLO_DOCKER_REPO }}
44+
DOCKER_FOLDER: ${{ secrets.SLO_DOCKER_FOLDER }}
45+
s3_endpoint: ${{ secrets.SLO_S3_ENDPOINT }}
46+
s3_images_folder: ${{ vars.SLO_S3_IMAGES_FOLDER }}
47+
grafana_domain: ${{ vars.SLO_GRAFANA_DOMAIN }}
48+
grafana_dashboard: dca60386-0d3d-43f5-a2af-5f3fd3e3b295
49+
grafana_dashboard_width: 2000
50+
grafana_dashboard_height: 2600
51+
ydb_version: 'newest'
52+
timeBetweenPhases: 30
53+
shutdownTime: 30
54+
55+
language_id0: 'php'
56+
workload_path0: 'slo-workload'
57+
language0: 'php'
58+
workload_build_context0: ../.
59+
workload_build_options0: -f Dockerfile
60+
61+
- uses: actions/upload-artifact@v3
62+
if: always() && env.DOCKER_REPO != null # check permissions and execute, even if the previous stage was failed
63+
env:
64+
DOCKER_REPO: ${{ secrets.SLO_DOCKER_REPO }}
65+
with:
66+
name: slo-logs
67+
path: logs/

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@
3333
"autoload-dev": {
3434
"psr-4": {
3535
"YdbPlatform\\Ydb\\Test\\": "tests",
36-
"App\\": "examples/"
36+
"App\\": "examples/",
37+
"YdbPlatform\\Ydb\\Slo\\": "slo-workload"
3738
}
3839
}
3940
}

slo-workload/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
composer.lock
2+
./vendor
3+
.idea

slo-workload/Dockerfile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
FROM ilyakharev/php-grpc:7.2
2+
3+
COPY . /src
4+
WORKDIR /src/slo-workload
5+
RUN composer update
6+
#RUN apt update; apt install htop
7+
ENTRYPOINT ["php", "application.php"]

slo-workload/README.MD

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
# SLO workload
2+
3+
SLO is the type of test where app based on ydb-sdk is tested against falling YDB cluster nodes, tablets, network
4+
(that is possible situations for distributed DBs with hundreds of nodes)
5+
6+
### Usage:
7+
8+
It has 3 commands:
9+
10+
- `create` - creates table in database
11+
- `cleanup` - drops table in database
12+
- `run` - runs workload (read and write to table with sets RPS)
13+
14+
### Run examples with all arguments:
15+
16+
create:
17+
18+
`$APP create grpcs://ydb.cool.example.com:2135 /some/folder -t tableName
19+
-min-partitions-count 6 -max-partitions-count 1000 -partition-size 1 -с 1000
20+
-write-timeout 10000`
21+
22+
cleanup:
23+
24+
`$APP cleanup grpcs://ydb.cool.example.com:2135 /some/folder -t tableName`
25+
26+
run:
27+
28+
`$APP create run grpcs://ydb.cool.example.com:2135 /some/folder -t tableName
29+
-prom-pgw http://prometheus-pushgateway:9091 -report-period 250
30+
-read-rps 1000 -read-timeout 10000
31+
-write-rps 100 -write-timeout 10000
32+
-time 600 -shutdown-time 30`
33+
34+
## Arguments for commands:
35+
36+
### create
37+
`$APP create <endpoint> <db> [options]`
38+
39+
```
40+
Arguments:
41+
endpoint YDB endpoint to connect to
42+
db YDB database to connect to
43+
44+
Options:
45+
-t -table-name <string> table name to create
46+
47+
-min-partitions-count <int> minimum amount of partitions in table
48+
-max-partitions-count <int> maximum amount of partitions in table
49+
-partition-size <int> partition size in mb
50+
51+
-c -initial-data-count <int> amount of initially created rows
52+
53+
-write-timeout <int> write timeout milliseconds
54+
```
55+
56+
### cleanup
57+
`$APP cleanup <endpoint> <db> [options]`
58+
59+
```
60+
Arguments:
61+
endpoint YDB endpoint to connect to
62+
db YDB database to connect to
63+
64+
Options:
65+
-t -table-name <string> table name to create
66+
67+
-write-timeout <int> write timeout milliseconds
68+
```
69+
70+
### run
71+
`$APP run <endpoint> <db> [options]`
72+
73+
```
74+
Arguments:
75+
endpoint YDB endpoint to connect to
76+
db YDB database to connect to
77+
78+
Options:
79+
-t -table-name <string> table name to create
80+
81+
-initial-data-count <int> amount of initially created rows
82+
83+
-prom-pgw <string> prometheus push gateway
84+
-report-period <int> prometheus push period in milliseconds
85+
86+
-read-rps <int> read RPS
87+
-read-timeout <int> read timeout milliseconds
88+
89+
-write-rps <int> write RPS
90+
-write-timeout <int> write timeout milliseconds
91+
92+
-time <int> run time in seconds
93+
-shutdown-time <int> graceful shutdown time in seconds
94+
```
95+
96+
## Authentication
97+
98+
Workload using anonymous credentials.
99+
100+
## What's inside
101+
When running `run` command, the program creates three jobs: `readJob`, `writeJob`, `metricsJob`.
102+
103+
- `readJob` reads rows from the table one by one with random identifiers generated by writeJob
104+
- `writeJob` generates and inserts rows
105+
- `metricsJob` periodically sends metrics to Prometheus
106+
107+
Table have these fields:
108+
- `hash Uint64 Digest::NumericHash(id)`
109+
- `id Uint64`
110+
- `payload_double Double`
111+
- `payload_hash Uint64`
112+
- `payload_str UTF8`
113+
- `payload_timestamp Timestamp`
114+
115+
Primary key: `("hash", "id")`
116+
117+
## Collected metrics
118+
- `oks` - amount of OK requests
119+
- `not_oks` - amount of not OK requests
120+
- `inflight` - amount of requests in flight
121+
- `latency` - summary of latencies in ms
122+
- `attempts` - summary of amount for request
123+
- `error` - amount of errors
124+
- `query_latency` - summary of latencies in ms in query
125+
126+
> You must reset metrics to keep them `0` in prometheus and grafana before beginning and after ending of jobs
127+
128+
In `php` it looks like that:
129+
```php
130+
$pushGateway->delete('workload-php', [
131+
'sdk' => 'php',
132+
'sdkVersion' => Ydb::VERSION
133+
]);
134+
```
135+
136+
## Look at metrics in grafana
137+
You can get dashboard used in that test [here](https://github.com/ydb-platform/slo-tests/blob/main/k8s/helms/grafana.yaml#L69) - you will need to import json into grafana.

slo-workload/application.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
require_once './vendor/autoload.php';
3+
/**
4+
* @var \YdbPlatform\Ydb\Slo\Command[] $commands
5+
*/
6+
$commands = [
7+
"create" =>new \YdbPlatform\Ydb\Slo\Commands\CreateCommand(),
8+
"run" =>new \YdbPlatform\Ydb\Slo\Commands\RunCommand(),
9+
"cleanup" =>new \YdbPlatform\Ydb\Slo\Commands\CleanupCommand()
10+
];
11+
12+
if ($argc == 1 || !isset($commands[$argv[1]])){
13+
echo "Commands:\n";
14+
foreach ($commands as $name=>$command) {
15+
echo "- ".$name."\t"."- ".$command->description."\n";
16+
}
17+
exit(0);
18+
}
19+
20+
if ($argc<4||substr($argv[2],0,4)!="grpc" || substr($argv[3],0,1)!="/"){
21+
echo $commands[$argv[1]]->help;
22+
exit(0);
23+
}
24+
25+
$data = $commands[$argv[1]]->generateOptions(array_slice($argv, 4));
26+
27+
$command = $commands[$argv[1]];
28+
29+
$commands[$argv[1]]->execute($argv[2],$argv[3], $data);

slo-workload/composer.json

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"name": "ydb-platform/ydb-php-slo",
3+
"description": "YDB PHP SDK",
4+
"license": "Apache-2.0",
5+
"authors": [
6+
{
7+
"name": "Ilia Kharev",
8+
"email": "ilyakharev@ydb.tech"
9+
}
10+
],
11+
"repositories": [
12+
{
13+
"type": "path",
14+
"url": "./../"
15+
}
16+
],
17+
"require": {
18+
"ydb-platform/ydb-php-sdk": "@dev",
19+
"promphp/prometheus_push_gateway_php": "^v1.0.1",
20+
"ext-sysvmsg": "*"
21+
},
22+
"autoload": {
23+
"psr-4": {
24+
"YdbPlatform\\Ydb\\Slo\\": "src/"
25+
}
26+
}
27+
}

slo-workload/php-grpc.Dockerfile

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
FROM ubuntu:20.04
2+
LABEL authors="ilyakharev"
3+
4+
RUN apt-get upgrade
5+
RUN apt-get update
6+
RUN apt-get install -y software-properties-common
7+
RUN apt-get update
8+
RUN add-apt-repository -y ppa:ondrej/php
9+
RUN apt-get update
10+
RUN apt-get install -y libz-dev
11+
RUN apt-get update
12+
RUN apt-get install -y php7.2-fpm php7.2-cli php7.2-curl php7.2-json php-pear php7.2-dev php7.2-bcmath
13+
RUN apt-get install -y php7.2-xml
14+
RUN apt-get update
15+
RUN curl -sS https://getcomposer.org/installer | php
16+
RUN mv composer.phar /usr/local/bin/composer
17+
RUN pecl install grpc-1.45.0
18+
RUN echo "extension=grpc.so" >> /etc/php/7.2/cli/php.ini
19+
RUN apt-get install --fix-missing -y git
20+
RUN echo "grpc.enable_fork_support = 1" >> /etc/php/7.2/cli/php.ini
21+
RUN echo "grpc.poll_strategy = poll" >> /etc/php/7.2/cli/php.ini

slo-workload/src/Command.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
3+
namespace YdbPlatform\Ydb\Slo;
4+
5+
abstract class Command
6+
{
7+
public $name = "";
8+
public $description = "";
9+
public $options = [];
10+
11+
12+
public abstract function execute(string $endpoint, string $path, array $options);
13+
14+
public function generateOptions(array $args): array
15+
{
16+
$result = [];
17+
for ($i = 0; $i < count($args) - 1; $i++) {
18+
if (substr($args[$i], 0, 1) != "-") continue;
19+
if (substr($args[$i + 1], 0, 1) == "-") continue;
20+
$arg = substr($args[$i], 1);
21+
$option = null;
22+
foreach ($this->options as $opt) {
23+
if (in_array($arg, $opt["alias"])) {
24+
$option = $opt;
25+
break;
26+
}
27+
}
28+
if ($option) {
29+
$result[$opt["alias"][0]] = $args[$i + 1];
30+
}
31+
}
32+
return $result;
33+
}
34+
}

0 commit comments

Comments
 (0)