groupcache

package module
v0.0.0-...-3162a35 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 28, 2024 License: MIT Imports: 14 Imported by: 0

README

🪡groupcache

Distributed system of cache based on protobuf, 🪡bttcp, 🪡cache

golang

introduction

A distributed caching system based on groups. It has ultra-high transmission fault tolerance performance and has a higher cache hit rate.

installing

Select the version to install

go get github.com/go-needle/groupcache@version

If you have already get , you may need to update to the latest version

go get -u github.com/groupcache/groupcache

quickly start
// main.go
package main

import (
	"flag"
	"fmt"
	"github.com/go-needle/groupcache"
	"log"
	"net/http"
	"time"
)

var db = map[string]string{
	"Tom":  "630",
	"Jack": "589",
	"Sam":  "567",
}

var db2 = map[string]string{
	"Tom":  "15",
	"Jack": "17",
	"Sam":  "15",
}

func createScoreGroup() *groupcache.Group {
	return groupcache.NewGroup("score", 2<<10, time.Duration(1024)*time.Second, groupcache.GetterFunc(
		func(key string) ([]byte, error) {
			log.Println("[SlowDB] search key", key)
			if v, ok := db[key]; ok {
				return []byte(v), nil
			}
			return nil, fmt.Errorf("%s not exist", key)
		}))
}

func createAgeGroup() *groupcache.Group {
	return groupcache.NewGroup("age", 2<<10, time.Duration(1024)*time.Second, groupcache.GetterFunc(
		func(key string) ([]byte, error) {
			log.Println("[SlowDB] search key", key)
			if v, ok := db2[key]; ok {
				return []byte(v), nil
			}
			return nil, fmt.Errorf("%s not exist", key)
		}))
}

func startCacheServer(addr string, addrs []string, groups []*groupcache.Group) {
	peers := groupcache.NewBttcpPicker(addr)
	peers.Set(addrs...)
	for _, group := range groups {
		group.RegisterPeers(peers)
	}
	peers.ListenAndServe()
}

func startAPIServer(apiAddr string, addrs []string, groups []*groupcache.Group) {
	peers := groupcache.NewBttcpPicker("")
	peers.Set(addrs...)
	for _, group := range groups {
		group.RegisterPeers(peers)
	}
	http.Handle("/api", http.HandlerFunc(
		func(w http.ResponseWriter, r *http.Request) {
			group := r.URL.Query().Get("group")
			key := r.URL.Query().Get("key")
			var g *groupcache.Group
			if group == "score" {
				g = groups[1]
			} else if group == "age" {
				g = groups[0]
			}
			if g == nil {
				fmt.Println("no group")
			}
			get, err := g.Get(key)
			if err != nil {
				return
			}
			if err != nil {
				fmt.Println(err)
				return
			}
			w.Header().Set("Content-Type", "application/octet-stream")
			w.Write(get.ByteSource())

		}))
	log.Println("frontend server is running at", apiAddr)
	log.Fatal(http.ListenAndServe(apiAddr, nil))
}

func startAPIServerByClient(peerAddr, apiAddr string) {
	client := groupcache.NewBttcpClient(peerAddr, 128, false)
	http.Handle("/api", http.HandlerFunc(
		func(w http.ResponseWriter, r *http.Request) {
			group := r.URL.Query().Get("group")
			key := r.URL.Query().Get("key")
			get, err := client.Get(group, key)
			if err != nil {
				fmt.Println(err)
				return
			}
			w.Header().Set("Content-Type", "application/octet-stream")
			w.Write(get)

		}))
	log.Println("frontend server is running at", apiAddr)
	log.Fatal(http.ListenAndServe(apiAddr, nil))

}

func main() {
	var port int
	var api bool
	var client bool
	flag.IntVar(&port, "port", 8001, "groupcache server port")
	flag.BoolVar(&api, "api", false, "Start a api server?")
	flag.BoolVar(&client, "client", false, "Is Use Client?")
	flag.Parse()

	addrMap := map[int]string{
		8001: "127.0.0.1:8001",
		8002: "127.0.0.1:8002",
		8003: "127.0.0.1:8003",
	}

	var addrs []string
	for _, v := range addrMap {
		addrs = append(addrs, v)
	}

	groups := []*groupcache.Group{createAgeGroup(), createScoreGroup()}

	if api {
		if client {
			startAPIServerByClient("127.0.0.1:8001", "0.0.0.0:9998")
		}
		startAPIServer("0.0.0.0:9999", addrs, groups)
	}
	startCacheServer(addrMap[port], addrs, groups)
}

