golang实现简单的redis服务4(实现过期时间功能)

news2024/12/12 5:08:56

      • 为什么要做过期时间?
      • redis失效时间是如何做的
        • redis有那些过期策略,优缺点,实现原理?
          • redis使用的什么方案
      • redis 有那些内存淘汰策略?常用的是什么,为什么?
        • noeviction: 不处理
        • lru: 未使用时间最久的key
        • lfu: 使用次数最少的key
        • random: 随机key
        • volatile与allkeys的区别

仓库地址: https://github.com/dengjiayue/my-redis-v2.0-RESP-.git

为什么要做过期时间?

: 因为redis是内存数据库,空间是有限并且昂贵的,如果我们只存数据很快就会资源耗尽.
所以我们需要清理数据腾出空间储存其他的数据

redis失效时间是如何做的

redis是使用失效时间字典去存放失效时间的
key为对应数据的指针,val为失效时间戳(毫秒级)
在这里插入图片描述

redis有那些过期策略,优缺点,实现原理?
  1. 立即清除,key到过期时间立即清除
    优点:内存友好,能够快速释放出空间
    缺点: cpu消耗大,不停执行清除,如果遇到请求压力大的时候会额外增加cpu的负担
    实现方案: 使用时间轮调度器,每设置一个失效时间就加一个延时调度删除方法,到过期时间会调度删除方法删除该数据

  2. 惰性清除: 当使用key的时候检查是否过期,如果过期就清除该数据
    优点: cpu友好,不需要时刻执行清除
    缺点: 内存不友好,有一些不使用的过期数据会无法清除,浪费空间资源(redis空间很宝贵)
    实现方案: 当调用查询的时候先检查是否过期,如果过期清除数据并返回空

  3. 定时清除: 定时扫描过期字典,将过期的数据清除
    这是一个折中的方案,既不会向立即清除那样消耗太多的cpu,又不会让不使用的数据长期停留在数据库中
    实现方案: 做一个定时任务,定时扫描过期字典并清除过期数据

redis使用的什么方案

redis使用的是定时以惰性删除结合的方案

package src

import (
	"my_redis/src/timewheel"
	"strconv"
	"time"
)

//过期时间实现
//

// 扫描部分key并检查是否过期
func (s *Server) CheckExpire(num int) {
	// 遍历所有key
	for k, v := range s.Ex {
		if v < time.Now().Unix() {
			// 过期了
			delete(s.Ex, k)
			// 删除key
			delete(s.M, k)
		}
		num--
		if num == 0 {
			break
		}
	}
}

// 定时过期
func (s *Server) TimingExpire() {
	// 定时执行
	ticker := time.NewTicker(time.Second)
	for {
		<-ticker.C
		// 定时执行
		s.CheckExpire(100)
	}
}

// 惰性过期(输出是否过期 )
func (s *Server) LazyExpire(key string) bool {
	// 检查key是否过期
	if s.Ex[key] < time.Now().Unix() {
		// 过期了
		delete(s.Ex, key)
		// 删除key
		delete(s.M, key)
		return true
	}
	return false
}

// 立即过期
// 使用时间轮实现立即过期
// exTime为毫秒过期时间
func (s *Server) ImmediatelyExpire(key string, exTime int64) {
	late := time.Millisecond * time.Duration(exTime)
	timewheel.Delay(late, key, func() {
		// 删除数据
		delete(s.Ex, key)
		// 过期时间记录
		delete(s.M, key)
	})
}

// 设置过期时间: 向Ex写数据
// exTime为过期时间(毫秒)
func (s *Server) SetExTime(key string, exTime string) error {
	//将exTime转换为数字
	exTimeNum, err := strconv.Atoi(exTime)
	if err != nil {
		return err
	}
	// 将exTime转换为过期时间戳(毫秒级)
	ex := time.Now().UnixMilli() + int64(exTimeNum)
	s.Ex[key] = ex
	return nil
}

参考:https://github.com/dawnzzz/simple-redis

redis 有那些内存淘汰策略?常用的是什么,为什么?

noeviction: 不处理

这种在内存资源耗尽的时候写会报错!

lru: 未使用时间最久的key

原理: 使用一个队列进行维护,如果一个key被使用那么就将这个key放在对头,如果队列满了(空间满了)再加入数据就会从队尾淘汰一个数据,再将新数据加到对头

