"If a worker wants to do his job well, he must first sharpen his tools." - Confucius, "The Analects of Confucius. Lu Linggong"
Front page > Programming > Go High-Performance Cache with TTL and Disk Persistence

Go High-Performance Cache with TTL and Disk Persistence

Published on 2024-08-15
Browse:698

Go High-Performance Cache with TTL and Disk Persistence

1.Introduction

Accelerate your Golang projects without the hassle of setting up a database everytime you begin a new project. Tired of configuring databases from scratch? Only to face new problems? Look no further In this blog we will be looking into Golang caching library with Support for TTL, disk Persistence and Hash Data type.

GoSwift.

2.Prerequisite

  • Basic Knowledge of Golang
  • Knowledge of how a typical cache works

3.Features

  1. Set & Get command
  2. Update command
  3. Del command
  4. Exists command
  5. Support for TTL
  6. Support for Disk Save(Snapshots)
  7. Support Hash Data type (Hset, Hget, HgetAll, HMset)
  8. Safe Locking

Set & Get command

import (
    "fmt"
    "github.com/leoantony72/goswift"
)

func main(){
    cache := goswift.NewCache()

    // Value 0 indicates no expiry
    cache.Set("key", "value", 0)

    val, err := cache.Get("key")
    if err !=nil{
        fmt.Println(err)
        return
    }
    fmt.Println("key", val)
}

Update command

// Update value
// @Update(key string, val interface{}) error
err = cache.Update("key","value2")
if err != nil{
    fmt.Println(err)
    return
}

Del command && Exists command

// Delete command
// @Del(key string)
cache.Del("key")

// Exist command
// @Exists(key string) bool
value = cache.Exists("key")
fmt.Println(value) // returns false

Support for TTL

// Set Value with Expiry
// @Set(key string, val interface{}, exp int)
// Here expiry is set to 1sec
cache.Set("key","value",1000)

// Hset command
// @Hset(key, field string, value interface{}, exp int)
// in this case the "key" expires in 1sec
cache.Hset("key","name","value",1000)
cache.Hset("key","age",18,1000)

Support Hash Data type (Hset, Hget, HgetAll, HMset)

// Hset command
// @Hset(key, field string, value interface{}, exp int)
// in this case the "key" expires in 1sec
cache.Hset("key","name","value",1000)
cache.Hset("key","age",18,1000)


// HMset command
// @HMset(key string, d interface{}, exp int) error
// Set a Hash by passing a Struct/Map
// ---by passing a struct---
type Person struct{
    Name  string
    Age   int
    Place string
}

person1 := &Person{Name:"bob",Age:18,Place:"NYC"}
err = cache.HMset("key",person1)
if err != nil{
    fmt.Println(err)
    return
}

// ---by passing a map---
person2 := map[string]interface{Name:"john",Age:18,Place:"NYC"}
err = cache.HMset("key",person2)
if err != nil{
    fmt.Println(err)
    return
}


// Hget command
// @HGet(key, field string) (interface{}, error)
// get individual fields in Hash
data,err := cache.HGet("key","field")
if err != nil{
    fmt.Println(err)
    return
}
fmt.Println(data)

// HgetAll command
// @HGetAll(key string) (map[string]interface{}, error)
// gets all the fields with value in a hash key
// retuns a map[string]interface{}
data,err = cache.HGetAll("key")
if err != nil{
    fmt.Println(err)
    return
}

Snapshots

opt := goswift.CacheOptions{
        EnableSnapshots:  true,
        SnapshotInterval: time.Second*5,
    }
c := goswift.NewCache(opt)

This will take a snapshot of the Data Every 5sec and saves it into a Snapshot.data file. By default Snapshots are disabled and if the SnapshotInterval is not provided default value is 5seconds.

NOTE: If the EnableSnapshot is false, Data saved in the file will not imported

Error handling

const (
    ErrKeyNotFound   = "key does not Exists"
    ErrFieldNotFound = "field does not Exists"
    ErrNotHashvalue  = "not a Hash value/table"
    ErrHmsetDataType = "invalid data type, Expected Struct/Map"
)

These are the common Errors that may occur while writing the code. These Varible provide you a clear and easy Error comparison method to determine errors.

data,err := cache.Get("key")
if err != nil {
    if err.Error() == goswift.ErrKeyNotFound {
        //do something
}
}    

Inner workings of the cache expiry

Every 3sec the **sweaper **function gets called to clear out the expired values from the hash table. We maintain a min heap which points to the hash map. The top element will be the key with the smallest TTL. we traverse through the tree until TTL is greater then the current time.

Summary

I wouldn't advice you to use this in production!!, but feel free to use it in your small side project. Do try it out and if you encounter a bug do make a issue on GitHub repo.

Email: [email protected]
Github: https://github.com/leoantony72
Repo: https://github.com/leoantony72/goswift

Release Statement This article is reproduced at: https://dev.to/leoantony72/go-high-performance-cache-with-ttl-and-disk-persistence-4a4m?1 If there is any infringement, please contact [email protected] to delete it
Latest tutorial More>

Disclaimer: All resources provided are partly from the Internet. If there is any infringement of your copyright or other rights and interests, please explain the detailed reasons and provide proof of copyright or rights and interests and then send it to the email: [email protected] We will handle it for you as soon as possible.

Copyright© 2022 湘ICP备2022001581号-3