Qui est votre Pandore et qu'est-ce que Tarantool a à voir avec cela?



Bonjour, je m'appelle Ivan et je développe des solutions à forte charge sur Tarantool . Je vais vous dire comment et pourquoi nous avons choisi Pandora pour tester en charge une application sur Tarantool, et vous montrer également un exemple de son utilisation.



Description de l'application testée



Testons le module de file d' attente distribuée à files partagées pour savoir à quelle vitesse nous pouvons insérer et récupérer les tâches de file d'attente . L'API de l'application est basée sur un protocole binaire qui vous permet d'effectuer des opérations de base sur les données, d'appeler des fonctions (RPC) et d'exécuter du code lua personnalisé. Dans notre cas, ce sont deux fonctions: queue.tube_name:putet queue.tube_name:take.



Choisir un outil de test



Il existe de nombreux outils de test, mais nous devons choisir les bons parmi eux. Nous sélectionnerons selon les critères suivants:



  1. Vous devez marcher sur un protocole binaire. Par conséquent, vous devrez écrire du code dans un langage de programmation pour lequel il existe un connecteur vers Tarantool. Jmeter, bfg, Pandora et Gatling en sont capables.
  2. Vous devez être capable de créer une charge relativement élevée avec des ressources modestes. Phantom, wrk, Jmeter, Pandora et Gatling peuvent tous fonctionner ici.
  3. Nous voulons tester des scénarios d'interaction complexes. Il est également utile de contrôler les caractéristiques de la charge, par exemple, créer une forte augmentation ou maintenir une valeur constante, bfg, Pandora et Gatling peuvent le faire en toute confiance.
  4. Nous voulons voir informatifbeaux graphismes. Ils sont utiles pour identifier les dépendances entre la charge et les erreurs qui se produisent. Ils peuvent être envoyés à influxdb, par exemple, Jmeter et Gatling. Beaucoup de choses peuvent fonctionner avec Taurus (liste complète ici ). Avec Yandex.Tank, Jmeter, Pandora, bfg et Phantom peuvent le faire.
  5. . , — .


, : . Jmeter Pandora, Taurus Jmeter Gatling.



Jmeter Gatlling?



Java-, Java, Groovy Scala . , , , Go.



Pandora — , Go ..



Go — ?



, , . Tarantool 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- Pandora gun:



    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. . , , , .



    queueCall Tarantool 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.



, .



Pour plus d'informations sur l'architecture et les capacités de Pandora, vous pouvez vous référer au rapport de son créateur sur la conférence Heisenbug.




All Articles