golang使用memcached为Google Cloud Datastore添加缓存的插件库godscache的使用

Golang使用memcached为Google Cloud Datastore添加缓存的插件库godscache的使用

概述

godscache是一个非官方的Google Cloud Platform Go Datastore包装器,它通过memcached添加了缓存功能。适用于App Engine Flexible、Compute Engine、Kubernetes Engine等环境。

功能特点

  • 为Google Cloud Datastore提供memcached缓存层
  • 减少对Datastore的直接访问,提高性能
  • 支持多种Google Cloud环境部署

安装

go get github.com/defcronyke/godscache

完整示例Demo

下面是一个完整的示例,展示如何使用godscache为Google Cloud Datastore添加memcached缓存:

package main

import (
	"context"
	"log"
	"time"

	"cloud.google.com/go/datastore"
	"github.com/bradfitz/gomemcache/memcache"
	"github.com/defcronyke/godscache"
)

// 定义数据模型
type Person struct {
	Name     string
	Age      int
	LastSeen time.Time
}

func main() {
	ctx := context.Background()

	// 1. 创建原生Datastore客户端
	dsClient, err := datastore.NewClient(ctx, "your-project-id")
	if err != nil {
		log.Fatalf("Failed to create datastore client: %v", err)
	}

	// 2. 创建memcached客户端
	mc := memcache.New("127.0.0.1:11211") // memcached服务器地址

	// 3. 创建带缓存的Datastore客户端
	cachedDS := godscache.New(dsClient, mc)

	// 4. 定义实体键
	key := datastore.NameKey("Person", "john_doe", nil)

	// 5. 存储数据(会自动缓存)
	person := &Person{
		Name:     "John Doe",
		Age:      30,
		LastSeen: time.Now(),
	}
	if _, err := cachedDS.Put(ctx, key, person); err != nil {
		log.Fatalf("Failed to save person: %v", err)
	}

	// 6. 读取数据(先从缓存尝试)
	var fetchedPerson Person
	if err := cachedDS.Get(ctx, key, &fetchedPerson); err != nil {
		log.Fatalf("Failed to fetch person: %v", err)
	}

	log.Printf("Fetched person: %+v", fetchedPerson)

	// 7. 删除数据(同时清除缓存)
	if err := cachedDS.Delete(ctx, key); err != nil {
		log.Fatalf("Failed to delete person: %v", err)
	}
}

高级用法

自定义缓存过期时间

// 创建带自定义缓存配置的Datastore客户端
config := &godscache.Config{
	Expiration: 10 * time.Minute, // 设置缓存过期时间为10分钟
}
cachedDS := godscache.NewWithConfig(dsClient, mc, config)

批量操作

// 批量获取
keys := []*datastore.Key{key1, key2, key3}
people := make([]Person, len(keys))
if err := cachedDS.GetMulti(ctx, keys, people); err != nil {
    log.Fatalf("Failed to fetch people: %v", err)
}

// 批量存储
if _, err := cachedDS.PutMulti(ctx, keys, people); err != nil {
    log.Fatalf("Failed to save people: %v", err)
}

注意事项

  1. 确保memcached服务已正确安装并运行
  2. 对于频繁更新的数据,需要权衡缓存带来的性能提升和数据一致性的要求
  3. 缓存键是基于Datastore的Key生成的,确保Key的唯一性

通过使用godscache,您可以显著减少对Google Cloud Datastore的直接访问,降低延迟和成本,同时保持数据的一致性。


更多关于golang使用memcached为Google Cloud Datastore添加缓存的插件库godscache的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang使用memcached为Google Cloud Datastore添加缓存的插件库godscache的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


godscache: 为Google Cloud Datastore添加Memcached缓存

godscache是一个Go语言库,它为Google Cloud Datastore提供了Memcached缓存层。这个库可以显著减少对Datastore的直接访问次数,提高应用性能并降低操作成本。

安装

go get github.com/bradfitz/gomemcache/memcache
go get github.com/tomasen/godscache

基本用法

初始化

package main

import (
	"context"
	"log"
	"time"

	"cloud.google.com/go/datastore"
	"github.com/bradfitz/gomemcache/memcache"
	"github.com/tomasen/godscache"
)

func main() {
	ctx := context.Background()

	// 初始化Datastore客户端
	dsClient, err := datastore.NewClient(ctx, "your-project-id")
	if err != nil {
		log.Fatalf("Failed to create datastore client: %v", err)
	}

	// 初始化Memcached客户端
	mc := memcache.New("127.0.0.1:11211") // Memcached服务器地址
	mc.Timeout = 100 * time.Millisecond   // 设置超时

	// 创建带缓存的Datastore客户端
	cachedDS := godscache.Wrap(dsClient, mc, &godscache.Options{
		Expiration: 5 * time.Minute, // 缓存过期时间
	})
	
	// 现在可以使用cachedDS代替原始的dsClient
}

