首页 文章

在webserver应用程序golang中使用键值存储

提问于
浏览
1

我试图让一个简单的键值存储在一个go webserver应用程序中运行,它应该存储一些信息 .

问题是,我只能创建它的一个实例,因为它写入磁盘和文件夹是锁定的,所以我需要找到使用我的Web服务器访问键值存储 .

因此每个当前实例都可以访问它(读/写) . 我怎么做?

目前我的应用程序看起来像这样:https://play.golang.org/p/_SmGBZlP0Vi我想要使用的包是:https://github.com/peterbourgon/diskv

基本上我会在main之前创建一个实例并将键值存储的实例传递给rtt函数,但这似乎不可能在go中直接实现 . 或者我做错了什么?

1 回答

  • 1

    Global Conn Instance

    首先使用键值存储的单个实例创建一个包,并使连接成为您连接一次的包变量,然后保持打开以供将来使用 . 这里有一些伪代码示例:

    package kvstore
    
    var conn *diskv.Conn // or whatever the type of the conn is
    
    func Connect(...) {
        // crate connection and fill conn
        conn = diskv.New(...)
    }
    
    func Write(k, v []byte) error {
        return conn.Write(k, v)
    }
    

    这样你就可以在任何地方使用"global"连接 . 只需在任何地方拨打 kvstore.Write(...) 即可写入商店 .

    同步并发访问

    如果您的应用程序使用多个可以访问kvstore的goroutine(可能 - 取决于您使用的包是否已经为您执行此操作)需要同步访问权限 . 您可以使用互斥锁进行连接:

    var (
        conn *diskv.Conn // or whatever the type of the conn is
        mutex sync.Mutex
    )
    
    func Write(k, v []byte) error {
        // everywhere you use the conn object, lock the mutex before and unlock after
        mutex.Lock()
        defer mutex.Unlock()
        return conn.Write(k, v)
    }
    

    您还可以使用actor模式 . 这里有一篇由Peter Bourgon撰写的文章,解释了actor pattern . 使用actor模式,我们可以确保conn对象仅用于一个goroutine,因此不需要使用互斥锁 .

    简单的kvstore包实现

    package kvstore
    
    import "github.com/peterbourgon/diskv"
    
    var conn *diskv.Diskv
    
    // Connect opens the global diskv db
    func Connect(dir string) {
        flatTransform := func(s string) []string { return []string{} }
    
        conn = diskv.New(diskv.Options{
            BasePath:     dir,
            Transform:    flatTransform,
            CacheSizeMax: 1024 * 1024,
        })
    }
    
    // Write writes to the global diskv db
    func Write(k string, v []byte) error {
        return conn.Write(k, v)
    }
    
    // Read reads from the global diskv db
    func Read(k string) ([]byte, error) {
        return conn.Read(k)
    }
    
    // Erase deletes a key from the global discv db
    func Erase(k string) error {
        return conn.Erase(k)
    }
    

    kvstore的示例用法

    package main
    
    import (
        "github.com/tehsphinx/diskv"
    )
    
    func main() {
        // call this once in startup sequence.
        kvstore.Connect("my-data-dir")
    
        // use this anywhere to write to key value store
        kvstore.Write("alpha", []byte{'1', '2', '2'})
    
        // use this anywhere to read from kvstore
        kvstore.Read("alpha")
    
        // use this anywhere to delete from kvstore
        kvstore.Erase("alpha")
    }
    

    只需将其复制到两个不同的文件夹中即可 . 有用 .

相关问题