Who is this Pandora of yours and what does Tarantool have to do with it?



Hi, my name is Ivan and I am developing high-load solutions in Tarantool . I will tell you how and why we chose Pandora for load testing an application on Tarantool, as well as show an example of how to use it.



Description of the application under test



Let's test the sharded-queue distributed queue module for how quickly we can insert and retrieve queue tasks. The application API is based on a binary protocol that allows you to perform basic data operations, call functions (RPC), and execute custom lua code. In our case, these are two functions: queue.tube_name:putand queue.tube_name:take.



Choosing a testing tool



There are a lot of testing tools, but we need to choose the right ones among them. We will select according to the following criteria:



  1. You need to walk on a binary protocol. Therefore, you will have to write code in a programming language for which there is a connector to Tarantool. Jmeter, bfg, Pandora and Gatling are capable of this.
  2. . Phantom, wrk, Jmeter, Pandora Gatling.
  3. . , , . bfg, Pandora Gatling.
  4. . . influxdb, , Jmeter Gatling. Taurus ( ). . Jmeter, Pandora, bfg Phantom.
  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.



, .



For more information about the architecture and capabilities of Pandora, you can refer to the report of its creator on Heisenbug conference.




All Articles