这种是最常用的,因为一个key在一段时间内没有被使用那么它在后面被使用的概率就会比较低.

lfu: 使用次数最少的key

原理: 统计每一个key的使用次数,需要淘汰的时候,淘汰使用次数最少的key.
这个有一个问题就是新key加进来使用次数比较低,在内存淘汰的时候新可以容易被淘汰掉

random: 随机key

就是随机挑选一个key进行淘汰.
这个基本很少用

volatile与allkeys的区别

volatile就是淘汰设置了过期时间的key
allkeys就是淘汰所有的key

根据实际需求选择合适的内存淘汰机制,一般会使用volatile进行淘汰,因为没设置过期时间一般默认为需要长期缓存的数据.

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

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

相关文章

VMware:如何在CentOS7上开启22端口

打开虚拟机&#xff1a;【编辑】【虚拟机网络设置】 其中填入的虚拟机IP地址是虚拟机中centos的IP地址&#xff0c;虚拟机端口为需要映射的centos端口 配置好之后保存&#xff0c;打开宿主机 win cmd telnet 192.168.1.26 22 如果出现上述窗口&#xff0c;则说明已经成功开放…

项目中使用AntV L7地图(五)添加飞线

项目中使用AntV L7地图&#xff0c;添加 飞线 文档地址&#xff1a;https://l7.antv.antgroup.com/zh/examples/line/animate/#trip_animate 一、初始化地图 使用的地图文件为四川地图JSON&#xff0c;下载地址:https://datav.aliyun.com/portal/school/atlas/area_selector#&…

基于FPGA的智能电子密码指纹锁(开源全免)

基于FPGA的智能电子密码指纹锁 一、功能描述硬件资源需求 二、整体框架知识准备AS608指纹模块4*4数字键盘模块 三、Verilog代码实现以及仿真验证1.AS608_data模块2.check_hand模块3.four_four_key模块4.check_mima模块5.change_mima模块6.seg_ctrl模块7.uart_top模块8.key_debo…

【Vue2+Element-ui】el-dialog宽度适配

1、不适配问题 分辨率100%-页面 分辨率150%-页面 在项目中&#xff0c;我开发分辨率一直是100%&#xff0c;但是客户使用的分辨率不相同&#xff0c;所以宽度要适配 2、解决-封装mixins.js 1)、封装的mixins 我将宽度设置成动态的&#xff0c;因为我的项目中需求不同。 expor…

css矩形样式,两边圆形

废话不多说&#xff0c;代码如下&#xff0c;直接拷贝即可使用&#xff1a; index.vue文件 <template><view class"wrap"><view class"tabs"><view class"tab active"><view class"name">标签</view…

【OpenCV】图像阈值

简单阈值法 此方法是直截了当的。如果像素值大于阈值&#xff0c;则会被赋为一个值&#xff08;可能为白色&#xff09;&#xff0c;否则会赋为另一个值&#xff08;可能为黑色&#xff09;。使用的函数是 cv.threshold。第一个参数是源图像&#xff0c;它应该是灰度图像。第二…

使用微信小程序调用飞桨PaddleX平台自行训练的模型——微信小程序用训练的牡丹花模型Demo测试

&#x1f3bc;个人主页&#xff1a;【Y小夜】 &#x1f60e;作者简介&#xff1a;一位双非学校的大二学生&#xff0c;编程爱好者&#xff0c; 专注于基础和实战分享&#xff0c;欢迎私信咨询&#xff01; &#x1f386;入门专栏&#xff1a;&#x1f387;【MySQL&#xff0…

Wordpress设置固定链接形式后出现404错误

比如固定连接设置为 /archives/%post_id%.html 这种形式&#xff0c;看起来比较舒服。对搜索引擎也友好。 出现404需要设置伪静态

JavaWeb学习--cookie和session,实现登录的记住我和验证码功能

目录 &#xff08;一&#xff09;Cookie概述 1.什么叫Cookie 2.Cookie规范 3.Cookie的覆盖 4.cookie的最大存活时间 ​​​​​​&#xff08;Cookie的生命&#xff09; &#xff08;二&#xff09; Cookie的API 1.创建Cookie&#xff1a;new 构造方法 2.保存到客户端浏…

Linux网络测试指令