run the shell to start server

#!/bin/bash
trap "rm server;kill 0" EXIT

go build -o server
./server -port=8001 &
./server -port=8002 &
./server -port=8003 &
./server -api=true&
./server -api=true -client=true&

sleep 5
echo ">>> start test"
curl "http://localhost:9999/api?group=score&key=Tom"
echo ""
sleep 1
curl "http://localhost:9999/api?group=score&key=Tom"
echo ""
sleep 1
curl "http://localhost:9999/api?group=score&key=Tom"
echo ""
sleep 1
curl "http://localhost:9999/api?group=score&key=Jack"
echo ""
sleep 1
curl "http://localhost:9999/api?group=age&key=Jack"
echo ""
sleep 1
curl "http://localhost:9999/api?group=age&key=Jack"
echo ""
sleep 1
curl "http://localhost:9998/api?group=age&key=Jack"

wait

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func SetHash

func SetHash(fn consistenthash.Hash)

SetHash is to set the function of defaultHash.

func SetHashReplicas

func SetHashReplicas(replicas int)

SetHashReplicas is to set defaultReplicas.

func SetPoolSize

func SetPoolSize(poolSize int)

SetPoolSize is to set defaultPoolSize.

Types

type BttcpClient

type BttcpClient struct {
	// contains filtered or unexported fields
}

BttcpClient is used to link the peer for groupcache

func NewBttcpClient

func NewBttcpClient(addr string, poolSize int, isTestConn bool) *BttcpClient

func (BttcpClient) Get

func (h BttcpClient) Get(group string, key string) ([]byte, error)

type BttcpPicker

type BttcpPicker struct {
	// contains filtered or unexported fields
}

BttcpPicker implements PeerPicker for a pool of bttcp peers.

func NewBttcpPicker

func NewBttcpPicker(self string) *BttcpPicker

NewBttcpPicker initializes a bttcp picker of peers.

func (*BttcpPicker) ListenAndServe

func (p *BttcpPicker) ListenAndServe()

ListenAndServe run a bttcp server on self address

func (*BttcpPicker) Log

func (p *BttcpPicker) Log(format string, v ...interface{})

Log info with server name

func (*BttcpPicker) PickPeer

func (p *BttcpPicker) PickPeer(key string) (PeerGetter, bool)

PickPeer picks a peer according to key

func (*BttcpPicker) Set

func (p *BttcpPicker) Set(peers ...string)

Set updates the pool's list of peers.

type Getter

type Getter interface {
	Get(key string) ([]byte, error)
}

A Getter loads data for a key.

type GetterFunc

type GetterFunc func(key string) ([]byte, error)

GetterFunc loads data for a key.

func (GetterFunc) Get

func (f GetterFunc) Get(key string) ([]byte, error)

Get implements Getter interface function

type Group

type Group struct {
	// contains filtered or unexported fields
}

A Group is a cache namespace and associated data loaded spread over

func GetGroup

func GetGroup(name string) *Group

GetGroup returns the named group previously created with NewGroup, or nil if there's no such group.

func NewGroup

func NewGroup(name string, cacheBytes int64, keySurvivalTime time.Duration, getter Getter) *Group

NewGroup create a new instance of Group

func (*Group) Get

func (g *Group) Get(key string) (cache.ByteView, error)

Get value for a key from cache

func (*Group) RegisterPeers

func (g *Group) RegisterPeers(peers PeerPicker)

RegisterPeers registers a PeerPicker for choosing remote peer

type PeerGetter

type PeerGetter interface {
	Get(group string, key string) ([]byte, error)
}

PeerGetter is the interface that must be implemented by a peer.

type PeerPicker

type PeerPicker interface {
	PickPeer(key string) (peer PeerGetter, ok bool)
}

PeerPicker is the interface that must be implemented to locate the peer that owns a specific key.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL