import (
"fmt"
"github.com/allegro/bigcache"
"github.com/kooksee/usmint/cmn"
"github.com/pingcap/tidb/store/tikv"
"github.com/tendermint/tendermint/libs/log"
"os"
"time"
) var Name = "txs" var tdb *TikvStore func Init(logger log.Logger) {
tikv.MaxConnectionCount = 256 url := os.Getenv("TIKV")
if url == "" {
panic("please init tikv url")
} store, err := tikv.Driver{}.Open(fmt.Sprintf("tikv://%s/pd", url))
cmn.MustNotErr("TikvStore Init Error", err) cache, err := bigcache.NewBigCache(bigcache.DefaultConfig(30 * time.Minute))
if err != nil {
panic(fmt.Sprintf("init cache error: %s ", err.Error()))
} tdb = &TikvStore{
name: []byte(Name),
c: store,
cache: cache,
}
} func GetDb() *TikvStore {
if tdb == nil {
panic("please init usdb")
}
return tdb
} import (
"bytes"
"context"
"fmt"
"github.com/allegro/bigcache"
"github.com/kooksee/usmint/cmn"
"github.com/pingcap/tidb/kv"
"github.com/pingcap/tidb/store/tikv"
"github.com/tendermint/tendermint/libs/db"
) type TikvStore struct {
db.DB
name []byte
c kv.Storage
cache *bigcache.BigCache
} func NewTikvStore(name, url string) *TikvStore {
tikv.MaxConnectionCount = 256 // tikv://etcd-node1:port,etcd-node2:port?cluster=1&disableGC=false
store, err := tikv.Driver{}.Open(fmt.Sprintf("tikv://%s/pd", url))
cmn.MustNotErr("NewTikvStore Error", err)
return &TikvStore{
name: []byte(name),
c: store,
}
} func (db *TikvStore) withPrefix(key []byte) []byte {
return append(db.name, key...)
} func (db *TikvStore) withTxn(fn func(txn kv.Transaction) error) {
txn, err := db.c.Begin()
cmn.MustNotErr("tikv store open tx error", err)
if err := fn(txn); err != nil && !kv.IsErrNotFound(fn(txn)) {
cmn.MustNotErr("tikv store exec tx error", err)
} cmn.MustNotErr("tikv store exec tx error", fn(txn))
defer txn.Rollback()
cmn.MustNotErr("tikv store commit tx error", txn.Commit(context.TODO()))
} func (db *TikvStore) getSnapshot() kv.Snapshot {
ss, err := db.c.GetSnapshot(kv.MaxVersion)
cmn.MustNotErr("tikv store GetSnapshot error", err)
return ss
} // Implements DB.
func (db *TikvStore) Get(key []byte) []byte {
k := db.withPrefix(key) rt, err := db.cache.Get(string(k))
if err == nil && len(rt) != 0 {
return rt
} ret, err := db.getSnapshot().Get(k)
if !kv.IsErrNotFound(err) {
cmn.MustNotErr("tikv store Get error", err)
} if err := db.cache.Set(string(k), ret); err != nil {
cmn.Log().Error("cache set error", "err", err)
} return ret
} // Implements DB.
func (db *TikvStore) Has(key []byte) bool {
ret, err := db.getSnapshot().Get(db.withPrefix(key))
return (!kv.IsErrNotFound(err)) && (len(ret) != 0)
} // Implements DB.
func (db *TikvStore) Set(key []byte, value []byte) {
k := db.withPrefix(key) db.withTxn(func(txn kv.Transaction) (err error) {
if err := db.cache.Set(string(k), value); err != nil {
cmn.Log().Error("cache error", "err", err)
}
return txn.Set(k, value)
})
} // Implements DB.
func (db *TikvStore) SetSync(key []byte, value []byte) {
db.Set(key, value)
} // Implements DB.
func (db *TikvStore) Delete(key []byte) {
db.withTxn(func(txn kv.Transaction) (err error) {
return txn.Delete(db.withPrefix(key))
})
} // Implements DB.
func (db *TikvStore) DeleteSync(key []byte) {
db.Delete(key)
} // Implements DB.
func (db *TikvStore) Close() {
cmn.MustNotErr("TikvStore Close Error", db.c.Close())
} // Implements DB.
func (db *TikvStore) Print() {
} // Implements DB.
func (db *TikvStore) Stats() map[string]string {
//keys := []string{
// "leveldb.num-files-at-level{n}",
// "leveldb.stats",
// "leveldb.sstables",
// "leveldb.blockpool",
// "leveldb.cachedblock",
// "leveldb.openedtables",
// "leveldb.alivesnaps",
// "leveldb.aliveiters",
//} return make(map[string]string)
} //----------------------------------------
// Batch // Implements DB.
func (db *TikvStore) NewBatch() db.Batch {
return &tikvStoreBatch{data: make(map[string][]byte), db: db}
} type tikvStoreBatch struct {
db *TikvStore
data map[string][]byte
} // Implements Batch.
func (m *tikvStoreBatch) Set(key, value []byte) {
m.data[string(key)] = value
} // Implements Batch.
func (m *tikvStoreBatch) Delete(key []byte) {
delete(m.data, string(key))
} // Implements Batch.
func (m *tikvStoreBatch) Write() {
m.db.withTxn(func(txn kv.Transaction) error {
for k, v := range m.data {
if err := txn.Set([]byte(k), v); err != nil {
return err
}
}
return nil
})
} // Implements Batch.
func (m *tikvStoreBatch) WriteSync() {
m.Write()
} //----------------------------------------
// Iterator
// NOTE This is almost identical to db/c_level_db.Iterator
// Before creating a third version, refactor. // Implements DB.
func (db *TikvStore) Iterator(start, end []byte) db.Iterator {
it, err := db.getSnapshot().Seek(db.withPrefix(start))
cmn.MustNotErr("TikvStore Iterator Error", err)
return newTikvStoreIterator(db.name, false, it, db.withPrefix(start), db.withPrefix(end))
} // Implements DB.
func (db *TikvStore) ReverseIterator(start, end []byte) db.Iterator {
it, err := db.getSnapshot().SeekReverse(db.withPrefix(start))
cmn.MustNotErr("TikvStore ReverseIterator Error", err)
return newTikvStoreIterator(db.name, true, it, db.withPrefix(start), db.withPrefix(end))
} type tikvStoreIterator struct {
db.Iterator name []byte
r kv.Iterator
reverse bool
start []byte
end []byte
} func newTikvStoreIterator(name []byte, reverse bool, r kv.Iterator, start, end []byte) *tikvStoreIterator {
return &tikvStoreIterator{
name: name,
r: r,
reverse: reverse,
start: start,
end: end,
}
} // Implements Iterator.
func (itr *tikvStoreIterator) Domain() ([]byte, []byte) {
return itr.start, itr.end
} // Implements Iterator.
func (itr *tikvStoreIterator) Valid() bool {
if !itr.r.Valid() {
return false
} if !itr.reverse {
if bytes.Compare(itr.r.Key(), itr.end) > 0 {
return false
}
} else {
if bytes.Compare(itr.r.Key(), itr.start) < 0 {
return false
}
} return true
} // Implements Iterator.
func (itr *tikvStoreIterator) Key() []byte {
return bytes.TrimPrefix(itr.r.Key(), itr.name)
} // Implements Iterator.
func (itr *tikvStoreIterator) Value() []byte {
return itr.r.Value()
} // Implements Iterator.
func (itr *tikvStoreIterator) Next() {
cmn.MustNotErr("tikvStoreIterator next error", itr.r.Next())
} // Implements Iterator.
func (itr *tikvStoreIterator) Close() {
itr.r.Close()
}