基本操作示例

type Post struct {
	Title   string
	Content string
	Created time.Time
}

func demoOperations(ctx context.Context, cachedDS *godscache.Wrapper) {
	// 创建新实体
	key := datastore.IncompleteKey("Post", nil)
	post := &Post{
		Title:   "Hello World",
		Content: "This is my first post",
		Created: time.Now(),
	}
	
	// 插入数据(会同时缓存)
	if _, err := cachedDS.Put(ctx, key, post); err != nil {
		log.Fatalf("Failed to save post: %v", err)
	}

	// 获取数据(首先尝试从缓存获取)
	var fetchedPost Post
	if err := cachedDS.Get(ctx, key, &fetchedPost); err != nil {
		log.Fatalf("Failed to get post: %v", err)
	}
	log.Printf("Fetched post: %+v", fetchedPost)

	// 更新数据(会更新缓存)
	post.Content = "Updated content"
	if _, err := cachedDS.Put(ctx, key, post); err != nil {
		log.Fatalf("Failed to update post: %v", err)
	}

	// 删除数据(会清除缓存)
	if err := cachedDS.Delete(ctx, key); err != nil {
		log.Fatalf("Failed to delete post: %v", err)
	}
}

高级功能

批量操作

func batchOperations(ctx context.Context, cachedDS *godscache.Wrapper) {
	// 批量插入
	keys := []*datastore.Key{
		datastore.IncompleteKey("Post", nil),
		datastore.IncompleteKey("Post", nil),
	}
	posts := []*Post{
		{Title: "Post 1", Content: "Content 1"},
		{Title: "Post 2", Content: "Content 2"},
	}
	
	if _, err := cachedDS.PutMulti(ctx, keys, posts); err != nil {
		log.Fatalf("Failed to batch insert: %v", err)
	}

	// 批量获取
	var fetchedPosts []Post
	if err := cachedDS.GetMulti(ctx, keys, fetchedPosts); err != nil {
		log.Fatalf("Failed to batch get: %v", err)
	}

	// 批量删除
	if err := cachedDS.DeleteMulti(ctx, keys); err != nil {
		log.Fatalf("Failed to batch delete: %v", err)
	}
}

事务支持

func transactionDemo(ctx context.Context, cachedDS *godscache.Wrapper) {
	key := datastore.IncompleteKey("Post", nil)
	post := &Post{
		Title:   "Transactional Post",
		Content: "This will be saved in a transaction",
	}

	// 开始事务
	tx, err := cachedDS.NewTransaction(ctx)
	if err != nil {
		log.Fatalf("Failed to start transaction: %v", err)
	}

	// 在事务中操作
	if _, err := tx.Put(key, post); err != nil {
		tx.Rollback()
		log.Fatalf("Failed to put in transaction: %v", err)
	}

	// 提交事务(成功后才会更新缓存)
	if _, err := tx.Commit(); err != nil {
		log.Fatalf("Failed to commit transaction: %v", err)
	}
}

配置选项

godscache提供了多种配置选项:

options := &godscache.Options{
	Expiration:     10 * time.Minute,  // 默认缓存过期时间
	CacheErrors:    false,            // 是否缓存错误
	KeyMangler:     nil,              // 自定义缓存键生成器
	Marshal:        nil,              // 自定义序列化方法
	Unmarshal:      nil,              // 自定义反序列化方法
	Logf:          func(format string, args ...interface{}) {
		log.Printf(format, args...)
	},                                // 日志记录函数
}

cachedDS := godscache.Wrap(dsClient, mc, options)

最佳实践

  1. 合理设置过期时间:根据数据更新频率设置合适的缓存时间
  2. 监控缓存命中率:添加日志记录缓存命中情况
  3. 处理缓存失效:重要数据变更时考虑主动清除缓存
  4. 避免大对象缓存:Memcached有大小限制(默认1MB)
  5. 考虑命名空间:在多租户环境中使用不同的命名空间

性能考虑

  • 对于频繁读取但很少修改的数据,缓存效果最好
  • 批量操作比单条操作效率更高
  • 事务中的操作只在提交成功后更新缓存
  • 监控Memcached服务器内存使用情况

通过合理使用godscache,可以显著降低Google Cloud Datastore的读取延迟和操作成本,同时保持数据的一致性。

回到顶部