Golang中如何实现一个高效的键值存储服务
Golang中如何实现一个高效的键值存储服务 我正在寻找一个基础的键值对(KEY/VALUE)HTTP前端代码。 如果能看看现有的HTTP服务代码,会对我有很大帮助。
我成功使用过boltdb和leveldb,但我确信还有其他人写过类似的基础软件。 请给我展示一些代码。
3 回复
你是否在考虑像Redis缓存这样的服务?但是用Go语言编写的?
更多关于Golang中如何实现一个高效的键值存储服务的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
我想看一些为键值库提供 HTTP API 的代码。 我之前用 Go 写过一个名为 SquidBlocker 的数据库,它使用了 BoltDB 或 LevelDB。 在我着手开发 V2 版本之前,我正在寻找其他思路。
我自己还没有找到一个为 LevelDB 提供键值 HTTP API 的服务,而这正是我真正想开始着手的方向。
以下是一个基于Go标准库和BoltDB的高效键值存储HTTP服务实现:
package main
import (
"encoding/json"
"io"
"log"
"net/http"
"sync"
"time"
"github.com/boltdb/bolt"
)
type KeyValueStore struct {
db *bolt.DB
mu sync.RWMutex
}
func NewKeyValueStore(path string) (*KeyValueStore, error) {
db, err := bolt.Open(path, 0600, &bolt.Options{Timeout: 1 * time.Second})
if err != nil {
return nil, err
}
err = db.Update(func(tx *bolt.Tx) error {
_, err := tx.CreateBucketIfNotExists([]byte("kvstore"))
return err
})
return &KeyValueStore{db: db}, err
}
func (kvs *KeyValueStore) Close() error {
return kvs.db.Close()
}
func (kvs *KeyValueStore) Put(key, value string) error {
kvs.mu.Lock()
defer kvs.mu.Unlock()
return kvs.db.Update(func(tx *bolt.Tx) error {
b := tx.Bucket([]byte("kvstore"))
return b.Put([]byte(key), []byte(value))
})
}
func (kvs *KeyValueStore) Get(key string) (string, error) {
kvs.mu.RLock()
defer kvs.mu.RUnlock()
var value []byte
err := kvs.db.View(func(tx *bolt.Tx) error {
b := tx.Bucket([]byte("kvstore"))
v := b.Get([]byte(key))
if v != nil {
value = make([]byte, len(v))
copy(value, v)
}
return nil
})
if err != nil {
return "", err
}
if value == nil {
return "", nil
}
return string(value), nil
}
func (kvs *KeyValueStore) Delete(key string) error {
kvs.mu.Lock()
defer kvs.mu.Unlock()
return kvs.db.Update(func(tx *bolt.Tx) error {
b := tx.Bucket([]byte("kvstore"))
return b.Delete([]byte(key))
})
}
type Request struct {
Key string `json:"key"`
Value string `json:"value"`
}
type Response struct {
Success bool `json:"success"`
Value string `json:"value,omitempty"`
Error string `json:"error,omitempty"`
}
func main() {
kvs, err := NewKeyValueStore("mykvstore.db")
if err != nil {
log.Fatal(err)
}
defer kvs.Close()
http.HandleFunc("/get", func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
return
}
var req Request
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
value, err := kvs.Get(req.Key)
resp := Response{Success: err == nil}
if err != nil {
resp.Error = err.Error()
} else {
resp.Value = value
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(resp)
})
http.HandleFunc("/put", func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
return
}
var req Request
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
err := kvs.Put(req.Key, req.Value)
resp := Response{Success: err == nil}
if err != nil {
resp.Error = err.Error()
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(resp)
})
http.HandleFunc("/delete", func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
return
}
var req Request
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
err := kvs.Delete(req.Key)
resp := Response{Success: err == nil}
if err != nil {
resp.Error = err.Error()
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(resp)
})
http.HandleFunc("/batch", func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
return
}
var requests []Request
if err := json.NewDecoder(r.Body).Decode(&requests); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
results := make([]Response, len(requests))
for i, req := range requests {
err := kvs.Put(req.Key, req.Value)
results[i] = Response{
Success: err == nil,
Error: func() string { if err != nil { return err.Error() }; return "" }(),
}
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(results)
})
log.Println("Starting key-value store server on :8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
这个实现包含以下特性:
-
BoltDB集成:使用BoltDB作为底层存储引擎,提供ACID事务支持
-
线程安全:使用读写锁(sync.RWMutex)确保并发安全
-
RESTful API:
POST /get- 获取键值POST /put- 设置键值POST /delete- 删除键值POST /batch- 批量操作
-
JSON接口:所有请求和响应都使用JSON格式
使用示例:
# 设置键值
curl -X POST http://localhost:8080/put \
-H "Content-Type: application/json" \
-d '{"key":"user:1","value":"{\"name\":\"John\",\"age\":30}"}'
# 获取键值
curl -X POST http://localhost:8080/get \
-H "Content-Type: application/json" \
-d '{"key":"user:1"}'
# 批量操作
curl -X POST http://localhost:8080/batch \
-H "Content-Type: application/json" \
-d '[{"key":"key1","value":"value1"},{"key":"key2","value":"value2"}]'
这个实现提供了基础的键值存储HTTP服务,可以根据需要扩展更多功能,如TTL支持、数据压缩或集群功能。

