go优雅读取zip压缩包-进阶2

【前言】
看到这里就晓得了,之前那一一篇文章go优雅读取zip压缩包,依旧还是有些问题,接下来,我就开始描述下本文章讲述的内容:

  1. 面对需要多次读取多个zip压缩包里的指定文件内容,如何提升读取的速度;
  2. 在提升速度的过程中,如何一步步找到内存占用和读取速度的平衡点;

!!!注意:
本次文章需要结合上一篇食用,本章不会直接贴全部实现代码,只提供核心实现代码和实现逻辑

结合上一次提到的通过读取zip的内存地址,来读取指定文件内容,后续发现一个问题。

Ⅰ 全局map实现快速读取指定文件

【问题】每次都需要去读取zip的内存地址,这个过程十分消耗时间,经测试后,发现读取速度居然要100ms左右
【解决办法】采用全局map,来存储下每一个zip包的内存地址,下次使用的时候,直接调用这个全局map,根据key-value,读取指定zip包的内存地址,后续就可以做到速率大幅度提升
【效果】 读取速度初次为50ms~100ms,后续的读取速度稳定到10ms左右

【相关代码如下】

var (
    tarFiles       = make(map[string]*zip.Reader) //创建一个全局的map来缓存已经打开的tar文件内存地址
    FSys           fs.FS
)
func main() {
    //读取压缩包
    ctx := context.Background()
    fsys, ok := tarFiles[archivePath]
    if !ok {
        var err error
        // 打开zip文件
        FSys, err = archiver.FileSystem(ctx, archivePath)
        if err != nil {
           fmt.Println("----从缓存中获取tar文件Error:", err)
        }
        if fsinfo, ok := FSys.(*zip.Reader); ok {
           tarFiles[archivePath] = fsinfo
           fsys = fsinfo
        } else {
           fmt.Println("----压缩包初始化失败:", err)
        }
        // 释放内存
        FSys = nil
    }
    // 其余代码
}

Ⅱ LRU找到内存占用和读取速度的平衡点

【现遇到问题】采用全局map存储zip内存地址,当处理大量的zip文件时,这将导致内存占用偏高,而且这个内存不会下降。
【解决办法】
采用缓存淘汰策略LRU算法(最近最少使用,根据数据的历史访问记录来进行淘汰数据)。这样,你可以在内存中保持一定数量的压缩包,当超过这个数量时,最不常用的压缩包将被从内存中删除,控制下存储的量 设置为25个,这样可以在速度和内存消耗之间找到一个平衡。

实操演练

// 第三种:采用LRU内存淘汰策略
fsys, err := zipFiles.Get(archivePath)
if err != nil {
    FSys, err = archiver.FileSystem(ctx, archivePath)
    if err != nil {
       fmt.Println("----从缓存中获取tar文件Error:", err)
       return nil, err
    }
    if fsinfo, ok := FSys.(*zip.Reader); ok {
       zipFiles.Add(archivePath, fsinfo)
       fsys = fsinfo
    } else {
       fmt.Println("----压缩包初始化失败:", err)
       return nil, err
    }
    FSys = nil
}

LRU算法实现

package core

import (
    zip "bt-tamper_proof_go/public/archiver/zip"
    "container/list"
    "errors"
    "sync"
)

// entry
// @author: 小小吴同学<2024-03-30>
// @Description: LRU 使用缓存淘汰策略算法
type entry struct {
    key   string
    value *zip.Reader
}

type LRUCache struct {
    maxEntries int
    ll         *list.List
    cache      map[string]*list.Element
    lock       sync.Mutex
}

func NewLRUCache(maxEntries int) *LRUCache {
    return &LRUCache{
       maxEntries: maxEntries,
       ll:         list.New(),
       cache:      make(map[string]*list.Element),
    }
}

/*
*  @author: 小小吴同学<2024-03-30 12:03:48>
*  @Description: 判断是否内存地址存在,不存在则创建,存在则删除再建
*  @param key
*  @param value
 */
func (c *LRUCache) Add(key string, value *zip.Reader) {
    c.lock.Lock()
    defer c.lock.Unlock()

    if ee, ok := c.cache[key]; ok {
       c.ll.MoveToFront(ee)
       ee.Value.(*entry).value = value
       return
    }

    ele := c.ll.PushFront(&entry{key, value})
    c.cache[key] = ele
    if c.maxEntries != 0 && c.ll.Len() > c.maxEntries {
       c.removeOldest()
    }
}

func (c *LRUCache) Get(key string) (*zip.Reader, error) {
    c.lock.Lock()
    defer c.lock.Unlock()

    if ele, hit := c.cache[key]; hit {
       c.ll.MoveToFront(ele)
       return ele.Value.(*entry).value, nil
    }
    return nil, errors.New("Key not found")
}

func (c *LRUCache) removeOldest() {
    ele := c.ll.Back()
    if ele != nil {
       c.ll.Remove(ele)
       kv := ele.Value.(*entry)
       delete(c.cache, kv.key)
    }
}

【效果】

  • 压测108个网站 新增文件1000次,读取文件稳定;
  • 内存占用均60M,文件防护速度保持在10ms内

在这里插入图片描述

【现有不足】访问模式的变化,需要一段时间才能逐渐将这部分新的数据加载到缓存中,替换掉原本的数据,这时候的缓存命中率下降,从原始的数据源拿去数据,防护速度会降低(后续会想下其余办法解决下这个问题)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

smart link实验配置

相关知识点&#xff1a;stp生成树协议&#xff0c;收敛时间慢会导致丢帧&#xff0c;所以利用samrt link配置 1.分主从端口&#xff0c;正常情况下主端口工作&#xff0c;从端口阻塞&#xff0c;防止回路&#xff0c;主端口出问题&#xff0c;切换从端口&#xff0c;并通过flu…

寒冬已逝,“量子春天”正来

最近&#xff0c;全球对量子技术领域的私人投资有所下降&#xff0c;引发了一些观点认为这个领域可能正逐渐衰退。 政治家、资助者和投资者并不总是以科学为关注焦点。然而&#xff0c;某些科技领域偶尔会成为热点&#xff0c;正如20世纪50年代核能技术的兴起&#xff0c;那时人…

分月饼 java题解

import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner sc new Scanner(System.in); int m sc.nextInt(); // 读取员工数量mint n sc.nextInt(); // 读取月饼数量n// 调用distribute方法并打印返回的分配方法总数//先默认每人分一个…

​慧天[HTWATER]可以与与SWMM模型之间实现转换吗?

​慧天[HTWATER]软件简介 针对城市排水系统基础设施数据管理的需求&#xff0c;以及水文、水力及水质模拟对数据的需求&#xff0c;实现了以数据库方式对相应数据的存储。可以对分流制排水系统及合流制排水系统进行地表水文、管网水力、水质过程的模拟计算。可以对城市低影响开…

echarts仪表盘特殊样式

const drawChartOption function (value, max) {const colorConfig {name: 测试,colorList: {text: #fff,line2: {type: linear,x: 0, // 右y: 0, // 下x2: 1, // 左y2: 0, // 上colorStops: [// {// offset: 0,// color: transparent// },{offset: 0.1,color: #031e…

TikTok防关联引流系统:全球多账号运营的终极解决方案

tiktok防关联引流系统介绍&#xff0c;tiktok防关联系统是基于tiktok生态研发的效率工具&#xff0c;帮你快速实现tiktok全球多账号运营&#xff0c;系统配备了性能强劲的安卓&#xff0c;防关联智能终端&#xff0c;可一建创建全球多国手机环境&#xff0c;完美满足各类app软件…

CX3324A是德科技CX3324A器件电流波形分析仪

181/2461/8938产品概述&#xff1a; 器件电流波形分析仪&#xff0c;1 GSa/s&#xff0c;14/16 位&#xff0c;4 通道 主机功能特性 为电流和差分传感器以及无源探头接口适配器提供 4 个模拟通道带宽选件&#xff1a;50 MHz、100 MHz、200 MHz存储器深度选件&#xff1a;4 M…

eclipse操作

1. 屏蔽不用的代码或文件夹 右键需要屏蔽的文件夹或文件&#xff0c;选择properties&#xff0c;选择c/c build &#xff0c;在Exclude resource from build 前面勾选&#xff0c;然后点击apply应用&#xff0c;就屏蔽了这个文件夹或者文件了&#xff0c;编译时就会忽略。 设置…

浅聊什么是Redis?

需求&#xff1a;MySQL面临大量的查询&#xff0c;即读写操作&#xff0c;因此类比CPU&#xff0c;给数据加缓存&#xff0c;Redis诞生。应用程序从MySQL查询的数据&#xff0c;在Redis设置缓存&#xff08;记录在内存中&#xff0c;无需IO操作&#xff09;&#xff0c;后再需要…

Linux(CentOS)安装Redis教程_简单快捷

一、安装依赖 因为redis是用C语言开发的&#xff0c;所以在安装之前需要确定是否安装gcc环境&#xff08;gcc -v&#xff09;&#xff0c;如果没有安转可以执行一下命令进行安装 [rootlocalhost ~]# yum install -y gcc 二、下载安装包 1.在官网先进行下载 官网地址&#x…

Node.js-------初识Node.js与内置模块

能够知道什么是 Node.js能够知道 Node.js 可以做什么能够说出 Node.js 中的 JavaScript 的组成部分能够使用 fs 模块读写操作文件能够使用 path 模块处理路径能够使用 http 模块写一个基本的 web 服务器 一.初识Node.js 1.浏览器中的 JavaScript 的组成部分 2.Node.js 简介 …

从“量子”到分子:探索计算的无限可能 | 综述荐读

在2023年年末&#xff0c;两篇划时代的研究报告在《科学》&#xff08;Science&#xff09;杂志上引发了广泛关注。这两篇论文分别来自两个研究小组&#xff0c;它们共同揭示了单氟化钙分子间相互作用的研究成果&#xff0c;成功地在这些分子间创造出了分子量子比特。这一成就不…

理解二分类场景评估中的Recall和Precision

场景解释&#xff1a; 二分类场景会有两种输出。我的样本里有猫的图片和其他的图片。我的输出值是“是猫”和“非猫”。这个场景下&#xff0c;“是猫”是我的正样本(Postive)。“非猫”是我的负样本(Negative)。 Confusion matrix: 横向表示预测的结果。纵向表示真实的结果。…

生命之重-ICU门口的守望人

有人说如果没有经历过在ICU门口守候的人&#xff0c;就无法真正懂得珍惜生命。但实际情况也未必尽然&#xff0c;不过这种经历确实可以教会你懂得珍惜&#xff0c;当然希望大家都不要亲身经历。我希望能够通过讲述一个真实的故事来呈现这一观点&#xff0c;而不是令人难以接受的…

Linux部署Kafka2.8.1

安装Jdk 首先确保你的机器上安装了Jdk&#xff0c;Kafka需要Java运行环境&#xff0c;低版本的Kafka还需要Zookeeper&#xff0c;我此次要安装的Kafka版本为2.8.1&#xff0c;已经内置了一个Zookeeper环境&#xff0c;所以我们可以不部署Zookeeper直接使用。 1、解压Jdk包 t…

idea了解

1、快捷键 1.1、编辑美化相关 1.1.1、双击选中一个单词&#xff0c;三击选中一行代码 1.1.2、ctrlD&#xff1a;快速粘贴复制&#xff1b;光标所在复制 1.1.3、altinsert&#xff1a;构造方法的快速生成&#xff1b;toString方法快速生成&#xff1b;等等 1.1.4、ctrlR:快…

怎样给文件夹中的文件依次编号?选择合适的方法给文件依次编号

在日常生活和工作中&#xff0c;我们经常需要对文件夹中的文件进行编号&#xff0c;以便更好地管理和查找。编号的方式多种多样&#xff0c;可以根据不同的需求和场景来选择。下面&#xff0c;我将详细介绍如何给文件夹中的文件依次编号。 一、了解编号的目的和需求 在给文件编…

基于51单片机的智能门禁系统仿真设计

**单片机设计介绍&#xff0c;基于51单片机的智能门禁系统仿真设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于51单片机的智能门禁系统仿真设计概要 一、设计概述 本设计旨在利用51单片机为核心控制器&#xff0c;结合…

为什么品牌宣传需要深度稿件?媒介盒子揭秘

在信息洪流中&#xff0c;品牌想要占据用户心智仅靠传统的广告方式很难达成目标&#xff0c;只有真正有价值的信息才能吸引用户注意力&#xff0c;品牌方可以通过深度稿件来实现。 深度传播稿是一种高质量的、需要花费较长时间和精力来撰写的宣传文章&#xff0c;篇幅较长&…

SpringBoot:自定义线程池配置类

文章目录 一、前言二、案例展示1、初始版本2、代码审核意见和优化建议3、潜在问题和风险4、优化建议5、优化后的代码 三、具体使用 一、前言 有时候我们在项目中做一些长链路的跑批任务时&#xff0c;基于Springboot项目的定时任务&#xff0c;我们可以指定一个自定义的线程配…