tendermint 跟tikv结合
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结合的更多相关文章
- TIKV副本一致性检查机制分析
背景 TIKV使用raft协议来实现副本同步,任何时刻写入一个KEY-VAL键值对,都会基于RAFT协议复制到不同机器的三个副本上,raft协议本身能保证副本同步的强一致性,但是任何系统都可能存在BU ...
- PBFT概念与Go语言入门(Tendermint基础)
Tendermint作为当前最知名且实用的PBFT框架,网上资料并不很多,而实现Tendermint和以太坊的Go语言,由于相对小众,也存在资料匮乏和模糊错漏的问题.本文简单介绍PBFT概念和Go语言 ...
- TiKV 源码解析系列文章(三)Prometheus(上)
本文为 TiKV 源码解析系列的第三篇,继续为大家介绍 TiKV 依赖的周边库 rust-prometheus,本篇主要介绍基础知识以及最基本的几个指标的内部工作机制,下篇会介绍一些高级功能的实现原理 ...
- Tidb进行缩减扩容tikv节点
这两天接到任务说是要进行测试缩减机器给集群带来的负面效果有哪些. 然后我就按照官方的教程将机器进行了缩减,主要是缩减tikv节点 我们先来看看官方的文章是怎么写的: 步骤都没有什么问题,就是进行到第二 ...
- Tidb缩减tikv机器
生产环境下,如何缩减机器? 1.首先是检查出来那个tikv节点需要缩减 " -d store { ", "stores": [ { "store&qu ...
- tikv性能参数调优
tiKV 最底层使用的是 RocksDB(tidb3.0版本中将使用tian存储引擎) 做为持久化存储,所以 TiKV 的很多性能相关的参数都是与 RocksDB 相关的.TiKV 使用了两个 Roc ...
- TiKV 源码解析系列——如何使用 Raft
本系列文章主要面向 TiKV 社区开发者,重点介绍 TiKV 的系统架构,源码结构,流程解析.目的是使得开发者阅读之后,能对 TiKV 项目有一个初步了解,更好的参与进入 TiKV 的开发中. 需要注 ...
- TiKV 源码解析系列 - Raft 的优化
本系列文章主要面向 TiKV 社区开发者,重点介绍 TiKV 的系统架构,源码结构,流程解析.目的是使得开发者阅读之后,能对 TiKV 项目有一个初步了解,更好的参与进入 TiKV 的开发中.本文是本 ...
- tikv 安装
export HostIP="127.0.0.1" docker run -d -p 2379:2379 -p 2380:2380 --name pd pingcap/pd \ - ...
随机推荐
- LINUX下安装pcre出现WARNING: 'aclocal-1.15' is missing on your system错误的解决办法
1.下载安装包 wget https://ftp.gnu.org/gnu/automake/automake-1.15.tar.gz 2.解压 tar -xzvf automake-1.15.tar. ...
- SaltStack 自动化工具
1.服务端安装master: # yum -y install salt-master # yum -y install salt-minion 2.客户端安装minion: # yum -y ins ...
- iOS利用block实现链式编程方法(Objective-C链式编程)
objc利用block实现链式编程方法 因为不好读.block和其他语言的匿名函数一样,很多程序员刚开始很难主动去用他. 本文描述block作为属性的实际使用,看懂block,并讲解如何利用block ...
- CentOS6.10安装详解
一.简介 CentOS(Community Enterprise Operating System,中文意思是社区企业操作系统)是Linux发行版之一,它是来自于Red Hat Enterpriser ...
- grub启动引导程序配置及命令行接口详解
Grub(GRand Unified Bootloader),统一资源引导器,它的工作是提供一个菜单,允许用户选择要启动的系统或不同的内核版本:把用户选定的内核装载到RAM中的特定空间中,然后解压.展 ...
- 帝国CMS站点迁移
1.重新安装xmapp环境 安装包地址 链接:https://pan.baidu.com/s/1OSwlP90G9VMAZYVXMG245Q 提取码:gnfr 2.安装后启动 3.复制数据库信息 将旧 ...
- MongoDB DBA 实践2-----常用语句与索引
一.mongodb常用语句 1.数据库database 1). 查看当前选择的数据库,默认是test 2).有则使用这个数据库,没有就创建 3).查看数据库,默认有admin.local和" ...
- 虚拟机与ARM之间的交叉编译总结
通过三大服务的配置,我们可以在ARM中下载内核和文件系统.我们通过在虚拟机中编程,得到的程序不能在ARM中运行,需要经过一个交叉编译.得到的可执行程序可以在ARM中运行,此时不能在虚拟机Linux中运 ...
- Kafka(1)-概述
一. 内部原理 1. 点对点模式(一对一,消费者主动拉取数据,消息收到后消息清除) 点对点模型通常是一个基于拉取或者轮询的消息传送模型,这种模型从队列中请求信息,而不是将消息推送到客户端.这个模型的特 ...
- python paramiko模块和多线程讲解
1.paramiko 实现ssh 登录 import paramiko # 实现ssh登录 ssh_client = paramiko.SSHClient() ssh_client.set_missi ...