2015-06-08 7 views
5

Болт получает файловую блокировку в файле данных, поэтому несколько процессов не могут открыть одну и ту же базу данных одновременно. Открытие уже открытой базы данных Bolt приведет к зависанию, пока другой процесс не закроет ее.Хранилище данных с храповым значением Boltdb исключительно в Go

Как это имеет место, существует ли какая-либо концепция объединения соединений, например, различные клиенты, которые одновременно подключаются и получают доступ к базе данных? Возможно ли это в boltdb? Как и в то же время существуют различные соединения, которые читают и записывают в базу данных. Как это можно реализовать?

+1

Будучи файл на основе БД, это вряд ли изменится из-за способа блокировки файлов работы. Вероятно, это также лучший вопрос в репозитории Bolt, а не в StackOverflow: https://github.com/boltdb/bolt – elithrar

ответ

9

базы данные болта обычно встраиваются в большую программу и не используются в сети, как вы бы с общими базами данных (думает, SQLite против MySQL). Использование Bolt немного похоже на постоянное map[[]byte][]byte, если это возможно. В зависимости от того, что вы делаете, вы можете просто использовать что-то вроде Redis.

Сказанное, если вам нужно использовать Bolt таким образом, это не очень сложно обернуть простым сервером. Ниже приведен пример, который записывает/читает ключи из базы данных болтов через HTTP. Вы можете использовать Keep-Alive для объединения пулов.

Код по адресу: https://github.com/skyec/boltdb-server

package main 

import (
    "flag" 
    "fmt" 
    "io/ioutil" 
    "log" 
    "net/http" 
    "time" 

    "github.com/boltdb/bolt" 
    "github.com/gorilla/mux" 
) 

type server struct { 
    db *bolt.DB 
} 

func newServer(filename string) (s *server, err error) { 
    s = &server{} 
    s.db, err = bolt.Open(filename, 0600, &bolt.Options{Timeout: 1 * time.Second}) 
    return 
} 

func (s *server) Put(bucket, key, contentType string, val []byte) error { 
    return s.db.Update(func(tx *bolt.Tx) error { 
     b, err := tx.CreateBucketIfNotExists([]byte(bucket)) 
     if err != nil { 
      return err 
     } 
     if err = b.Put([]byte(key), val); err != nil { 
      return err 
     } 
     return b.Put([]byte(fmt.Sprintf("%s-ContentType", key)), []byte(contentType)) 
    }) 
} 

func (s *server) Get(bucket, key string) (ct string, data []byte, err error) { 
    s.db.View(func(tx *bolt.Tx) error { 
     b := tx.Bucket([]byte(bucket)) 
     r := b.Get([]byte(key)) 
     if r != nil { 
      data = make([]byte, len(r)) 
      copy(data, r) 
     } 

     r = b.Get([]byte(fmt.Sprintf("%s-ContentType", key))) 
     ct = string(r) 
     return nil 
    }) 
    return 
} 

func (s *server) ServeHTTP(w http.ResponseWriter, r *http.Request) { 
    vars := mux.Vars(r) 

    if vars["bucket"] == "" || vars["key"] == "" { 
     http.Error(w, "Missing bucket or key", http.StatusBadRequest) 
     return 
    } 

    switch r.Method { 
    case "POST", "PUT": 
     data, err := ioutil.ReadAll(r.Body) 
     if err != nil { 
      http.Error(w, err.Error(), http.StatusInternalServerError) 
      return 
     } 
     err = s.Put(vars["bucket"], vars["key"], r.Header.Get("Content-Type"), data) 
     w.WriteHeader(http.StatusOK) 
    case "GET": 
     ct, data, err := s.Get(vars["bucket"], vars["key"]) 
     if err != nil { 
      http.Error(w, err.Error(), http.StatusInternalServerError) 
      return 
     } 
     w.Header().Add("Content-Type", ct) 
     w.Write(data) 
    } 
} 

func main() { 
    var (
     addr string 
     dbfile string 
    ) 

    flag.StringVar(&addr, "l", ":9988", "Address to listen on") 
    flag.StringVar(&dbfile, "db", "/var/data/bolt.db", "Bolt DB file") 
    flag.Parse() 

    log.Println("Using Bolt DB file:", dbfile) 
    log.Println("Listening on:", addr) 

    server, err := newServer(dbfile) 
    if err != nil { 
     log.Fatalf("Error: %s", err) 
    } 

    router := mux.NewRouter() 
    router.Handle("/v1/buckets/{bucket}/keys/{key}", server) 
    http.Handle("/", router) 

    log.Fatal(http.ListenAndServe(addr, nil)) 
} 
+0

Спасибо большое! Я понял, как он отличается от других баз данных, которые совместно используются в сети. Он будет принадлежать одному процессу, который предоставляет API через сеть. –

+0

Звучит неплохо. Одно из преимуществ обертывания механизма хранения, как это, вы можете построить интерфейс для удовлетворения ваших конкретных потребностей. Используете ли вы только небольшие ключи и значения, в которых важна пропускная способность? Сделайте его интерфейсом UDP. Или, может быть, интерфейс protobuf более подходит для вас. Я буду продолжать возиться с этим кодом в качестве побочного проекта. Так что, вероятно, попробуйте каждый из них. Удачи. – SkyeC

+0

Существуют различные уникальные идентификаторы, и все торгуют суммой в размере миллисекунд, и я должен ее сохранить и обновить их текущие расходы (общая сумма ставок до этого времени) как можно скорее. Схема, которую я использую, похожа на - ведро для каждого уникального идентификатора и сохранение времени в качестве ключа и значения в качестве ставки. - общий ковш для всех уникальных и обновление их текущих расходов в этом где key = уникальный идентификатор и значение = последние текущие расходы. Как и в этом случае, какой интерфейс я должен использовать. И как я могу увеличить скорость обновления значения i.e.Я должен использовать db.Update() или db.Batch() и как? –

4

В boltdb отсутствует концепция объединения соединений, поскольку соединение отсутствует. Это не база данных клиент/сервер, это встроенная база данных (например, sqlite или Berkeley-DB).

Boltdb сконструирован таким образом, что несколько goroutines одного и того же процесса могут одновременно обращаться к базе данных (используя различные транзакции). Модель представляет собой единый писатель, несколько читателей. Boltdb не предназначен для поддержки доступа из нескольких процессов.

Если вам нужна программа Go использовать встроенную базу данных, поддерживающий доступ из нескольких процессов одновременно, вы можете захотеть взглянуть на обертках над LMDB, такими как:

+0

Хорошо! Благодарю. Может ли кто-нибудь создать тег boltDB, чтобы управлять дальнейшими запросами было легко. –

+0

болтb только что добавил. –

+0

Спасибо за добавление! –

 Смежные вопросы

  • Нет связанных вопросов^_^