tendermint 跟tikv结合的更多相关文章

  1. TIKV副本一致性检查机制分析

    背景 TIKV使用raft协议来实现副本同步,任何时刻写入一个KEY-VAL键值对,都会基于RAFT协议复制到不同机器的三个副本上,raft协议本身能保证副本同步的强一致性,但是任何系统都可能存在BU ...

  2. PBFT概念与Go语言入门(Tendermint基础)

    Tendermint作为当前最知名且实用的PBFT框架,网上资料并不很多,而实现Tendermint和以太坊的Go语言,由于相对小众,也存在资料匮乏和模糊错漏的问题.本文简单介绍PBFT概念和Go语言 ...

  3. TiKV 源码解析系列文章(三)Prometheus(上)

    本文为 TiKV 源码解析系列的第三篇,继续为大家介绍 TiKV 依赖的周边库 rust-prometheus,本篇主要介绍基础知识以及最基本的几个指标的内部工作机制,下篇会介绍一些高级功能的实现原理 ...

  4. Tidb进行缩减扩容tikv节点

    这两天接到任务说是要进行测试缩减机器给集群带来的负面效果有哪些. 然后我就按照官方的教程将机器进行了缩减,主要是缩减tikv节点 我们先来看看官方的文章是怎么写的: 步骤都没有什么问题,就是进行到第二 ...

  5. Tidb缩减tikv机器

    生产环境下,如何缩减机器? 1.首先是检查出来那个tikv节点需要缩减 " -d store { ", "stores": [ { "store&qu ...

  6. tikv性能参数调优

    tiKV 最底层使用的是 RocksDB(tidb3.0版本中将使用tian存储引擎) 做为持久化存储,所以 TiKV 的很多性能相关的参数都是与 RocksDB 相关的.TiKV 使用了两个 Roc ...

  7. TiKV 源码解析系列——如何使用 Raft

    本系列文章主要面向 TiKV 社区开发者,重点介绍 TiKV 的系统架构,源码结构,流程解析.目的是使得开发者阅读之后,能对 TiKV 项目有一个初步了解,更好的参与进入 TiKV 的开发中. 需要注 ...

  8. TiKV 源码解析系列 - Raft 的优化

    本系列文章主要面向 TiKV 社区开发者,重点介绍 TiKV 的系统架构,源码结构,流程解析.目的是使得开发者阅读之后,能对 TiKV 项目有一个初步了解,更好的参与进入 TiKV 的开发中.本文是本 ...

  9. tikv 安装

    export HostIP="127.0.0.1" docker run -d -p 2379:2379 -p 2380:2380 --name pd pingcap/pd \ - ...

随机推荐

  1. 关于contentquery webpart的pdf文件如何在OOS上打开,并且所有文件在浏览器新起的页面打开?

    function SetHref(pdf) { var c = pdf.href; var d = "http://eds.jd.com"; var f = "" ...

  2. 修改Mac系统host文件

    第一步.在终端里面输入 sudo -i 获取临时获取管理员权限,会提示你输入密码,就是启动的密码. 第二步.输入 vi /etc/hosts  前面的vi是编辑器,当然也可以换用其他的,例如上面的na ...

  3. OO第三次博客作业——规格

    OO第三次博客作业——规格 一.调研结果: 规格的历史: 引自博文链接:http://blog.sina.com.cn/s/blog_473d5bba010001x9.html 传统科学的特点是发现世 ...

  4. Redis 单机和多实例部署

    作者:北京运维 1. 安装环境说明 OS 版本:CentOS 7.5.1804 Redis 版本:redis-3.2.12 Redis 下载页面:http://download.redis.io/re ...

  5. ubuntu 安装linux 下vmVMware tools 步骤及问题解决

    一. 菜单栏     “虚拟机” ——> “设置 ”     使用linux.so镜像文件    此文件在vmware workstation 的安装目录.并且打开CD/DVD的连接. 二.终端 ...

  6. 构建WebGL目标时的内存考量

    Memory Considerations when targeting WebGL 构建WebGL目标时的内存考量 Memory in Unity WebGL can be a constraini ...

  7. 树莓3B+_中文支持安装输入法

    参考: https://www.cnblogs.com/collisionzhang/p/7413349.html 莓派默认是采用英文字库的,而且系统里没有预装中文字库,所以即使你在locale中改成 ...

  8. 如何通过SQL语句写入webshell

    在web应用场景下,经常会碰到SQL注入场景,如页面能够执行SQL语句,那么可能会有直接通过SQL语句写入webshell的风险,常见的phpmyadmin环境下,通过几个语句可以轻松将一句话木马写入 ...

  9. 20155216 2016-2017-2《Java程序设计》课程总结

    20155216 2016-2017-2<Java程序设计>课程总结 (按顺序)每周作业链接汇总 预备作业1:简要内容:我对师生关系的见解 预备作业2:简要内容:有关C语言学习调查以及学习 ...

  10. 20155217 实验四 Android程序设计

    20155217 实验四 Android程序设计 任务一: 完成Hello World, 要求修改res目录中的内容,Hello World后要显示自己的学号. R.java文件是定义该项目所有资源的 ...