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. 05_Dockerfile实战(上)

    在上一章我们介绍了docker镜像的概念,并且介绍了构建镜像的两种方式 使用docker commit命令提交创建的容器. 使用Dockerfile文件和docker build命令,这种更为推荐和常 ...

  2. Java中关于Servlet中请求中文乱码及文件下载

    1,Servlet请求响应中文乱码问题 package com.demo.servlet; import java.io.PrintWriter; import java.io.IOException ...

  3. oracle中的greatest 函数和 least函数

    oracle中的greatest 函数和 least函数 原文地址:https://blog.csdn.net/sinat_32023305/article/details/78778596    g ...

  4. 手把手教你创建私有podspec

    本文来自 网易云社区 . CocoaPods是iOS非常好用的类库管理工具,可以非常方便的管理和更新项目中使用到的第三方库,以及将自己项目中的公共组件交由它管理. 工作中比较常用到的是通过CocoaP ...

  5. web前端开发插件(无需重复造轮子)

    1.artdialog 对话框组件 简介:是一个基于JavaScript编写的对话框组件,他拥有精致的界面与友好的接口 文档链接:http://www.daimajiayuan.com/downloa ...

  6. DP学习笔记

    DP学习笔记 可是记下来有什么用呢?我又不会 笨蛋你以后就会了 完全背包问题 先理解初始的DP方程: void solve() { for(int i=0;i<;i++) for(int j=0 ...

  7. gulp之几个常用插件介绍

    今天给大家分享一篇gulp几款插件的使用 以下代码用到得模块加载‘ const gulp=require("gulp"); const gulpSass=require(" ...

  8. MIPI调试经验(转载)

    目录 一.D-PHY 1.传输模式 2.Lane States 3.Lane Levels 4.操作模式 5.时序要求 二.DSI 1.线路构成 2.两种接口的 LCD 3.数据包类型 4.从控制器到 ...

  9. nexus3使用docker运行/创建docker私有仓库/maven私有仓库

    version: '3.2' services: nexus3: container_name: nexus3 hostname: nexus3 image: sonatype/nexus3:3.14 ...

  10. 爬虫常用的 urllib 库知识点

    urllib 库 urllib 库是 Python 中一个最基本的网络请求库.它可以模仿浏览器的行为向指定的服务器发送请求,同时可以保存服务器返回的数据. urlopen() 在 Python3 的 ...