• Stars
    star
    541
  • Rank 82,114 (Top 2 %)
  • Language
    Go
  • License
    BSD 3-Clause "New...
  • Created over 2 years ago
  • Updated 6 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

The First Redis Cache Library To Ensure Eventual Consistency And Strong Consistency With DB.

license Build Status codecov Go Report Card Go Reference

English | 简体中文

RocksCache

The first Redis cache library to ensure eventual consistency and strong consistency with DB.

Features

  • Eventual Consistency: ensures eventual consistency of cache even in extreme cases
  • Strong consistency: provides strong consistent access to applications
  • Anti-breakdown: a better solution for cache breakdown
  • Anti-penetration
  • Anti-avalanche
  • Batch Query

Usage

This cache repository uses the most common update DB and then delete cache cache management policy

Read cache

import "github.com/dtm-labs/rockscache"

// new a client for rockscache using the default options
rc := rockscache.NewClient(redisClient, NewDefaultOptions())

// use Fetch to fetch data
// 1. the first parameter is the key of the data
// 2. the second parameter is the data expiration time
// 3. the third parameter is the data fetch function which is called when the cache does not exist
v, err := rc.Fetch("key1", 300 * time.Second, func()(string, error) {
  // fetch data from database or other sources
  return "value1", nil
})

Delete the cache

rc.TagAsDeleted(key)

Batch usage

Batch read cache

import "github.com/dtm-labs/rockscache"

// new a client for rockscache using the default options
rc := rockscache.NewClient(redisClient, NewDefaultOptions())

// use FetchBatch to fetch data
// 1. the first parameter is the keys list of the data
// 2. the second parameter is the data expiration time
// 3. the third parameter is the batch data fetch function which is called when the cache does not exist
// the parameter of the batch data fetch function is the index list of those keys
// missing in cache, which can be used to form a batch query for missing data.
// the return value of the batch data fetch function is a map, with key of the
// index and value of the corresponding data in form of string
v, err := rc.FetchBatch([]string{"key1", "key2", "key3"}, 300, func(idxs []int) (map[int]string, error) {
    // fetch data from database or other sources
    values := make(map[int]string)
    for _, i := range idxs {
        values[i] = fmt.Sprintf("value%d", i)
    }
    return values, nil
})

Batch delete cache

rc.TagAsDeletedBatch(keys)

Eventual consistency

With the introduction of caching, consistency problems in a distributed system show up, as the data is stored in two places at the same time: the database and Redis. For background on this consistency problem, and an introduction to popular Redis caching solutions, see.

But all the caching solutions we've seen so far, without introducing versioning at the application level, fail to address the following data inconsistency scenario.

cache-version-problem

Even if you use lock to do the updating, there are still corner cases that can cause inconsistency.

redis cache inconsistency

Solution

This project brings you a brand new solution that guarantee data consistency between the cache and the database, without introducing version. This solution is the first of its kind and has been patented and is now open sourced for everyone to use.

When the developer calls Fetch when reading the data, and makes sure to call TagAsDeleted after updating the database, then the cache can guarentee the eventual consistency. When step 5 in the diagram above is writing to v1, the write in this solution will eventually be ignored.

For a full runnable example, see dtm-cases/cache

Strongly consistent access

If your application needs to use caching and requires strong consistency rather than eventual consistency, then this can be supported by turning on the option StrongConsisteny, with the access method remaining the same

rc.Options.StrongConsisteny = true

Refer to cache consistency for detailed principles and dtm-cases/cache for examples

Downgrading and strong consistency

The library supports downgrading. The downgrade switch is divided into

  • DisableCacheRead: turns off cache reads, default false; if on, then Fetch does not read from the cache, but calls fn directly to fetch the data
  • DisableCacheDelete: disables cache delete, default false; if on, then TagAsDeleted does nothing and returns directly

When Redis has a problem and needs to be downgraded, you can control this with these two switches. If you need to maintain strong consistent access even during a downgrade, rockscache also supports

Refer to cache-consistency for detailed principles and dtm-cases/cache for examples

Anti-Breakdown

