沧州三亚菏泽经济预测自然
投稿投诉
自然科学
知识物理
化学生物
地理解释
预测理解
本质社会
人类现象
行为研究
经济政治
心理结构
关系指导
人文遗产
菏泽德阳
山西湖州
宝鸡上海
茂名内江
三亚信阳
长春北海
西安安徽
黄石烟台
沧州湛江
肇庆鹤壁
六安韶关
成都钦州

快速构建Go语言KVCache

12月4日 相思宫投稿
  缓存是几乎所有程序或产品的必需品,我们在每个角落都能看到它,比如网页、数据库、应用程序等。
  它的意义在于它所带来的效率。这就像在你忙于燃烧卡路里的问题时,把你最喜欢的零食放在桌子上,让你快速拿一下。
  熟悉和可快速构建一个本地kv缓存对日常开发很重要,所以我将从头开始实现一个健全且可用的本地kv缓存。KVCache的基本元素
  首先是实现键值缓存时应考虑的因素:贮存
  一般最常用的数据结构是map〔string〕Element{},其中string为key,其中element包含value信息。元素
  最简单的元素至少应该包含值和过期时间。并且值类型通常是interface{},可以根据场景换成string、int或者其他特定类型。并发
  缓存必须考虑并发访问,除非它是特定于线程的映射。和其他高级语言一样,Go也提供了一个线程安全的映射(sync。map)。
  当然,将map与sync。RWMutex组合起来可以实现相同的功能,提供更大的灵活性并帮助更好地理解Go。容量
  如果要在KubernetesPod中运行,则需要提前设置缓存大小。
  否则,它可能会消耗过多的内存,并导致整个pod因内存限制而被淘汰。删除过期的
  及时释放过期的key可以提高缓存利用率,节省开销,提升性能。GC调优
  它与Go相关,减少了GC对缓存的影响。而sync。Pool可以用来进一步优化。API设计
  Cache有Put、Get、Remove和Flush4个基本功能,并且开放给更多的方法以获得更好的支持。缓存实现
  考虑到这些元素,我们现在要设计缓存。
  首先是两个简单的步骤。1)定义所有类型和功能。typeCachestruct{defaultExpirationtime。Durationelementsmap〔string〕Elemcapacityint64sizeint64locksync。RWMutexpoolsync。Poolcleanercleaner}typeElemstruct{KstringNeededforthesync。PoolVinterface{}Expirationint64LastHitint64}typecleanerstruct{Intervaltime。Durationstopchanbool}func(cCache)Get(kstring)(vinterface{},errerror){returnnil,nil}func(cCache)Put(kstring,vinterface{})error{returnnil,nil}func(cCache)Remove(kstring)(isFoundbool,errerror){returnfalse,nil}func(cCache)Flush()error{returnnil}Usedincleaningjobfunc(cCache)RemoveExpired(){}Runcleaningjobfunc(clcleaner)Run(cCache){}定义默认参数
  在New函数中使用它们。const(DEFAULTEXPIRATION10time。MinuteDEFAULTCLEANDURATION10time。MinuteDEFAULTCAP1024)funcNewCache()(Cache,error){returnnewCache(DEFAULTCAP,DEFAULTEXPIRATION,DEFAULTCLEANDURATION)}funcnewCache(capint64,expirationtime。Duration,cleandurationtime。Duration)(Cache,error){returnCache{defaultExpiration:expiration,elements:make(map〔string〕Elem,cap),capacity:cap,lock:new(sync。RWMutex),cleaner:cleaner{Interval:cleanduration,stop:make(chanbool),},pool:sync。Pool{New:func()interface{}{returnEntry{}},},},nil}
  然后是put方法。在为map设置key和val之前,需要做一些额外的工作。获取并设置密钥的过期时间。获取和设置密钥的最后访问时间。
  在缓存已满,但无法删除过期key为新key腾出空间的场景下,我们需要引入一些额外的淘汰策略。
  LRU,最近最少用户,就是我们在这种情况下应用的:最近没有被访问过的键将被淘汰。但是,需要注意的是,它对历史数据并不友好。
  还有一些其他的淘汰政策,例如,
  LFU,最不常用的,淘汰了低频率访问的键。潜在的问题是,如果密钥在短时间内被频繁访问,它们将在缓存中保留很长时间,尽管以后不会访问。
  FIFO,先进先出,最新的保留。其缺点与LFU相同。
  ARC,自适应替换缓存。作为LRU的高级版本,它通过与LFU和LRU集成,4个队列,消耗更多内存来实现更高性能的缓存。
  此外,还有其他算法,如双队列、MRU等。
  最后,我们来看看sync。Pool。只有在立即使用存储的对象时才需要选择加入功能。否则,池中的对象将在Get中起作用之前被频繁替换。但这是我们未来需要改进缓存的功能。
  一步一步,Put方法就搞定了。func(cCache)Put(kstring,vinterface{})error{expire:time。Now()。Add(DEFAULTEXPIRATION)。UnixNano()lastHit:time。Now()。UnixNano()ifc。size1c。capacity{LRUkicksiniferr:c。removeLeastVisited();err!nil{returnerr}}c。lock。Lock()deferc。lock。Unlock()ifele,ok:c。elements〔k〕;ok{ele。Vvele。Expirationexpireele。LastHitlastHitreturnnil}ele:Elem{V:v,Expiration:expire,LastHit:lastHit,}c。pool。Put(ele)c。elements〔k〕elec。sizec。size1returnnil}
  然后你会发现Getthefunction已经在你的口袋里了:只需从pool和map中获取结果,并更新最后访问时间和过期时间。func(cCache)Get(kstring)(vinterface{},errerror){ele:c。pool。Get()ifitem,ok:ele。(Elem);ok{ifitem。Kk{returnitem。V,nil}}expire:time。Now()。Add(DEFAULTEXPIRATION)。UnixNano()lastHit:time。Now()。UnixNano()c。lock。RLock()deferc。lock。RUnlock()ifele,ok:c。elements〔k〕;ok{ele。Expirationexpireele。LastHitlastHitreturnele。V,nil}returnnil,nil}
  接下来要做的就是构建一个自动清理器,通过启动一个goroutine定期清理过期时间小于当前时间的键。Usedincleaningjobfunc(cCache)RemoveExpired(){now:time。Now()。UnixNano()c。lock。Lock()deferc。lock。Unlock()fork,v:rangec。elements{ifv。Expiration0nowv。Expiration{,c。Remove(k)}}}Runcleaningjobfunc(clcleaner)Run(cCache){ticker:time。NewTicker(cl。Interval)for{select{caseticker。C:c。RemoveExpired()casecl。stop:ticker。Stop()return}}}funcstopJanitor(cCache){c。cleaner。stoptrue}
  同时,将以下两行添加到前面的New方法中。goc。cleaner。Run(c)runtime。SetFinalizer(c,stopCleaner)
  至此,缓存功能基本完成,下面我们测试下性能。性能比较
  迫不及待的想把我们自己搭建的缓存和Github上那些完美的缓存做个性能对比,我以gocache和hashicorplrucache为例,写了一个benchmark测试,对比一下访问效率。packagegolanglocalcacheimport(fmttestingtimehashicorpgithub。comhashicorpgolanglrugocachegithub。compatrickmngocache)funcBenchmarkGoCache(btesting。B){c:gocache。New(1time。Minute,5time。Minute)b。Run(Put,func(btesting。B){fori:0;ib。N;i{c。Add(toKey(i),toKey(i),gocache。DefaultExpiration)}})b。Run(Get,func(btesting。B){fori:0;ib。N;i{value,found:c。Get(toKey(i))iffound{value}}})}funcBenchmarkCache(btesting。B){c,:NewCache()b。Run(Put,func(btesting。B){fori:0;ib。N;i{c。Put(toKey(i),toKey(i))}})b。Run(Get,func(btesting。B){fori:0;ib。N;i{value,:c。Get(toKey(i))ifvalue!nil{value}}})}funcBenchmarkHashicorpLRU(btesting。B){c:cache2go。Cache(test)c,:hashicorp。New(1024)b。Run(Put,func(btesting。B){fori:0;ib。N;i{c。Add(toKey(i),toKey(i))}})b。Run(Get,func(btesting。B){fori:0;ib。N;i{value,err:c。Get(toKey(i))iferrtrue{value}}})}functoKey(iint)string{returnfmt。Sprintf(item:d,i)}
  结果符合我的预期。我们的缓存比那些成熟的开源缓存慢。但是,当它只花费我们20分钟时,我们还能期待什么。
  结果给了我一个提示,hashicorpcache这么快一定是有原因的,以后我们可以在单独讲一下!改进方法
  我们的缓存速度较慢,但我们可以做一些事情来加快速度。那怎么办?
  最重要的因素是并发和缓存大小,两者相互影响:并发越大,元素越多,内存占用越大,缓存越慢。因此,减少并发是第一要务。
  这里我们需要一种着色方法,将一个缓存映射拆分为多个,以降低并发可能性并缩小每个缓存的大小。毫无疑问,散列最常用于阴影,因为哈希结果具有高离散率,即高随机性。
  Hash避免产生过多的内存分配,缓解垃圾回收带来的压力。哈希算法非常高效。
  可以很容易地得出结论,哈希方法的速度决定了着色算法的效率,因为密钥是通过hash(key)分配给不同的缓存的。
  那么问题就在于选择哪种算法。MD5和SHA256是最常见的哈希算法,FNV和DJB2各有优势。如果您在这些选项上苦苦挣扎,请进行基准比较。
  此外,添加更多方法,如直接访问字符串和直接存储int,或优化sync。Pool使用也是改进缓存的方法。结束
  互联网世界有很多的开源缓存,这使得我们免于自己编写,而且效率更高。但是,当你更了解其中实现原理的时候,开发起来会更加的高效。
