
Olá, meu nome é Ivan e estou desenvolvendo soluções de alta carga no Tarantool . Vou contar como e por que escolhemos o Pandora para testar a carga de um aplicativo no Tarantool, além de mostrar um exemplo de como usá-lo.
Descrição do aplicativo em teste
sharded-queue , . API , , (RPC), lua. : 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.
Para obter mais informações sobre a arquitetura e os recursos do Pandora, você pode consultar o relatório de seu criador na conferência Heisenbug.