The use of cache through this library comes with an anti-breakdown feature. On the one hand Fetch will use singleflight within the process to avoid multiple requests being sent to Redis within a process, and on the other hand distributed locks will be used in the Redis layer to avoid multiple requests being sent to the DB from multiple processes at the same time, ensuring that only one data query request ends up at the DB.

The project's anti-breakdown provides a faster response time when hot cached data is deleted. If a hot cache data takes 3s to compute, a normal anti-breakdown solution would cause all requests for this hot data to wait 3s for this time, whereas this project's solution returns it immediately.

Anti-Penetration

The use of caching through this library comes with anti-penetration features. When fn in Fetch returns an empty string, this is considered an empty result and the expiry time is set to EmptyExpire in the rockscache option.

EmptyExpire defaults to 60s, if set to 0 then anti-penetration is turned off and no empty results are saved

Anti-Avalanche

The cache is used with this library and comes with an anti-avalanche. RandomExpireAdjustment in rockscache defaults to 0.1, if set to an expiry time of 600 then the expiry time will be set to a random number in the middle of 540s - 600s to avoid data expiring at the same time

Contact us

Chat Group

Join the chat via https://discord.gg/dV9jS5Rb33.

Give a star!

If you think this project is interesting, or helpful to you, please give a star!

More Repositories

1

dtm

A distributed transaction framework, supports workflow, saga, tcc, xa, 2-phase message, outbox patterns, supports many languages.
Go
10,116
star
2

client-csharp

The new client for dtm in csharp, including workflow, dtmcli, and dtmgrpc
C#
123
star
3

dtm-examples

various examples for dtm
Go
79
star
4

dtmcli-php

a php client for distributed transaction framework dtm.
PHP
32
star
5

dtm-cases

some classic applications of dtm
Go
26
star
6

dtmcli-java

Official java client for distributed transaction framework dtm
Java
26
star
7

dtmcli-node

a node client for distributed transaction framework dtm.
TypeScript
25
star
8

dtmcli-csharp-sample

dtmcli c# sample
C#
23
star
9

dtmgrpc-csharp

A c# gRPC client of distributed transaction manager DTM.
C#
21
star
10

dtm.pub

dtm-简体中文文档
Shell
19
star
11

quick-start-sample

quick start sample for client
Go
19
star
12

dtmcli-py

a python client for distributed transaction framework dtm.
Python
17
star
13

client

the new client for dtm in go, including workflow, dtmcli, and dtmgrpc
Go
15
star
14

dtmcli-java-sample

Java
13
star
15

dtmcli

a go http client for distributed transaction framework DTM.
Go
13
star
16

dtmcli-php-sample

PHP
12
star
17

dtmcli-csharp

A c# HTTP client of distributed transaction manager DTM. Deprecated, please refer to https://github.com/dtm-labs/client-csharp
C#
12
star
18

dtmdriver-clients

dtm sample project for microservice
Go
10
star
19

dtmcli-node-sample

node sample of dtmcli
JavaScript
7
star
20

dtmcli-py-sample

python sample for dtm
Python
7
star
21

dtmdriver-kratos

kratos driver for dtm
Go
6
star
22

dtmcli-go-sample

Go
4
star
23

dtmdriver-gozero

go-zero driver for supporting dtm
Go
4
star
24

logger

the lightweight logger wrapper for zap used by dtm-labs
Go
3
star
25

dtmdriver

dtm's driver interface for micro-services
Go
2
star
26

dtmgrpc-go-sample

a go sample for dtmgrpc
Go
2
star
27

dtmgrpc

grpc client for dtm. code is synced from github.com/yedf/dtm/dtmgrpc
Go
2
star
28

dtmdriver-dapr

dtm driver for dapr https://github.com/dapr/dapr
Go
2
star
29

dtmdriver-ego

Go
2
star
30

operator

[WIP]cloud native dtm operator
Go
1
star
31

dtmcli-java-spring-sample

dtmcli-java-spring-sample
Java
1
star
32

driver-gozero

dtm driver for gozero, used by the client of gozero to access dtmgrpc
Go
1
star
33

en.dtm.pub

english document for dtm
Shell
1
star
34

rockscache-java

A Redis Cache Library To Ensure Eventual Consistency And Strong Consistency With DB.
Kotlin
1
star