
こんにちは、私の名前はIvanです。Tarantoolで高負荷ソリューションを開発しています。TarantoolでのアプリケーションのロードテストにPandoraを選択した方法と理由、およびその使用方法の例を示します。
テスト中のアプリケーションの説明
シャードキュー分散キューモジュールをテストして、キュータスクの挿入と取得がどれだけ迅速にできるかを確認しましょう。アプリケーションAPIは、データを使用して基本的な操作を実行したり、関数(RPC)を呼び出したり、カスタムluaコードを実行したりできるバイナリプロトコルに基づいています。私たちの場合、これらは2つの関数です:queue.tube_name:putとqueue.tube_name:take。
テストツールの選択
テストツールはたくさんありますが、その中から適切なものを選択する必要があります。以下の基準に従って選択します。
- バイナリプロトコルを歩く必要があります。したがって、Tarantoolへのコネクタがあるプログラミング言語でコードを作成する必要があります。Jmeter、bfg、Pandora、Gatlingがこれに対応しています。
- . Phantom, wrk, Jmeter, Pandora Gatling.
- . , , . bfg, Pandora Gatling.
-
. . influxdb, , Jmeter Gatling. Taurus ( ). . Jmeter, Pandora, bfg Phantom. - . , — .
, : . Jmeter Pandora, Taurus Jmeter Gatling.
Jmeter Gatlling?
Java-, Java, Groovy Scala . , , , Go.
Pandora — , Go ..
Go — ?
Pandora — ?
Go.
. — ?
, , c , , , .
as code
, , .
?
, .
go get github.com/tarantool/go-tarantool \
github.com/spf13/afero \
github.com/yandex/pandora
: , .
:
type Ammo struct { Method string TubeName string Params map[string] interface {} }
. , .
: .
tnt_queue_ammo.json:
{"Method": "put", "TubeName": "test-tube", "Params": {"data": "task"}} {"Method": "take", "TubeName": "test-tube"}
TubeName— sharded-queue.
:
type GunConfig struct { Target []string `validate:"required"` User string `validate:"required"` Pass string `validate:"required"` }
yaml- Pandoragun:
gun: type: tnt_queue_gun target: - localhost:3301 - localhost:3302 user: admin pass: queue-app-cluster-cookie
.
type.
:
type Gun struct { conn *tarantool.Connection conf GunConfig aggr core.Aggregator }
, ( Tarantool).
Bind. . .
func (g *Gun) Bind(aggr core.Aggregator, deps core.GunDeps) error { conn, err := tarantool.Connect( g.conf.Target[rand.Intn(len(g.conf.Target))], tarantool.Opts{ User: g.conf.User, Pass: g.conf.Pass, }, ) if err != nil { log.Fatalf("Error: %s", err) } g.conn = conn g.aggr = aggr return nil }
Shoot. . , , , .
queueCallTarantool go-tarantool:
func (g *Gun) Shoot(coreAmmo core.Ammo) { ammo := coreAmmo.(*Ammo) sample := netsample.Acquire(ammo.Method) code := 200 var err error startTime := time.Now() switch ammo.Method { case "put": _, err = g.queueCall(ammo.TubeName, "put", ammo.Params["data"]) case "take": _, err = g.queueCall(ammo.TubeName, "take") } sample.SetLatency(time.Since(startTime)) if err != nil { log.Printf("Error %s task: %s", ammo.Method, err) code = 500 } defer func() { sample.SetProtoCode(code) sample.AddTag(ammo.TubeName) g.aggr.Report(sample) }() }
:
- .
- ( HTTP).
- , .
: 20 . 25 . 60 . ( ) 1 .
rps:
duration: 60s
type: line
from: 20000
to: 25000
startup:
type: once
times: 1000
:
pandora:
enabled: true
package: yandextank.plugins.Pandora
pandora_cmd: ./tnt_queue_gun
config_file: ./tnt_queue_load.yaml
:
docker run -v $(pwd):/var/loadtest \
-v $SSH_AUTH_SOCK:/ssh-agent \
-e SSH_AUTH_SOCK=/ssh-agent \
--net host \
-it direvius/yandex-tank
:

Go- Tarantool, .
, queue.tube_name:ack, ID . , InfluxDB Grafana- Overload.
Pandoraのアーキテクチャと機能の詳細については、Heisenbugカンファレンスでの作成者のレポートを参照してください。