Ping Ping命令是一个网络工具&#xff0c;用于测试主机之间的可达性。它通过发送ICMP&#xff08;Internet Control Message Protocol&#xff09;回声请求消息到目标主机&#xff0c;并等待接收ICMP回声应答消息来判断目标是否可达以及测量往返时间。Ping命令对于诊断网络连接…

【伪代码】数据结构-期末复习 线性表

目录 例1 矩阵相乘 线性表 2.1 线性表的类型定义 例2-1 求并集 LALA∪LB 例2-2 有序表归并 2. 2 线性表的顺序表示和实现 1&#xff0e;构造空表 2&#xff0e;插入 3&#xff0e;删除 4&#xff0e;定位 顺序表的优点&#xff1a; 顺序表的缺点&#xff1a; 例…

<C++11> 智能指针

目录 前言 C11和boost中智能指针的关系 一、智能指针的使用及原理 1. 智能指针介绍 2. 智能指针的使用 3. 智能指针的原理 二、C中的智能指针 1. auto_ptr 2. unique_ptr 3. shared_ptr std::shared_ptr的基本设计 shared_ptr的线程安全问题 定制删除器 4. weak_ptr shared_pt…

书生实战营第四期-进阶岛第六关-MindSearch 快速部署

一、开发环境配置 1、打开codespace主页&#xff0c;选择Blank模板进行创建 Codespaces 2、创建conda环境隔离并安装依赖 conda create -n mindsearch python3.10 -y conda init 因为是新建的codespace&#xff0c;在第一次创建conda环境时&#xff0c;需要conda init 然后再…

ViT学习笔记(二) Patch+Position Embedding阶段的详细推演与理解

我认为讲得最好的一个文章&#xff1a;Vision Transformer详解-CSDN博客 有很多文章&#xff0c;自己并没有完全正确理解。 我的笔记&#xff0c;以ViT的标准应用为例&#xff1a; • 输入图像&#xff1a;输入图像的尺寸是224x224&#xff0c;且是RGB图像&#xff0c;因此输…

JS听到了强运的回响

正则表达式 介绍 正则表达式是用于匹配字符串中字符组合的模式&#xff0c;在JS中&#xff0c;正则表达式也是对象 通常用来查找&#xff0c;替换那些符合正则表达式的文本 就是筛选出符合条件的一类人 比如说 有人喜欢玩艾斯爱慕&#xff0c;那他喜欢的就是这一类人&…

工业4.0下的IT网络与OT网络

https://zhuanlan.zhihu.com/p/498984722 随着“中国制造2025”的深入推进&#xff0c;制药行业以手工为主的传统生产方式正在被以“工业4.0 ”为核心的自动化生产方式逐步替代。 为了实现生产自动化&#xff0c;很多制药企业都引入了由PLC&#xff08;可编程逻辑控制器 &am…

C# MVVM 牛牛的实现依赖注入和MVVM绑定(DependencyInjection+CommunityToolkit)

这段时间在网上发现搜索MVVM数据绑定时&#xff0c;发现很多都是最基本的数据绑定&#xff0c;完全没有考虑依赖注入的问题&#xff0c;这里实现一下我们的方法&#xff0c;让我们的数据绑定和依赖注入都变得简单起来。 安装资源包 首先我们要下载一下资源包DependencyInject…

gitee常见命令

目录 1.本地分支重命名 2.更新远程仓库分支 3.为当前分支设置远程跟踪分支 4.撤销已经push远程的代码 5.idea->gitee的‘还原提交’ 需要和本地当前的代码解决冲突 解决冲突 本地工作区的差异代码显示 本地commit和push远程 6.idea->gitee的‘将当前分支重置到此…

【JAVA高级篇教学】第二篇:使用 Redisson 实现高效限流机制

在高并发系统中&#xff0c;限流是一项非常重要的技术手段&#xff0c;用于保护后端服务&#xff0c;防止因流量过大导致系统崩溃。本文将详细介绍如何使用 Redisson 提供的 RRateLimiter 实现分布式限流&#xff0c;以及其原理、使用场景和完整代码示例。 目录 一、什么是限流…

Python画泰勒图

1. 安装画泰勒图的库 pip install SkillMetricsSkillMetrics库在图的设置细节&#xff08;模型标记符号、colorbar&#xff09;有很多不足&#xff0c;比如无法按颜色区分每个散点。 注意&#xff01;&#xff01;&#xff01; 提前算好数据的标准差、相关系数和中心化均方根…