Translations:
go-vshard-router is a library for sending requests to a sharded tarantool cluster directly, without using tarantool-router. This library based on tarantool vhsard library router. go-vshard-router takes a new approach to creating your cluster
Old cluster schema
graph TD
subgraph Tarantool Database Cluster
subgraph Replicaset 1
Master_001_1
Replica_001_2
end
end
ROUTER1["Tarantool vshard-router 1_1"] --> Master_001_1
ROUTER2["Tarantool vshard-router 1_2"] --> Master_001_1
ROUTER3["Tarantool vshard-router 1_3"] --> Master_001_1
ROUTER1["Tarantool vshard-router 1_1"] --> Replica_001_2
ROUTER2["Tarantool vshard-router 1_2"] --> Replica_001_2
ROUTER3["Tarantool vshard-router 1_3"] --> Replica_001_2
GO["Golang service"]
GO --> ROUTER1
GO --> ROUTER2
GO --> ROUTER3
New cluster schema
graph TD
subgraph Application Host
Golang-Service
end
Golang-Service --> |iproto| MASTER1
Golang-Service --> |iproto| REPLICA1
MASTER1["Master 001_1"]
REPLICA1["Replica 001_2"]
subgraph Tarantool Database Cluster
subgraph Replicaset 1
MASTER1
REPLICA1
end
end
ROUTER1["Tarantool vshard-router(As contorol plane)"]
ROUTER1 --> MASTER1
ROUTER1 --> REPLICA1
With Go module support, simply add the following import
import "github.com/KaymeKaydex/go-vshard-router"
to your code, and then go [build|run|test]
will automatically fetch the necessary dependencies.
Otherwise, run the following Go command to install the go-vshard-router
package:
$ go get -u github.com/KaymeKaydex/go-vshard-router
First you need to import Go-Vshard-Router package for using Go-Vshard-Router
package main
import (
"context"
"fmt"
"strconv"
"time"
vshardrouter "github.com/KaymeKaydex/go-vshard-router"
"github.com/KaymeKaydex/go-vshard-router/providers/static"
"github.com/google/uuid"
"github.com/tarantool/go-tarantool/v2"
"github.com/tarantool/go-tarantool/v2/pool"
)
func main() {
ctx := context.Background()
directRouter, err := vshardrouter.NewRouter(ctx, vshardrouter.Config{
DiscoveryTimeout: time.Minute,
DiscoveryMode: vshardrouter.DiscoveryModeOn,
TopologyProvider: static.NewProvider(map[vshardrouter.ReplicasetInfo][]vshardrouter.InstanceInfo{
vshardrouter.ReplicasetInfo{
Name: "replcaset_1",
UUID: uuid.New(),
}: {
{
Addr: "127.0.0.1:1001",
UUID: uuid.New(),
},
{
Addr: "127.0.0.1:1002",
UUID: uuid.New(),
},
},
vshardrouter.ReplicasetInfo{
Name: "replcaset_2",
UUID: uuid.New(),
}: {
{
Addr: "127.0.0.1:2001",
UUID: uuid.New(),
},
{
Addr: "127.0.0.1:2002",
UUID: uuid.New(),
},
},
}),
TotalBucketCount: 128000,
PoolOpts: tarantool.Opts{
Timeout: time.Second,
},
})
if err != nil {
panic(err)
}
user := struct {
ID uint64
}{
ID: 123,
}
bucketID := vshardrouter.BucketIDStrCRC32(strconv.FormatUint(user.ID, 10), directRouter.RouterBucketCount())
interfaceResult, getTyped, err := directRouter.RouterCallImpl(
ctx,
bucketID,
vshardrouter.CallOpts{VshardMode: vshardrouter.ReadMode, PoolMode: pool.PreferRO, Timeout: time.Second * 2},
"storage.api.get_user_info",
[]interface{}{&struct {
BucketID uint64 `msgpack:"bucket_id" json:"bucket_id,omitempty"`
Body map[string]interface{} `msgpack:"body"`
}{
BucketID: bucketID,
Body: map[string]interface{}{
"user_id": "123456",
},
}},
)
info := &struct {
BirthDay int
}{}
err = getTyped(&[]interface{}{info})
if err != nil {
panic(err)
}
fmt.Printf("interface result: %v", interfaceResult)
fmt.Printf("get typed result: %v", info)
}
Learn with th Quick Start, which include examples and theory.
Service with go-vshard-router on top of the tarantool example from the original vshard library using raft
Benchmark | Runs | Time (ns/op) | Memory (B/op) | Allocations (allocs/op) |
---|---|---|---|---|
BenchmarkCallSimpleInsert_GO-8 | 9844 | 114596 | 1894 | 41 |
BenchmarkCallSimpleInsert_Lua-8 | 7587 | 156181 | 1101 | 19 |
BenchmarkCallSimpleSelect_GO-8 | 16350 | 75770 | 2827 | 60 |
BenchmarkCallSimpleSelect_Lua-8 | 10060 | 116768 | 1610 | 28 |
Topology:
- 4 replicasets (x2 instances per rs)
- 4 tarantool proxy
- 1 golang service
constant VUes scenario: at a load close to production
select