前言

前段時間,校招投了golang崗位,可是沒什麼好的項目往簡歷上寫,因而參考了許多網上資料,作了一個簡單的分佈式緩存項目。
如今閒下來了,打算整理下。html

github項目地址:https://github.com/Jun10ng/Gache
裏面還有我整理的一些面試問題,給顆星吧。java

typora-root-url: ./git

Golang校招面試項目-類redis分佈式緩存

實現一個分佈式緩存,功能有:LRU淘汰策略,http調用,併發緩存,一致性哈希,分佈式節點,防止緩存擊穿github

實現LRU淘汰策略

map
maxSize

代碼實現

定義了三個數據結構redis

Value
entry
Cache
type Value interface {

	//返回佔用的內存大小
	Len() int
}

type entry struct {
	key string
	value Value
}

type Cache struct {
	//容許使用的最大內存
	maxBytes int64

	//當前已使用的內存
	nbytes int64


	ll *list.List

	cache map[string] *list.Element

	//某條記錄被移除時的回調函數,能夠是nil
	OnEvicted func(key string, value Value)

}
OnEvictedOnEvicted

實現單機併發

sync.Mutex
type cache struct {
	mu sync.Mutex
	lru *lru.Cache
	cacheBytes int64
}

cache並無new方法,由於採用的是延遲初始化 在add方法中,判斷c.lru是否爲nil,若是等於nil再建立 這種方法稱爲延遲初始化,一個對象的延遲初始化意味着該對象的 建立將會延遲至第一次使用該對象時。 這個方法在redis中很常見,由於能必定程度上提升性能

func (c *cache) add(key string, value ByteView){
	c.mu.Lock()
	defer c.mu.Unlock()
	if c.lru == nil{
		c.lru = lru.New(c.cacheBytes,nil)
	}
	c.lru.Add(key,value)
}

主體結構

本質上是再進行一次封裝

難道一臺機器就只有一個緩存表嗎?你打開redis的可視化工具,能看到redis還有16個池呢,因此咱們要實現多個緩存表。怎麼作?再加一層。試想一下:

//groups 實例集合表
groups = make(map[string]*Group)

併發cache
//這裏的group是實例
type Group struct {
	name string
	getter Getter
	mainCache cache
}

http服務調用

/_Gache/
http://XXX.com/_Gache//
groupnamegroupsnamekeykey
groups[groupname][key]

TODo

一致性哈希
分佈式節點