golang本地缓存库之bigcache

1. 前言

上周工作之余逛github看到一个本地缓存库bigcache,这个是allegro公司开源的一个项目,主要是用于本地缓存使用,根据他们的博客说明,他们编写这个库最初的目的就是实现一个非常快速的缓存服务。

看了下bigcache这个库的源码,这个库主要在两个方面进行了一定的创新:

  1. 并发性
    1. 缓存获取的时候会产生并发,会涉及锁的争用问题,bigcache通过分片的机制解决了并发的问题
  2. 省略垃圾收集器
    1. Go中的垃圾收集器在GC期间会在扫描和标记阶段去访问map中的每一个键值对,当map很大的时候会造成系统性能的下降。在go中如果你使用的map的键值都不包含任何指针元素的话,则GC会忽略这些内容,所以bigcache通过将所有的键都定义成整数类型,从而避免了GC。

2. 为什么不使用Redis等缓存中间件呢?

关于为什么不使用Redis/Memcached这类缓存,这是因为这些缓存中间件都属于外部依赖,在对缓存进行操作时都存在网络上的延迟,所以就生出了bigcache。

3. 并发分片

缓存服务会同时接收多个请求,因此需要对缓存提供并发访问,而实现并发访问的简单方法是利用读写锁,即sync.RWMutex来实现,从而确保每一次只有一个goroutine可以修改缓存,但这样会阻塞其他的Goroutine,从而触及性能瓶颈。
在这里插入图片描述

为了解决这个问题,bigcache通过分片的机制,即将cache分成N个shard,即每个shard存储一部分数据,而在对Key的数据进行获取或者存储的时候,通过hash(key)%N 即可实现分片位置的获取。在N足够大的时候,锁的争用可以最小化到几乎为0。
在这里插入图片描述

3.过期键值的驱逐

本地缓存肯定有缓存大小的上限,为了避免本地缓存无限增大的问题,就需要驱逐过期的键值对,bigcache通过一个fifo的队列(在bigcache中,这个fifo的实现是通过BytesQueue来实现的,即每个键值的插入与删除都是通过具体的偏移量来实现的,驱逐则是通过移动fifo的头类实现的),来实现数据驱逐的问题。

当缓存的键值对数据被添加到缓存中的时候,会发生两个额外的操作:

  1. 包含key和创建时间的键值对会被添加到队列的尾部
  2. 从队列中读取最旧的元素,将元素的创建时间戳与当前时间进行比较,如果超出了存活的生命周期大小,则队列中的元素键值对将会被删除。

由于键值的驱逐是需要获取锁来实现的,所以一般都是在写入缓存的期间执行驱逐行为。

4. 省略垃圾收集器

在Go中,如果你有一个map,则垃圾收集器会在标记和扫描阶段访问该map的每一个项目,当map足够大的时候,可能会对应用程序的性能造成较大的影响。

因为bigcache的定位就是满足数百万个键值对的存储,所以会使得GC耗费的时间变长,从而使得应用程序性能下降。

GC只在堆上发生,可以考虑去堆外存储这些元素,但如果去堆外存储,则需要依赖额外的库(offheap)。

另一种是通过减少指针的数量来实现零GC开销的map,可以参考freecache,将键值保存在环形缓冲区中,使用索引切片查找条目。

最后一种就是bigcache使用的基于go的一个优化方法,优化表明如果map中的键值没有使用指针类型,则GC会忽略这些内容。但Go中所有的数据基本都是基于指针构建的,比如结构体、切片以及数组等。这就意味着我们需要把这些键值修改为ini或者bool这样的数据,从而避免键值设置为指针。

在上面并发分片中,采用分片的方式存储多组缓存数据从而增加并发度,这里bigcache会复用分片的理论,因为分片是将key通过hash方法变成一个int类型的key,而通过int类型的key我们可以找到具体的分片位置,具体的缓存是存储在分片中的,而分片缓存中的map是map[int][int]类型的,则key表示我们获取的hashkey,值则表示具体的数据的偏移量。这样在获取某个key数据的时候,我们只需要:

  1. 通过hash函数获取hashedKey
  2. 通过hashedKey获取分片
  3. 通过分片中hashedKey的偏移量
  4. 通过偏移量获取数据

在这里插入图片描述

5. 总结

bigcache用于在本地存储数以百万计的键值对拥有比较好的性能,这个主要得意于其采用的:

  1. 并发分片
  2. 零GC

并发分片的方式帮助bigcache在分片足够大的时候,可以做到goroutine争用为0,而通过Go官方对map键值非指针的情况下,GC会忽略这些内容的优化,bigcache通过将key转化为hash整数,从而定位到具体的shard分片,继而将值量化为具体的BytesQueue中的偏移量,实现了map[int][int]结构,从而实现了零GC。

这里面的BytesQueue也挺有趣的,将所有的键值数据通过byte的形式与偏移量进行具体的转化,从而实现了基于bytes数组的fifo队列。

另外bigcache还提供除了一组http的接口用于其他服务调用获取缓存数据。

参考

  1. Writing a very fast cache service with millions of entries in Go
  2. bigcache
  3. runtime: Large maps cause significant GC pauses

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/1340.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【信号与系统 - 10】拉普拉斯变换

1 定义 周期信号的傅里叶变换那篇提到了&#xff1a; F ( j w ) ∫ − ∞ ∞ e − j w t f ( t ) d t F(jw)\int^{\infty}_{-\infty}e^{-jwt}f(t)dt F(jw)∫−∞∞​e−jwtf(t)dt 这个定义式需要满足绝对可积&#xff0c;即 ∫ − ∞ ∞ ∣ f ( t ) ∣ d t < ∞ \int…

linux进阶篇:使用Apache搭建文件服务器目录

Linux服务搭建篇&#xff1a;使用Apache搭建文件服务器目录 一、关于文件服务器 ​ 在一个项目中&#xff0c;如果想把公共软件或者资料共享给项目组成员&#xff0c;可以搭建一个简易的文件服务器来实现&#xff0c;只要是在局域网内的成员都可以通过浏览器或者wget命令来下…

IDEA中添加servlet模板

官方代码链接 #if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end #parse("File Header.java")import javax.servlet.*; import javax.servlet.http.*;

C++奇迹之旅:构造函数和析构函数

文章目录 &#x1f4dd;类的6个默认成员函数&#x1f320; 构造函数&#x1f309; 概念&#x1f309;特性&#x1f309;三种默认构造函数 &#x1f320; 析构函数&#x1f320; 特性&#x1f6a9;总结 &#x1f4dd;类的6个默认成员函数 如果一个类中什么成员都没有&#xff0…

iOS重签名-超详细,附排错

文章目录 重签名步骤步骤 1: 准备必要的材料步骤 2: 解压 .ipa 文件步骤3:将 Provisioning Profile 复制到 Payload 目录步骤 4: 移除原来的签名步骤 5: 使用新的证书和 Provisioning Profile 进行重签名步骤 6: 重新打包 .ipa 文件步骤 7: 安装和测试得到provisioning file和…

Python编程玩转二维码

文章目录 Python编程玩转二维码第一部分&#xff1a;背景介绍第二部分&#xff1a;qrcode库是什么&#xff1f;第三部分&#xff1a;如何安装这个库&#xff1f;第四部分&#xff1a;库函数使用方法第五部分&#xff1a;场景应用第六部分&#xff1a;常见Bug及解决方案第七部分…

微信小程序展示倒计时

html <view class"countdown"> <text>倒计时&#xff1a;</text> <text wx:for"{{countdown}}" wx:key"index">{{item}}</text> </view> ts data: {countdown: [], // 存放倒计时数组 targetTime:…

【CSAPP/计组】#1 数的存储与表示方法、机器中浮点数加减法详解

文章目录 前言一、定点格式定点整数 二、浮点数的表示方法2.1 浮点数存储2.2 浮点数加减法a. 操作数检查b. 对阶c. 尾数相加与检查溢出d. 结果规格化与溢出处理e.舍入处理 Some tips: 为什么进位/双符号判断法有效的通俗解释&#xff1f;Some tips:符号位拓展 前言 计算机中常…

【归并】Leetcode 排序数组

题目讲解 912. 排序数组 算法讲解 使用归并算法排序数组&#xff0c;我们先在数组中寻找一个mid点&#xff0c;然后把数组分成了两部分&#xff0c;我们先排左部分&#xff0c;排左边部分的时候有需要将当前的子数组分成两部分&#xff0c;继续循环&#xff0c;直到当前子数组…

【结构型模式】装饰器模式

