From c2f9c15c795eb736317fee0f87bf3d7afd02cdc7 Mon Sep 17 00:00:00 2001 From: lilin90 Date: Thu, 7 Jun 2018 11:02:27 +0800 Subject: [PATCH 1/3] tikv: update the usage example for Txn KV API --- tikv/go-client-api.md | 185 ++++++++++++++++++++++++++---------------- 1 file changed, 114 insertions(+), 71 deletions(-) diff --git a/tikv/go-client-api.md b/tikv/go-client-api.md index 5f1c7078d13aa..84790b3982b43 100644 --- a/tikv/go-client-api.md +++ b/tikv/go-client-api.md @@ -142,17 +142,26 @@ To use the Transactional Key-Value API in applications developed by golang, take 1. Install the necessary packages. ```bash + go get -v -u github.com/juju/errors go get -v -u github.com/pingcap/tidb/kv go get -v -u github.com/pingcap/tidb/store/tikv + go get -v -u golang.org/x/net/context ``` 2. Import the dependency packages. ```bash import ( + "flag" + "fmt" + "os" + + "github.com/juju/errors" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/store/tikv" - "fmt" + "github.com/pingcap/tidb/terror" + + goctx "golang.org/x/net/context" ) ``` @@ -184,92 +193,136 @@ To use the Transactional Key-Value API in applications developed by golang, take package main import ( - "context" + "flag" "fmt" - "strconv" + "os" + "github.com/juju/errors" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/store/tikv" + "github.com/pingcap/tidb/terror" + + goctx "golang.org/x/net/context" +) + +type KV struct { + K, V []byte +} + +func (kv KV) String() string { + return fmt.Sprintf("%s => %s (%v)", kv.K, kv.V, kv.V) +} + +var ( + store kv.Storage + pdAddr = flag.String("pd", "192.168.199.113:2379", "pd address:192.168.199.113:2379") ) -// if key not found, set value to zero -// else increase the value -func increase(storage kv.Storage, key []byte) error { - txn, err := storage.Begin() +// Init initializes information. +func initStore() { + driver := tikv.Driver{} + var err error + store, err = driver.Open(fmt.Sprintf("tikv://%s", *pdAddr)) + terror.MustNil(err) +} + +// key1 val1 key2 val2 ... +func puts(args ...[]byte) error { + tx, err := store.Begin() if err != nil { - return err + return errors.Trace(err) } - defer txn.Rollback() - var oldValue int - val, err := txn.Get(key) - if err != nil { - if !kv.ErrNotExist.Equal(err) { - return err - } - } else { - oldValue, err = strconv.Atoi(string(val)) + + for i := 0; i < len(args); i += 2 { + key, val := args[i], args[i+1] + err := tx.Set(key, val) if err != nil { - return err + return errors.Trace(err) } } - - err = txn.Set(key, []byte(strconv.Itoa(oldValue+1))) + err = tx.Commit(goctx.Background()) if err != nil { - return err + return errors.Trace(err) } - err = txn.Commit(context.Background()) + return nil } -// lookup value for key -func lookup(storage kv.Storage, key []byte) (int, error) { - var value int - txn, err := storage.Begin() - if err != nil { - return value, err - } - defer txn.Rollback() - val, err := txn.Get(key) +func get(k []byte) (KV, error) { + tx, err := store.Begin() if err != nil { - return value, err + return KV{}, errors.Trace(err) } - value, err = strconv.Atoi(string(val)) + v, err := tx.Get(k) if err != nil { - return value, err + return KV{}, errors.Trace(err) } - return value, nil + return KV{K: k, V: v}, nil } -func main() { - driver := tikv.Driver{} - storage, err := driver.Open("tikv://192.168.199.113:2379") +func dels(keys ...[]byte) error { + tx, err := store.Begin() if err != nil { - panic(err) + return errors.Trace(err) } - defer storage.Close() - - key := []byte("Account") - // lookup account - account, err := lookup(storage, key) + for _, key := range keys { + err := tx.Delete(key) + if err != nil { + return errors.Trace(err) + } + } + err = tx.Commit(goctx.Background()) if err != nil { - fmt.Printf("failed to lookup key %s: %v\n", key, err) - } else { - fmt.Printf("Account is %d\n", account) + return errors.Trace(err) } + return nil +} - // increase account - err = increase(storage, key) +func scan(keyPrefix []byte, limit int) ([]KV, error) { + tx, err := store.Begin() if err != nil { - panic(err) + return nil, errors.Trace(err) } - - // lookup account again - account, err = lookup(storage, key) + it, err := tx.Seek(keyPrefix) if err != nil { - fmt.Printf("failed to lookup key %s: %v\n", key, err) - } else { - fmt.Printf("Account increased to %d\n", account) + return nil, errors.Trace(err) + } + defer it.Close() + var ret []KV + for it.Valid() && limit > 0 { + ret = append(ret, KV{K: it.Key()[:], V: it.Value()[:]}) + limit-- + it.Next() } + return ret, nil +} + +func main() { + pdAddr := os.Getenv("PD_ADDR") + if pdAddr != "" { + os.Args = append(os.Args, "-pd", pdAddr) + } + flag.Parse() + initStore() + + // set + err := puts([]byte("key1"), []byte("value1"), []byte("key2"), []byte("value2")) + terror.MustNil(err) + + // get + kv, err := get([]byte("key1")) + terror.MustNil(err) + fmt.Println(kv) + + // scan + ret, err := scan([]byte("key"), 10) + for _, kv := range ret { + fmt.Println(kv) + } + + // delete + err = dels([]byte("key1"), []byte("key2")) + terror.MustNil(err) } ``` @@ -277,19 +330,9 @@ The result is like: ```bash INFO[0000] [pd] create pd client with endpoints [192.168.199.113:2379] -INFO[0000] [pd] leader switches to: http://127.0.0.1:2379, previous: -INFO[0000] [pd] init cluster id 6554145799874853483 -INFO[0000] [kv] Rollback txn 400197262324006914 -failed to lookup key Account: [kv:2]Error: key not exist -INFO[0000] [kv] Rollback txn 400197262324006917 -Account increased to 1 - -# run the program again -INFO[0000] [pd] create pd client with endpoints [192.168.199.113:2379] -INFO[0000] [pd] leader switches to: http://127.0.0.1:2379, previous: -INFO[0000] [pd] init cluster id 6554145799874853483 -INFO[0000] [kv] Rollback txn 400198364324954114 -Account is 1 -INFO[0000] [kv] Rollback txn 400198364324954117 -Account increased to 2 +INFO[0000] [pd] leader switches to: http://192.168.199.113:2379, previous: +INFO[0000] [pd] init cluster id 6563858376412119197 +key1 => value1 ([118 97 108 117 101 49]) +key1 => value1 ([118 97 108 117 101 49]) +key2 => value2 ([118 97 108 117 101 50]) ``` \ No newline at end of file From 5537cce5fa4bf10d9d86c894ccbad79f4ad9a5ac Mon Sep 17 00:00:00 2001 From: lilin90 Date: Fri, 8 Jun 2018 11:07:51 +0800 Subject: [PATCH 2/3] tikv: update the code fencing --- tikv/go-client-api.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tikv/go-client-api.md b/tikv/go-client-api.md index 84790b3982b43..88019e5d4ca00 100644 --- a/tikv/go-client-api.md +++ b/tikv/go-client-api.md @@ -15,13 +15,13 @@ To use the Raw Key-Value API in applications developed by golang, take the follo 1. Install the necessary packages. - ```bash + ```go go get -v -u github.com/pingcap/tidb/store/tikv ``` 2. Import the dependency packages. - ```bash + ```go import ( "fmt" "github.com/pingcap/tidb/config" @@ -31,7 +31,7 @@ To use the Raw Key-Value API in applications developed by golang, take the follo 3. Create a Raw Key-Value client. - ```bash + ```go cli, err := tikv.NewRawKVClient([]string{"192.168.199.113:2379"}, config.Security{}) ``` @@ -42,7 +42,7 @@ To use the Raw Key-Value API in applications developed by golang, take the follo 4. Call the Raw Key-Value client methods to access the data on TiKV. The Raw Key-Value API contains the following methods, and you can also find them at [GoDoc](https://godoc.org/github.com/pingcap/tidb/store/tikv#RawKVClient). - ```bash + ```go type RawKVClient struct func (c *RawKVClient) Close() error func (c *RawKVClient) ClusterID() uint64 @@ -54,7 +54,7 @@ To use the Raw Key-Value API in applications developed by golang, take the follo ### Usage example of the Raw Key-Value API -```bash +```go package main import ( @@ -141,7 +141,7 @@ To use the Transactional Key-Value API in applications developed by golang, take 1. Install the necessary packages. - ```bash + ```go go get -v -u github.com/juju/errors go get -v -u github.com/pingcap/tidb/kv go get -v -u github.com/pingcap/tidb/store/tikv @@ -150,7 +150,7 @@ To use the Transactional Key-Value API in applications developed by golang, take 2. Import the dependency packages. - ```bash + ```go import ( "flag" "fmt" @@ -167,7 +167,7 @@ To use the Transactional Key-Value API in applications developed by golang, take 3. Create Storage using a URL scheme. - ```bash + ```go driver := tikv.Driver{} storage, err := driver.Open("tikv://192.168.199.113:2379") ``` @@ -178,7 +178,7 @@ To use the Transactional Key-Value API in applications developed by golang, take 5. Call the Transactional Key-Value API's methods to access the data on TiKV. The Transactional Key-Value API contains the following methods: - ```bash + ```go Begin() -> Txn Txn.Get(key []byte) -> (value []byte) Txn.Set(key []byte, value []byte) @@ -189,7 +189,7 @@ To use the Transactional Key-Value API in applications developed by golang, take ### Usage example of the Transactional Key-Value API -```bash +```go package main import ( From ff68d47d2dbd0ee35991b1c1532ab56075796e7b Mon Sep 17 00:00:00 2001 From: lilin90 Date: Tue, 12 Jun 2018 10:58:38 +0800 Subject: [PATCH 3/3] tikv: address comments --- tikv/go-client-api.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tikv/go-client-api.md b/tikv/go-client-api.md index 88019e5d4ca00..72854ad927065 100644 --- a/tikv/go-client-api.md +++ b/tikv/go-client-api.md @@ -15,7 +15,7 @@ To use the Raw Key-Value API in applications developed by golang, take the follo 1. Install the necessary packages. - ```go + ```bash go get -v -u github.com/pingcap/tidb/store/tikv ``` @@ -141,7 +141,7 @@ To use the Transactional Key-Value API in applications developed by golang, take 1. Install the necessary packages. - ```go + ```bash go get -v -u github.com/juju/errors go get -v -u github.com/pingcap/tidb/kv go get -v -u github.com/pingcap/tidb/store/tikv