Redis caching layer for Cloudflare KV in Golang

Redis caching layer for Cloudflare KV in Golang

Go Reference

Ask questions in the GitHub issues

Why redis-cloudflare-kv?

  • Cloudflare KV is a highly distributed, eventually consistent, key-value store that spans Cloudflare's global edge. It allows you to store billions of key-value pairs and read them with some average latency (2 to 3 seconds) anywhere in the world.
  • Cloudflare KV Read operation is very slow when compared to Redis which offers memory efficiency, fast operating speed, and high availability. So it's better to use Redis as a caching layer for Cloudflare KV to provide fast, economic scaling for your application.
  • redis-cloudflare-kv checks if there is a cached result for a query in Redis.
  • If not found in the cache, it will retrieve data from Cloudflare KV and on the successful result, cache it in Redis for future queries.

Application Architecture

Installation

You need a working Go environment.

go get github.com/dineshsonachalam/redis-cloudflare-kv

Quickstart

TCP Connection: redis://:@:/ // UNIX Connection: unix://:@?db= os.Getenv("REDIS_URL"), os.Getenv("CLOUDFLARE_ACCESS_KEY"), os.Getenv("CLOUDFLARE_EMAIL_ADDRESS"), os.Getenv("CLOUDFLARE_ACCOUNT_ID"), ) namespaceID := os.Getenv("TEST_NAMESPACE_ID") key1 := "opensource.facebook.react" value1 := "A declarative, efficient, and flexible JavaScript library for building user interfaces." key2 := "opensource.facebook.react-native" value2 := "A framework for building native apps with React." key3 := "opensource.facebook.flow" value3 := "Adds static typing to JavaScript to improve developer productivity and code quality." key4 := "opensource.facebook.docusaurus" value4 := "Easy to maintain open source documentation websites." // Write writes a value identified by a key in Redis and Cloudflare KV status, err := kvClient.Write(key1, []byte(value1), namespaceID) if !status && err != nil { log.Fatal(err) } fmt.Printf("Write operation is successful for key: %v\n", key1) // Read returns the value associated with the given key // If the key is not available in the Redis server, // it searches for the key in Cloudflare KV and if the key is available, it writes the key/value in the Redis. // Then it returns the value associated with the given key. value, err := kvClient.Read(key1, namespaceID) if err != nil { log.Fatal(err) } fmt.Printf("Read operation is successful. Key: %v, Value: %v\n", key1, string(value)) // Delete deletes a key/value in Redis and Cloudflare KV status, err = kvClient.Delete(key1, namespaceID) if !status && err != nil { log.Fatal(err) } fmt.Printf("Delete operation is successful for key: %v\n", key1) kvClient.Write(key2, []byte(value2), namespaceID) kvClient.Write(key3, []byte(value3), namespaceID) kvClient.Write(key4, []byte(value4), namespaceID) // ListKeysByPrefix returns keys that matches the prefix // If there are no key's that matches the prefix in the Redis // We search for the prefix pattern in Cloudflare KV, if there are keys // that matches the prefix, we return the keys. keys, err := kvClient.ListKeysByPrefix("opensource.facebook", namespaceID) if err != nil { log.Fatal(err) } fmt.Printf("ListKeysByPrefix operation is successful. Keys: %v\n", keys) } // Output: // dineshsonachalam@macbook examples % go run main.go // Write operation is successful for key: opensource.facebook.react // Read operation is successful. Key: opensource.facebook.react, Value: A declarative, efficient, and flexible JavaScript library for building user interfaces. // Delete operation is successful for key: opensource.facebook.react // ListKeysByPrefix operation is successful. Keys: [opensource.facebook.docusaurus opensource.facebook.react-native opensource.facebook.flow] ">
package main

import (
	"fmt"
	"log"
	"os"

	rediscloudflarekv "github.com/dineshsonachalam/redis-cloudflare-kv"
)