​一、装饰器模式概述 装饰器模式&#xff08;装饰者模式&#xff09;定义&#xff1a;装饰器模式动态地将责任附加到对象上。若要拓展功能&#xff0c;装饰者提供了比继承更有弹性地替代方案。&#xff08;对象结构型模型&#xff09;通俗点来说&#xff1a;动态的给一个对象增…

淘宝购物更智能:taobao.item_search API接口实现关键字精准匹配

随着电子商务的飞速发展&#xff0c;淘宝作为中国最大的网络购物平台之一&#xff0c;为亿万消费者提供了便捷、丰富的购物体验。然而&#xff0c;在海量商品中快速找到符合自己需求的商品&#xff0c;一直是消费者面临的挑战。为了提升购物体验&#xff0c;淘宝开放平台提供了…

【JS】js数字转k、w结尾 | 1000 = 1k

问题 数字转k、w结尾 如&#xff1a;10001k 100001w 码 /*** 数字转k,w* param {Number} num * returns String*/ const numberTokw num > {if (num < 1000) return numlet endStr w,numVal 10000;if (num > 999 && num < 10000) {endStr knumVal …

使用python socket搭建Client测试平台

目录 概述 1 背景 2 Client功能实现 2.1 何谓Client 2.2 代码功能介绍 2.3 代码实现 2.3.1 代码介绍 2.3.2 代码内容 3 测试 3.1 PC上创建Server 3.2 同一台PC上运行Client 3.2.1 建立连接 3.2.2 测试数据交互 3.3 Linux 环境下运行Client 3.3.1 建立连接 3.3.…

ElasticSearch实战之项目搜索高亮

文章目录 1. 前情配置2、数据操作2.1 操作API2.2 数据入库 3. 高亮搜索3.1 方法封装3.2 高亮搜索 1. 前情配置 为满足ElasticSearch可在项目中实现搜索高亮&#xff0c;我们需要先做一些前情配置 导入ElasticSearch依赖 <dependency><groupId>org.springframewor…

EPSON晶振应用到汽车电子产品上的型号有哪些?

EPSON品牌应用在汽车电子产品上的晶振.&#xff0c;当然也少不了晶振可能最熟悉的就是32.768K系列和26MHZGPS晶振用的多。 在汽车里每一个部件都应有的不一样,甚至多次使用到同一尺寸,不同频率的晶振.爱普生品牌晶振型号就有几百种,很容易混淆,要想记住汽车里所应用到的不是件…

B树(B-tree)

B树(B-tree) B树(B-tree)是一种自平衡的多路查找树&#xff0c;主要用于磁盘或其他直接存取的辅助存储设备 B树能够保持数据有序&#xff0c;并允许在对数时间内完成查找、插入及删除等操作 这种数据结构常被应用在数据库和文件系统的实现上 B树的特点包括&#xff1a; B树为…

学习空间转换-3D转换

1.什么是空间转换&#xff1f; 使用的是transform属性实现元素在空间内的位移&#xff0c;旋转&#xff0c;缩放等效果。 空间&#xff1a;是从坐标轴角度定义的。x,y,z三条坐标轴构成的一个立体空间&#xff0c;Z轴位置与视线方向相同。 所以空间转换也被叫做3D转换 语法&a…

PICkit 3 v3.10中的 Device Family 识别不到芯片

1&#xff1a;现象描述 在使用 PICkit3烧写hex文件的时候&#xff0c;Device Family只有默认芯片&#xff0c;识别不到当前使用的芯片&#xff0c;导致报错“Device Error - hex file not loaded”&#xff0c;我当前使用的是 PIC16F1826芯片&#xff0c;默认不支持&#xff1…

快速开发部署平台Replit

Replit 是可以快速搭建开发、部署环境的平台。能够快速将原型进行部署&#xff0c;代码编辑器支持协同开发&#xff0c;他的在线编辑器做的不错&#xff0c;相当于云上提供了一个 vscode&#xff0c;代码实时更新。Replit 底层是基于容器技术的&#xff0c;可以安全的隔离多个用…

html、css、QQ音乐移动端静态页面,资源免费分享,可作为参考,提供InsCode在线运行演示

CSDN将我上传的免费资源私自变成VIP专享资源&#xff0c;且作为作者的我不可修改为免费资源&#xff0c;不可删除&#xff0c;寻找客服无果&#xff0c;很愤怒&#xff0c;&#xff08;我发布免费资源就是希望大家能免费一起用、一起学习&#xff09;&#xff0c;接下来继续寻找…