douzhi4991 2018-03-31 19:42
浏览 38
已采纳

在Web服务器应用程序Golang中使用键值存储

I tried to get a simple key value store working inside of a go webserver app, which should store some information.

The issue is, I can only create one instance of it, since its writing to the disk and the folder is locked, so I need to find away to access the key value store with my Webserver.

So every current instance can access it (read/write). How do I do that?

Currently My app looks like that: https://play.golang.org/p/_SmGBZlP0Vi The Package I wanted to use is this: https://github.com/peterbourgon/diskv

Basically I would create an instance before the main and pass the instance of the key value store, to the rtt function, but that seems not directly be possible in go. Or do I something wrong?

  • 写回答

1条回答 默认 最新

  • duanan2732 2018-03-31 20:31
    关注

    Global Conn Instance

    First create a package with a single instance of the key value store and make the connection a package variable that you connect once and then keep open for all future use. Here some pseudo code sample:

    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)
    }
    

    That way yo have a "global" connection that can be used from everywhere. Simply call kvstore.Write(...) anywhere to write to the store.

    Sync concurrent access

    If your application uses multiple goroutines that can access the kvstore you (might -- depending if the package you use already does this for you or not) need to sync the access. You can do this by using a mutex for the connection:

    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)
    }
    

    You can also use the actor pattern. Here a post by Peter Bourgon that explains the actor pattern. With the actor pattern we can make sure the conn object is only used in one goroutine making the use of a mutex unnecessary.

    Simple kvstore package implementation

    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)
    }
    

    Sample usage of 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")
    }
    

    Just copy it in two different folders and try. It works.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 逻辑谓词和消解原理的运用
  • ¥15 请求分析基于spring boot+vue的前后端分离的项目
  • ¥15 三菱伺服电机按启动按钮有使能但不动作
  • ¥15 js,页面2返回页面1时定位进入的设备
  • ¥200 关于#c++#的问题,请各位专家解答!网站的邀请码
  • ¥50 导入文件到网吧的电脑并且在重启之后不会被恢复
  • ¥15 (希望可以解决问题)ma和mb文件无法正常打开,打开后是空白,但是有正常内存占用,但可以在打开Maya应用程序后打开场景ma和mb格式。
  • ¥20 ML307A在使用AT命令连接EMQX平台的MQTT时被拒绝
  • ¥20 腾讯企业邮箱邮件可以恢复么
  • ¥15 有人知道怎么将自己的迁移策略布到edgecloudsim上使用吗?