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淘汰机制有效管理内存使用。

回到顶部