使用sync.map做内存缓存

背景

实际业务场景中有些需求对于数据实时性要求不高,但是对于吞吐量和响应有着极高的要求,这个时候我们可以建立多级缓存来解决此类问题,本篇文章我们讨论的是内存缓存(golang)来实现

实现方案

想到内存缓存,想必大家第一个想到的是golang中的map+mutex、sync.map的方式来实现.
对于读多写少的场景,一般建议大家用sync.map来实现(具体场景的性能测试如下)
在这里插入图片描述

引用自: https://blog.csdn.net/wyg_031113/article/details/106282340

code

package bm

import (
	"hash/crc32"
	"sync"
	"time"
)

const (
	BucketSize = 256
)

type BigSyncMap struct {
    // 分段来存储 数据提供并发访问效率
	cacheBuckets [BucketSize]*sync.Map
	// 存储每个key的过期时间
	expires      *sync.Map
}

var (
	bigMap *BigSyncMap
	once   sync.Once
)
// GetBigSyncMapInstance 获取实例
func GetBigSyncMapInstance() *BigSyncMap {
	once.Do(func() {
		bigMap = &BigSyncMap{
			expires: &sync.Map{},
		}
		for i := 0; i < BucketSize; i++ {
			bigMap.cacheBuckets[i] = &sync.Map{}
		}
		// 开启携程 定时清除过期的data
		go bigMap.flushExpireData()
	})
	return bigMap
}

func (m *BigSyncMap) flushExpireData() {
	for {
		m.expires.Range(func(key, expireTime interface{}) bool {
			if time.Since(expireTime.(time.Time)) > time.Minute*30 {
				m.delete(key.(string))
			}
			return true
		})
		time.Sleep(time.Minute * 2)
	}
}
func (m *BigSyncMap) delete(key string) {
	m.cacheBuckets[checksum(key)].Delete(key)
}
// checksum 根据crc32算法取key的index
func checksum(key string) int {
	return int(crc32.ChecksumIEEE([]byte(key)) % BucketSize)
}
// Load 加载数据
func (m *BigSyncMap) Load(key interface{}) (interface{}, bool) {
	return m.cacheBuckets[checksum(key.(string))].Load(key)
}
//  Store 存储数据,并更新对应key的expire time
func (m *BigSyncMap) Store(key, val interface{}) {
	m.cacheBuckets[checksum(key.(string))].Store(key,val)
	m.expires.Store(key,time.Now())
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值