高性能缓存:使用 Redis 和本地内存缓存实战示例
在现代高并发系统中,缓存技术是提升性能和降低数据库压力的关键手段。无论是分布式系统中的Redis缓存,还是本地高效的本地内存缓存,合理使用都能让你的应用如虎添翼。今天,我们将基于go-dev-frame/sponge/pkg/cache库的代码示例,深入探讨这两种缓存的原理与使用方法,带你从零到一掌握缓存技术。
缓存的原理:为什么它如此重要?
缓存的核心思想是通过将频繁访问的数据存储在快速读取的介质中,减少对底层存储(如数据库)的直接请求。以Redis为例,它是一个高性能的键值对存储系统,支持持久化、网络分布式部署,适合大规模分布式应用。而本地内存缓存则利用程序运行时的RAM,速度更快但容量有限,通常用于单机场景或临时数据存储。两者的共同目标是:降低延迟,提升吞吐量。
在cache库中,无论是Redis还是本地内存缓存,都通过统一的接口封装了Set、Get和Delete操作。这种设计不仅简化了开发,还提供了灵活的扩展性。接下来,我们将通过代码示例,逐一剖析它们的实现与应用。
使用Redis缓存:分布式性能的保障
Redis以其高可用性和丰富的数据结构著称。在cache中,我们可以通过以下代码快速集成Redis缓存:
package mainimport ("context""fmt""time""github.com/redis/go-redis/v9""github.com/go-dev-frame/sponge/pkg/cache""github.com/go-dev-frame/sponge/pkg/encoding"
)// User 结构体示例
type User struct {ID intName string
}func main() {// 初始化 Redis 客户端redisClient := redis.NewClient(&redis.Options{Addr: "localhost:6379",Password: "",DB: 0,})cachePrefix := "user:"jsonEncoding := encoding.JSONEncoding{}newObject := func() interface{} {return &User{}}// 创建 Redis 缓存实例c := cache.NewRedisCache(redisClient, cachePrefix, jsonEncoding, newObject)ctx := context.Background()user := &User{ID: 1, Name: "Alice"}// 设置缓存数据err := c.Set(ctx, "1", user, 10*time.Minute)if err != nil {fmt.Println("缓存存储失败:", err)return}// 获取缓存数据var cachedUser Usererr = c.Get(ctx, "1", &cachedUser)if err != nil {fmt.Println("缓存读取失败:", err)return}fmt.Println("从缓存获取用户:", cachedUser)// 删除缓存c.Delete(ctx, "1")
}
原理剖析
NewRedisCache函数通过Redis客户端、cachePrefix(键前缀,用于命名空间隔离)、jsonEncoding(序列化方式)和newObject(反序列化目标对象构造器)初始化缓存实例。Set方法将数据序列化为JSON后存入Redis,Get方法则反序列化回指定对象。这种设计兼顾了灵活性与类型安全,非常适合需要跨服务共享数据的场景。
使用本地内存缓存:单机性能的极致追求
对于不依赖分布式的场景,本地内存缓存是一个轻量高效的选择。以下是一个基于sponge/pkg/cache的本地内存缓存示例:
package mainimport ("context""fmt""time""github.com/go-dev-frame/sponge/pkg/cache""github.com/go-dev-frame/sponge/pkg/encoding"
)// User 结构体示例
type User struct {ID intName string
}func main() {// 初始化内存缓存cachePrefix := "user:"jsonEncoding := encoding.JSONEncoding{}newObject := func() interface{} {return &User{}}// 创建内存缓存实例c := cache.NewMemoryCache(cachePrefix, jsonEncoding, newObject)ctx := context.Background()user := &User{ID: 2, Name: "Bob"}// 设置缓存数据err := c.Set(ctx, "2", user, 10*time.Minute)if err != nil {fmt.Println("缓存存储失败:", err)return}// 获取缓存数据var cachedUser Usererr = c.Get(ctx, "2", &cachedUser)if err != nil {fmt.Println("缓存读取失败:", err)return}fmt.Println("从缓存获取用户:", cachedUser)// 删除缓存c.Delete(ctx, "2")
}
原理剖析
本地内存缓存基于本地RAM实现,默认使用类似bigcache的底层库,支持配置最大容量和淘汰策略(如LRU)。通过InitGlobalMemory可以自定义缓存参数,但即使不初始化也能直接使用默认配置。它的优势在于无需网络IO,延迟极低,适合高频读写的场景。
Redis vs 本地内存缓存:如何选择?
- Redis:适用于分布式系统、需要持久化或跨进程共享数据的场景。缺点是网络开销和部署成本较高。
- 本地内存缓存:适合单机高性能需求或临时数据存储,简单易用但容量受限,且重启后数据丢失。
总结
通过cache库,Go开发者可以轻松集成Redis和本地内存缓存,满足不同场景的性能需求。无论是分布式系统的Redis,还是单机场景的本地内存缓存,它们都以统一接口降低了学习成本,同时保留了高度的灵活性。希望这篇博客能为你提供实用的技术洞察,快去试试吧!
Sponge 是一个强大的 Go 开发框架,其核心理念是通过解析 SQL、Protobuf、JSON 文件逆向生成模块化代码,这些代码可灵活组合成多种类型的完整后端服务。Sponge 提供一站式项目开发解决方案,涵盖代码生成、开发、测试、API 文档生成和部署等方面,显著提升开发效率,降低开发难度,实现以"低代码"方式构建高质量企业级项目。Sponge与内置的DeepSeek R1助手协同重构传统开发范式,打造极速开发体验。
Sponge Github 地址: https://github.com/go-dev-frame/sponge
相关文章:
高性能缓存:使用 Redis 和本地内存缓存实战示例
在现代高并发系统中,缓存技术是提升性能和降低数据库压力的关键手段。无论是分布式系统中的Redis缓存,还是本地高效的本地内存缓存,合理使用都能让你的应用如虎添翼。今天,我们将基于go-dev-frame/sponge/pkg/cache库的代码示例&a…...
Linux动态库和静态库
Linux动态库和静态库 Linux动态库和静态库动静态库的基本原理可执行程序的生成过程动静态库的本质 认识动静态库背后的库支持动静态库的命名静态链接示例 动静态库各自的特征静态库动态库 静态库的打包与使用示例文件打包1. 生成目标文件2. 打包静态库3. 组织文件使用 Makefile…...
13 IO流:字节流、字符流、缓冲流、文件复制(字节/字符/缓冲区)、字符转换流、打印流、IO框架(黑马Java视频笔记)
文章目录 IO流 >> 读写数据的方案1. 认识IO流1)IO流的分类2)IO流的体系 2. 文件字节输入流2.1 创建文件字节流对象2.2 读取文件1)使用read()方法一个一个字节的读取2)使用字节数组读取数据:byte[]3)使用字节流读…...
深入理解 TypeScript 中的迭代器(Iterators)与生成器(Generators)
一、为什么需要迭代协议? 在现代 JavaScript/TypeScript 开发中,我们经常需要处理各种集合型数据:数组、Map、Set 甚至是自定义数据结构。ES6 引入的迭代协议(Iteration Protocols)正是为了解决统一遍历机制的问题。通…...
靶场(十四)---小白心得思路分享---Extplorer
启程: 开始扫描端口服务,发现什么都没有,果断进行下一步目录扫描 PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0) | ssh-hostkey: | 3072 98:4e:5d:e1:e6:97:29:6f:…...
逆向中常见的加密算法识别
1、base64及换表 base64主要是将输入的每3字节(共24bit)按照每六比特分成一组,变成4个小于64的索引值,然后通过一个索引表得到4个可见的字符。 索引表为一个64字节的字符串,如果在代码中发现引用了这个索引表“ABCDEF…...
【初学者】怎样学习、使用与研究算法?
李升伟 整理 学习、使用与研究算法是一个系统化的过程,涉及理论学习、实践应用和深入研究。以下从学习方法、使用技巧和研究方向三个方面进行详细阐述: 一、学习方法 1. 分阶段学习 初级阶段:掌握经典算法,如最短路径算法&…...
【愚公系列】《高效使用DeepSeek》018-错题本整理
🌟【技术大咖愚公搬代码:全栈专家的成长之路,你关注的宝藏博主在这里!】🌟 📣开发者圈持续输出高质量干货的"愚公精神"践行者——全网百万开发者都在追更的顶级技术博主! 👉 江湖人称"愚公搬代码",用七年如一日的精神深耕技术领域,以"…...
Linux上的`i2c-tools`工具集的编译构建和安装
源码复制到Ubuntu系统中并解压 的i2c-tools工具集的源码百度网盘下载链接: https://pan.baidu.com/s/1XNuMuT1auT1dMzYo3LAFmw?pwdi6xe 终端进入源码目录 cd /home/book/mybuild/i2c-tools-4.2执行编译构建命令 运行下面的命令进行编译构建 make CC${CROSS_COM…...
langgraph简单Demo(使用langserve实现外部调用)
前言 这个示例是研究如何使用langserve实现外部调用 接入大模型参考文章:接入阿里云百炼 1、安装依赖 pip install langserve fastapi uvicorn pip install sse_starlette 2、代码实现 from fastapi import FastAPI from langchain_core.messages import HumanM…...
【C#高阶编程】—单例模式详解
C# 单例模式 单例模式是一种设计模式,用于确保一个类只有一个实例,并提供一个全局访问点来访问该实例。单例模式常用于需要全局唯一对象的场景,比如配置文件管理、日志记录、数据库连接池等。 单例模式的核心特点 私有构造函数:…...
折叠树报表
折叠树报表中包含了三种信息: 1.树组织信息-可展开、收拢 2.节点的统计信息(汇总求和) 3.每个节点对应的数据信息 一、准备数据 mysql8 数据库中存在两张表 org和store表。 org表和部分数据如下,其中orgname是组织的名称,codepath是完整的组织代码,seq是每个节点的顺序,可…...
Python个人学习笔记(16):模块(os)
四、os模块 主要用于文件夹处理 (一)文件夹相关 os.makedirs(‘dirname1/dirname2’) :创建文件夹目录,不能重复创建,用的多 代码: os.makedirs(a/b/c)结果: os.removedirs(‘dirname1’)&…...
虚拟地址空间(下)进程地址空间(上)
一.关于页表组成 1.权限(rwx) 作用:如1.让代码区变成只读的 2.写时拷贝的实现:子进程创建时其页表指向的父进程代码和数据权限都是只读的,子进程试图修改,触发错误,系统开始写时拷贝。 来源:…...
【数据集分享】青藏高原两次强震玛多地震和漾濞地震的震源过程
2021年5月21日,5小时内在青藏高原不同区域发生了漾濞6.4级和玛多7.4级强烈地震,表明印度板块和欧亚大陆板块的碰撞汇聚作用下青藏高原持续和频繁的 剧烈构造运动和地震活动。本研究利用地震记录和空间对地观测同震位移资料(InSAR)…...
jmeter环境搭建及使用
Meter 是一个开源的性能测试工具,用于测试静态和动态资源的性能。 1、安装 官网下载: 下载地址:Apache JMeter - Download Apache JMeter 网盘下载: 通过百度网盘分享的文件:apache-jmeter-5.6.3.rar 链接&#x…...
Python 鼠标轨迹算法 - 防止游戏检测
一.简介 鼠标轨迹算法是一种模拟人类鼠标操作的程序,它能够模拟出自然而真实的鼠标移动路径。 鼠标轨迹算法的底层实现采用C/C语言,原因在于C/C提供了高性能的执行能力和直接访问操作系统底层资源的能力。 鼠标轨迹算法具有以下优势: 模拟…...
网络编程--服务器双客户端聊天
写一个服务器和客户端 运行服务器和2个客户端,实现聊天功能 客户端1和客户端2进行聊天,客户端1将聊天数据发送给服务器,服务器将聊天数据转发给客户端2 要求: 服务器使用 select 模型实现 ,客户端1使用 poll 模型实现…...
yum软件包乾坤大挪移(Yum Package Qiankun Great Migration)
yum软件包乾坤大挪移 背景 由于很多的生产环境是无法连接外网的,因此用yum或者dnf命令来安装软件包常常是一个比较麻烦的事情,原因是很多软件的依赖很复杂,如果要一个个下载、拷贝、再安装,这往往是一个非常繁琐冗杂的过程&…...
Java:读取中文,read方法
public static void main(String[] args) throws IOException {FileReader fr new FileReader("C:\\aaa\\a.txt");//字符流的底层也是一个字节一个字节读取的,遇到中文就一次读多个,GBK一次读两个,UTF-8一次读三个字节//idea默认U…...
[GHCTF 2025]真会布置栈吗?
题目是一个聊天室,我们先按照题目使用 /help Help: /help 显示此帮助信息 /msg [text] 在当前频道发送消息 /nick [name] 更改你的用户名 /list 列出可用的频道 /join [channel] 切换到不同的频道 /channel …...
集合的练习1-2
//练习1: import java.util.ArrayList;public class ArraylistTest1 {public static void main(String[] args){ArrayList<String> listnew ArrayList<>();//需求:定义一个集合,添加字符串,并进行遍历//遍历格式&…...
英语词性--数词
文章目录 数词概念数词分词基数词序数词 基数与序数词的区别基变序的规律 数词概念 数词(Numerals) 是英语中用于表示 数量(基数)或顺序(序数) 的词类,通常用于描述数字、计数、顺序等。 例如&…...
面试整理--一个报告生成的方案解析
最近又快到了年后找工作的时间,近期写点工作积累,供大家参考。 欢迎关注公主号【测试开发备忘录】,交流职场技巧和经验 首先从工作中一个报错来展开: Start directory is not importable: 错误信息 "Start directory is not importable…...
C#零基础入门篇(18. 文件操作指南)
## 一、文件操作基础 在C#中,文件操作主要通过System.IO命名空间中的类来实现,例如File、FileStream、FileInfo等。 ## 二、常用文件操作方法 ### (一)文件读取 1. **使用File.ReadAllText方法读取文件内容为字符串** …...
Linux 一步部署DHCP服务
#!/bin/bash #脚本作者和日期 #author: PEI #date: 20250319 #检查root权限 if [ "$USER" ! "root" ]; then echo "错误:非root用户,权限不足!" exit 0 fi #防火墙与高级权限 systemctl stop firewa…...
如何打造安全稳定的亚马逊采购测评自养号下单系统?
在当今的电商领域,亚马逊作为全球领先的在线购物平台,其商品种类繁多,用户基数庞大,成为了众多商家和消费者的首选。而对于一些需要进行商品测评或市场调研的用户来说,拥有一个稳定、安全的亚马逊账号体系显得尤为重要…...
【大模型学习】第二十四章 生成式人工智能(GAI)简介
目录 一、什么是生成式人工智能(GAI)? 二、核心技术原理 三、典型应用场景 四、技术特点与挑战 五、训练优化策略 六、关键性能指标(2025年基准) 七、技术演进方向: 一、什么是生成式…...
Pytorch中layernorm实现详解
平时我们在编写神经网络时,经常会用到layernorm这个函数来加快网络的收敛速度。那layernorm到底在哪个维度上进行归一化的呢? 一、问题描述 首先借用知乎上的一张图,原文写的也非常好,大家有空可以去阅读一下,链接放…...
YOLO11报错:AttributeError: module ‘torch‘ has no attribute ‘OutOfMemoryError‘
事情是这样的:前几天YOLO11的代码还是可以训练的,昨天训练了一天,今天换模型就报这个错。 AttributeError: module torch has no attribute OutOfMemoryError我查了一下:YOLO11官方代码issues里面也有人有同样的问题,…...
