Golang分布式内存数据库Olric:嵌入式键值存储方案
Golang分布式内存数据库Olric:嵌入式键值存储方案 Olric
分布式内存键值数据库。既可作为嵌入式 Go 库使用,也可作为跨语言服务独立运行。
核心特性
- 专为在服务器间共享临时性、近似性、快速变化的数据而设计
- 基于内存存储,支持可选的磁盘快照功能
- 支持嵌入式部署,也可通过 olricd 作为跨语言服务运行
- 支持多种键淘汰算法
- 快速的二进制通信协议
- 高可用与水平扩展能力
- 在非完整 CP 解决方案中提供最佳一致性保障
- 默认支持数据复制(含同步/异步模式)
- 支持原子操作
典型应用场景
- 键值存储
- 缓存系统
- 云应用扩展
- 服务发现
在 Github 上为 Olric 点赞:https://github.com/buraksezer/olric
更多关于Golang分布式内存数据库Olric:嵌入式键值存储方案的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于Golang分布式内存数据库Olric:嵌入式键值存储方案的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
以下是关于Olric分布式内存数据库的专业技术分析及嵌入式使用示例:
Olric作为Go语言实现的分布式内存数据库,其嵌入式模式通过olric.EmbeddedClient提供完整的分布式键值存储能力。以下展示核心功能的代码实现:
1. 嵌入式模式基础使用
package main
import (
"context"
"fmt"
"log"
"github.com/buraksezer/olric"
"github.com/buraksezer/olric/config"
)
func main() {
// 创建嵌入式配置
c := config.New("local")
c.BindAddr = "127.0.0.1"
c.BindPort = 0 // 自动选择端口
// 启动嵌入式节点
db, err := olric.New(c)
if err != nil {
log.Fatalf("Failed to create Olric instance: %v", err)
}
ctx := context.Background()
go func() {
// 启动服务
err = db.Start()
if err != nil {
log.Fatalf("Olric start failed: %v", err)
}
}()
// 等待节点启动完成
<-db.Started()
// 获取分布式映射
dm, err := db.NewDMap("my-map")
if err != nil {
log.Fatalf("Failed to create DMap: %v", err)
}
// 写入数据
err = dm.Put(ctx, "key1", "value1")
if err != nil {
log.Fatalf("Put operation failed: %v", err)
}
// 读取数据
val, err := dm.Get(ctx, "key1")
if err != nil {
log.Fatalf("Get operation failed: %v", err)
}
fmt.Printf("Retrieved value: %s\n", val)
// 原子操作示例
err = dm.PutIf(ctx, "counter", 1, olric.IfNotFound)
if err != nil {
log.Fatalf("PutIf failed: %v", err)
}
// 关闭数据库
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
db.Shutdown(ctx)
}
2. 分布式原子操作实现
// 原子递增操作
func atomicIncrement(dm *olric.DMap, key string) error {
ctx := context.Background()
// 使用 PutIf 实现原子操作
for {
current, err := dm.Get(ctx, key)
if err != nil && err != olric.ErrKeyNotFound {
return err
}
newValue := 1
if current != nil {
newValue = current.(int) + 1
}
// 条件写入实现原子性
err = dm.PutIf(ctx, key, newValue, olric.IfFound)
if err == nil {
break // 成功更新
}
if err != olric.ErrKeyNotFound {
return err
}
// 键不存在时创建
err = dm.PutIf(ctx, key, newValue, olric.IfNotFound)
if err == nil {
break
}
}
return nil
}
3. 集群配置示例
func setupCluster() *olric.Olric {
c := config.New("local")
// 集群成员配置
c.MemberlistConfig = memberlist.DefaultLocalConfig()
c.MemberlistConfig.BindAddr = "127.0.0.1"
c.MemberlistConfig.BindPort = 0
// 存储配置
c.DMaps = &config.DMaps{
NumEvictionWorkers: 4,
MaxIdleDuration: 10 * time.Minute,
}
// 副本配置
c.ReplicationMode = config.AsyncReplicationMode
c.ReplicaCount = 2
db, err := olric.New(c)
if err != nil {
log.Fatal(err)
}
return db
}
4. TTL和淘汰策略
func useWithTTL(dm *olric.DMap) error {
ctx := context.Background()
// 设置带TTL的键值
err := dm.PutEx(ctx, "session-data", "user123", 5*time.Minute)
if err != nil {
return err
}
// 检查键是否存在
exists, err := dm.Expire(ctx, "session-data", 10*time.Minute)
if err != nil {
return err
}
if exists {
fmt.Println("Key TTL updated successfully")
}
return nil
}
Olric在嵌入式场景下通过Go channel和goroutine实现高效的并发控制,其分布式映射(DMap)接口提供与标准map相似的API,同时保证在分布式环境下的数据一致性。基于Raft的分布式协议确保在节点故障时维持系统可用性,内置的LRU和TTL淘汰机制有效管理内存使用。