func main() {
	// Construct a new KV Client object
	kvClient := rediscloudflarekv.New(
		// REDIS_URL -> TCP Connection:  redis://:@:/
		//              UNIX Connection: unix://:@?db=
		os.Getenv("REDIS_URL"),
		os.Getenv("CLOUDFLARE_ACCESS_KEY"),
		os.Getenv("CLOUDFLARE_EMAIL_ADDRESS"),
		os.Getenv("CLOUDFLARE_ACCOUNT_ID"),
	)
	namespaceID := os.Getenv("TEST_NAMESPACE_ID")
	key1 := "opensource.facebook.react"
	value1 := "A declarative, efficient, and flexible JavaScript library for building user interfaces."
	key2 := "opensource.facebook.react-native"
	value2 := "A framework for building native apps with React."
	key3 := "opensource.facebook.flow"
	value3 := "Adds static typing to JavaScript to improve developer productivity and code quality."
	key4 := "opensource.facebook.docusaurus"
	value4 := "Easy to maintain open source documentation websites."

	// Write writes a value identified by a key in Redis and Cloudflare KV
	status, err := kvClient.Write(key1, []byte(value1), namespaceID)
	if !status && err != nil {
		log.Fatal(err)
	}
	fmt.Printf("Write operation is successful for key: %v\n", key1)

	// Read returns the value associated with the given key
	// If the key is not available in the Redis server,
	// it searches for the key in Cloudflare KV and if the key is available, it writes the key/value in the Redis.
	// Then it returns the value associated with the given key.
	value, err := kvClient.Read(key1, namespaceID)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("Read operation is successful. Key: %v, Value: %v\n", key1, string(value))

	// Delete deletes a key/value in Redis and Cloudflare KV
	status, err = kvClient.Delete(key1, namespaceID)
	if !status && err != nil {
		log.Fatal(err)
	}
	fmt.Printf("Delete operation is successful for key: %v\n", key1)

	kvClient.Write(key2, []byte(value2), namespaceID)
	kvClient.Write(key3, []byte(value3), namespaceID)
	kvClient.Write(key4, []byte(value4), namespaceID)

	// ListKeysByPrefix returns keys that matches the prefix
	// If there are no key's that matches the prefix in the Redis
	// We search for the prefix pattern in Cloudflare KV, if there are keys
	// that matches the prefix, we return the keys.
	keys, err := kvClient.ListKeysByPrefix("opensource.facebook", namespaceID)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("ListKeysByPrefix operation is successful. Keys: %v\n", keys)
}

// Output:
// dineshsonachalam@macbook examples % go run main.go
// Write operation is successful for key: opensource.facebook.react
// Read operation is successful. Key: opensource.facebook.react, Value: A declarative, efficient, and flexible JavaScript library for building user interfaces.
// Delete operation is successful for key: opensource.facebook.react
// ListKeysByPrefix operation is successful. Keys: [opensource.facebook.docusaurus opensource.facebook.react-native opensource.facebook.flow]

License

MIT © dineshsonachalam

Owner
Dinesh Sonachalam
Software Developer at Gogoair
Dinesh Sonachalam
Similar Resources

Cache library for golang. It supports expirable Cache, LFU, LRU and ARC.

Cache library for golang. It supports expirable Cache, LFU, LRU and ARC.

GCache Cache library for golang. It supports expirable Cache, LFU, LRU and ARC. Features Supports expirable Cache, LFU, LRU and ARC. Goroutine safe. S

Dec 30, 2022

An in-memory cache library for golang. It supports multiple eviction policies: LRU, LFU, ARC

GCache Cache library for golang. It supports expirable Cache, LFU, LRU and ARC. Features Supports expirable Cache, LFU, LRU and ARC. Goroutine safe. S

May 31, 2021

Go Memcached client library #golang