投诉 评论 转载

CBA超级外援抵达上海,邱彪终于等到了,新疆男篮能否一飞冲天CBA超级外援正式上线,邱彪终于等到了,新疆男篮能否一飞冲天?CBA窗口期即将告一段落,根据安排各支球队在一周之后就将正式启程前往诸暨赛区,所以留给他们调整的时间不多了。据悉新……女人再懒也别穿拖鞋,很邋遢!瞧瞧这位妈妈这样穿,减龄还气质天气越来越暖和,换上春装的同时鞋子也要换成更加轻薄透气的款式,其中,样式简单、鞋型宽松、穿脱方便的拖鞋十分受欢迎,尤其是带点设计感的拖鞋,时尚感爆棚,穿起来很洋气。但对于……盘点那些难忘的歌词(1)1、我们在同一个屋檐下,写着属于我们共同的诗篇2、悠闲的人从没心事,我没有擦去争吵的橡皮,只有一支画着孤独的笔3、我拒绝更好更圆的月亮,拒绝未知的疯狂,拒绝声色的张……倚天屠龙记过去19年,善解人意的小昭,如今44岁活得好精彩金庸先生的小说一直以来都备受大家的喜欢和追捧,而他的一系列武侠小说,也一一被影视化,拍成了电视剧和电影作品。虽说现如今金庸先生已经离开了我们,但是他曾一手打造的武侠世界,将永远……小白与小灰春末,小区入住了一只鸽子,时常绕我家北边那楼飞上飞下,停靠行走。北楼离我书房相距不远,鸽子的动势、静势我都能看清。因疫情,家中书房成了我的办公室,每当烦恼劳累,我会走到窗……俄乌冲突持续,中俄等37国公开去美元化后,第38国或将叫停美3月12日,有消息称,美国可能将禁止从俄罗斯进口伏特加、鱼子酱和钻石,并呼吁美国与欧盟和G7一起,取消俄罗斯贸易的最惠国待遇地位,同时,美国还表示将禁止向俄罗斯出口包括服装、珠……除夕年夜饭,不管贫富,这5道年夜菜记得端上桌,寓意吉祥年味足导语:除夕年夜饭,不管贫富,这2道年夜菜记得端上桌,寓意吉祥年味足。大家好我是傻姐美食,生活中唯有美食和美景不可辜负,马上就到春节了,我们中国人一年一度最重大的节日,举国……快速构建Go语言KVCache缓存是几乎所有程序或产品的必需品,我们在每个角落都能看到它,比如网页、数据库、应用程序等。它的意义在于它所带来的效率。这就像在你忙于燃烧卡路里的问题时,把你最喜欢的零食放……纸老虎!女排夺冠大热被弱旅狠狠教训,埃格努狂送16分成卧底世界女排联赛正在激烈地进行之中,本次世界女排联赛,多支球队都希望自己能够在赛场上有好的表现。虽然中国女排的整体实力并不是最强大的,但是中国女排的姑娘们一直在全力冲击好成绩。从这……碳酸锂逼近30万元!锂王蒸发300亿!在经历两年疯涨后,碳酸锂价格终于迎来了一轮快速下跌。数据显示,电池级碳酸锂跌7000元吨,均价报35。5万元吨,工业级碳酸锂跌7500元吨,均价报31。9万元吨。或……64岁杨丽萍再跳孔雀舞,化浓妆遮掩不住老态,满脸褶子像老太太近日,杨丽萍主演的舞剧版《孔雀》正式开启全国巡演,第一站便是知名的苏州湾大剧院,和以往一样,杨丽萍带领团队精心打磨了这一部作品,早已迈入花甲之年的杨丽萍在舞台上依旧是舞姿翩迁,……蒸锅选什么材质的比较好?选购蒸锅时需要注意些什么?头条创作挑战赛中国人现在比较讲究少盐、少油的健康饮食,蒸这种烹饪方式就很好的解决了这个难题。蒸锅选什么材质的比较好?蒸锅通过几十年的演变,外形的变化不大,但在材质上跟以前……
您的心脏怎么样?中医陪你了解自己的心脏iPhone14Pro缺货要等到明年?着急换机不妨看看这3款深圳企业100强名单发布,平安华为腾讯万科领衔2022年职工社保缴费基数调整上限为19899元下限为398CBA三消息上海裁掉三名内线,山西更换新东家,刘晓宇无培养费九十年代从良后,我和前夫的那点事儿(52)田静怕无归期,怕空欢喜,怕来的不是你。网友你值得世间美好樊振东出局让人意外!秦志戬执教能力遭质疑,最佳帮手在国乒队中中超1队史首胜国安12家上市,25家金种子摩拳擦掌湖北农企冲刺资本市场年轻人不愿意换手机的原因找到了!没钱不是唯一因素韩女星JOY身着超短裙大秀抬头挺胸之间的性感,韩网友太美了!

友情链接:中准网聚热点快百科快传网快生活快软网快好知文好找