About This is a memcache client library for the Go programming language (http://golang.org/). Installing Using go get $ go get github.com/bradfitz/gom

Dec 28, 2022

gdcache is a pure non-intrusive distributed cache library implemented by golang

gdcache is a pure non-intrusive distributed cache library implemented by golang

gdcache is a pure non-intrusive distributed cache library implemented by golang, you can use it to implement your own distributed cache

Sep 26, 2022

Cache list, count with filter param golang, using struct, hashkey

Dumbcache Cache list, count with filter param golang, using struct, hashkey Structure we hash your request object to md5 hashing and add a prefix coun

Nov 1, 2021

Fast key-value cache written on pure golang

GoCache Simple in-memory key-value cache with default or specific expiration time. Install go get github.com/DylanMrr/GoCache Features Key-value stor

Nov 16, 2021

Light weight thread safe cache for golang

go-cache Light weight thread safe LRU cache Getting started import( "fmt" "github.com/tak1827/go-cache/lru" ) func main() { size := 2 cache := l

Dec 12, 2021

lru: the most concise and efficient LRU algorithm based on golang

lru This package of lru is the most concise and efficient LRU algorithm based on golang. Example Quick start: package main import ( "fmt" "github.

Dec 27, 2021

Continuous Benchmark for cache libraries written in golang.

Simple performance comparison of cache libraries written in golang. Reports Continuous Bencmark Result (click here) Default parameters 256 shards * 32

Oct 26, 2022
Comments
  • This project seems misleading

    This project seems misleading

    Hi..

    while I like the ambition here, I think this is a non-sensical comparison. The reason is you are accessing KV in a very inefficient way, by using the HTTP API, which talks to a global REST endpoint in america. It is actually discouraged to access KV this way, instead you should access it via a worker script, which means KV is read from and written to in the closest Cloudflare PoP. This is mentioned in the community discord (somewhere) by CF staff and also on discourse forums, e.g. here: https://community.cloudflare.com/t/workers-kv-very-slow-accessing-data-thought-api/266932/2

MySQL to Redis caching made easy

redisql MySQL to Redis caching made easy

Sep 4, 2022
POC de caching en Go en utilisant go-redis/cache

Test-web POC de caching en Go en utilisant go-redis/cache, cette lib permet d'avoir un cache local et un cache redis (appel cache local puis cache red

Nov 19, 2021
LFU Redis implements LFU Cache algorithm using Redis as data storage

LFU Redis cache library for Golang LFU Redis implements LFU Cache algorithm using Redis as data storage LFU Redis Package gives you control over Cache

Nov 10, 2022
Concurrency-safe Go caching library with expiration capabilities and access counters

cache2go Concurrency-safe golang caching library with expiration capabilities. Installation Make sure you have a working Go environment (Go 1.2 or hig

Jan 1, 2023
groupcache is a caching and cache-filling library, intended as a replacement for memcached in many cases.

groupcache Summary groupcache is a distributed caching and cache-filling library, intended as a replacement for a pool of memcached nodes in many case

Dec 31, 2022
Multi-level caching service in Go
Multi-level caching service in Go

IgoVIUM Multi-level caching service in Go. Specifically: Distributed in-memory cache (L1) DB-based cache (L2) Long term historization on persistent vo

Nov 9, 2022
API Cache is a simple caching server, using grpc to accept messages.

API Cache is a simple caching server, using grpc to accept messages. It allows to store key-value pairs, where key is string and value is []byte.

Nov 16, 2021
Design and Implement an in-memory caching library for general use

Cache Implementation in GoLang Problem Statement Design and Implement an in-memory caching library for general use. Must Have Support for multiple Sta

Dec 28, 2021
🧩 Redify is the optimized key-value proxy for quick access and cache of any other database throught Redis and/or HTTP protocol.

Redify (Any database as redis) License Apache 2.0 Redify is the optimized key-value proxy for quick access and cache of any other database throught Re

Sep 25, 2022
Minicache - Distributed cache implemented in Go. Like Redis but simpler.
Minicache - Distributed cache implemented in Go. Like Redis but simpler.

Distributed cache with client-side consistent hashing, distributed leader-elections, and dynamic node discovery. Supports both HTTP/gRPC interfaces secured with mTLS.

Jan 4, 2023