Springboot基于Redis的高性能分布式缓存数据库的实现与实例
一、引言
在现代的分布式系统和高并发应用中,缓存机制显得尤为重要。Redis作为一种开源(BSD许可)的内存键值存储,因其高性能、丰富的数据结构和多样化的应用场景,成为开发者们的首选。在这篇博客中,我们将详细介绍Redis的背景与概念,探讨其应用场景,并指导在Linux环境下安装Redis以及集成至Springboot项目中使用。
二、 Redis简介与概念
Redis简介
Redis(Remote Dictionary Server)是由Salvatore Sanfilippo于2009年开发的开源内存数据库。与传统的关系型数据库不同,Redis是一个内存中的数据结构存储系统,它不仅支持键-值数据,还支持丰富的数据结构如字符串(String)、哈希(Hash)、列表(List)、集合(Set)、有序集合(Sorted Set)等。
Redis的特点
- 高性能:Redis数据存储在内存中,读写速度极快。
- 多样的数据结构:支持字符串、哈希、集合、列表、有序集合等多种数据结构。
- 持久化:提供RDB快照和AOF两种持久化机制。
- 主从复制:支持数据复制,提供高可用性。
- 分布式特性:通过Redis Cluster实现数据的自动分片与高可用性。
三、 Redis的应用场景
缓存
Redis的高读写性能使其成为缓存解决方案的首选。将频繁访问的数据缓存起来,可以极大地提高系统的响应速度和吞吐量。如网站页面缓存、数据库查询结果缓存等。
会话存储
在分布式系统中,使用Redis存储用户会话信息可以确保跨服务器的一致性,提高系统规模化处理能力。
消息队列
Redis的列表(List)和发布/订阅(Pub/Sub)功能使其可以用来构建消息队列,高效处理异步任务。
分布式锁
利用Redis的SETNX(SET if Not eXists) 命令可以实现分布式锁,确保多个客户端之间操作的互斥性。
计数器
Redis的原子操作特性非常适合构建各种计数器,如页面浏览量、商品库存等。
四、 Linux环境下安装Redis
#更新系统包管理器
sudo apt-get update#安装构建工具和依赖,Redis是用C语言编写的,所以我们首先需要安装编译Redis所需的工具和依赖包。sudo apt-get install build-essential tcl#下载Redis源码
mkdir /usr/local/rediscd rediswget http://download.redis.io/releases/redis-6.2.6.tar.gz#解压并编译tar xzf redis-6.2.6.tar.gz
cd redis-6.2.6
make#运行测试make test #安装Redis
sudo make install#修改配置文件,
vi ./redis.conf#添加或修改以下配置
bind 127.0.0.1 前面加#注释或者将127.0.0.1修改为0.0.0.0 哪些IP可访问
daemonize no修改为yes 后台启动
requirepass 去掉前面的#号,修改后面内容 为登录密码
protected-mode yes 修改为 no 可远程连接#启动Redis服务器 默认情况下,Redis服务器会在端口6379上启动。./bin/redis-server ../redis.conf
#启动Redis客户端,打开另一终端窗口,使用redis-cli连接到Redis服务器。./bin/redis-cli
简单操作示例
# 设置键值
set mykey "Hello, Redis!"
# 获取键值
get mykey
五、Springboot整合Redis
1.添加核心依赖
<dependency><groupid>org.springframework.boot</groupid><artifactid>spring-boot-starter-data-redis</artifactid>
</dependency>
2.Redis的yml配置设置
# 端口
server:port: 8008
spring:application:# 应用名称name: spring-boot-redis# redis 配置redis:host: 10.98.2.33#超时连接timeout: 1000msjedis:pool:#最大连接数据库连接数,设 0 为没有限制max-active: 8#最大等待连接中的数量,设 0 为没有限制max-idle: 8#最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。max-wait: -1ms#最小等待连接中的数量,设 0 为没有限制min-idle: 0
3.编写测试用例
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;
@RestController
@RequestMapping("/redis")
public class RedisController {@Resourceprivate StringRedisTemplate stringRedisTemplate ;@RequestMapping("/setGet")public String setGet (){stringRedisTemplate.opsForValue().set("user1","smile");return stringRedisTemplate.opsForValue().get("user1") ;}@Resourceprivate RedisTemplate redisTemplate ;/*** 设置 Key 的有效期 10 秒*/@RequestMapping("/setKeyTime")public String setKeyTime (){redisTemplate.opsForValue().set("timeKey","timeValue",10, TimeUnit.SECONDS);return "success" ;}@RequestMapping("/getTimeKey")public String getTimeKey (){// 这里 Key 过期后,返回的是字符串 'null'return String.valueOf(redisTemplate.opsForValue().get("timeKey")) ;}
}
4.自定义序列化配置类
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.io.Serializable;
/*** Redis 配置*/
@Configuration
public class RedisConfig {private static final Logger LOGGER = LoggerFactory.getLogger(RedisConfig.class) ;/*** 序列化配置*/@Beanpublic RedisTemplate<string, serializable> redisTemplate(LettuceConnectionFactory redisConnectionFactory) {LOGGER.info("RedisConfig == >> redisTemplate ");RedisTemplate<string, serializable> template = new RedisTemplate<>();template.setKeySerializer(new StringRedisSerializer());template.setValueSerializer(new GenericJackson2JsonRedisSerializer());template.setConnectionFactory(redisConnectionFactory);return template;}
}
5.序列化配置类使用测试
import com.boot.redis.entity.User;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
@RestController
@RequestMapping("/User")
public class UserController {@Resourceprivate RedisTemplate redisTemplate ;@RequestMapping("/setUser")public String setUser (){User user = new User() ;user.setName("cicada");user.setAge(22);List<string> list = new ArrayList<>() ;list.add("小学");list.add("初中");list.add("高中");list.add("大学");user.setEducation(list);redisTemplate.opsForValue().set("userInfo",user);return "success" ;}@RequestMapping("/getUser")public User getUser (){return (User)redisTemplate.opsForValue().get("userInfo") ;}
}
结论:
Redis作为一种高性能的内存数据库,不仅适用于缓存场景,还可以应用于会话存储、消息队列、分布式锁和计数器等多个方面。通过本文的介绍,相信您对Redis有了一个全面的了解,并能够在Linux环境中成功安装和使用Redis。在实际项目中,合理使用Redis,可以显著提高系统的性能和可靠性。
相关文章:
Springboot基于Redis的高性能分布式缓存数据库的实现与实例
一、引言 在现代的分布式系统和高并发应用中,缓存机制显得尤为重要。Redis作为一种开源(BSD许可)的内存键值存储,因其高性能、丰富的数据结构和多样化的应用场景,成为开发者们的首选。在这篇博客中,我们将…...
防止多次点击,vue的按钮上做简易的防抖节流处理
话不多说,上个视频,看看是不是你要的效果 防抖节流 1.创建一个directive.js // directive.js export default {install(Vue) {// 防重复点击(指令实现)Vue.directive(repeatClick, {inserted(el, binding) {el.addEventListener(click, () > {if (!el.disabled) {el.disabl…...
云计算【第一阶段(21)】Linux引导过程与服务控制
目录 一、linux操作系统引导过程 1.1、开机自检 1.2、MBR引导 1.3、GRUB菜单 1.4、加载 Linux 内核 1.5、init进程初始化 1.6、简述总结 1.7、初始化进程centos 6和7的区别 二、排除启动类故障 2.1、修复MBR扇区故障 2.1.1、 实验 2.2、修复grub引导故障 2.2.1、实…...
Google 发布最新开放大语言模型 Gemma 2,现已登陆 Hugging Face Hub
Google 发布了最新的开放大语言模型 Gemma 2,我们非常高兴与 Google 合作,确保其在 Hugging Face 生态系统中的最佳集成。你可以在 Hub 上找到 4 个开源模型 (2 个基础模型和 2 个微调模型) 。发布的功能和集成包括: Hub 上的模型https://hf.…...
智能分析赋能等保:大数据技术在安全审计记录中的应用
随着信息技术的飞速发展,大数据技术在各行各业中的应用愈发广泛,特别是在网络安全领域,大数据技术为安全审计记录提供了强有力的支撑。本文将深入探讨智能分析如何赋能等保(等级保护),以及大数据技术在安全…...
Django中,update_or_create()
在Django中,可以使用update_or_create()方法来更新现有记录或创建新记录。该方法接受一个字典作为参数,用于指定要更新或创建的字段和对应的值。 update_or_create()方法的语法如下: 代码语言:python obj, created Model.obje…...
每日一学(1)
目录 1、ConCurrentHashMap为什么不允许key为null? 2、ThreadLocal会出现内存泄露吗? 3、AQS理解 4、lock 和 synchronized的区别 1、ConCurrentHashMap为什么不允许key为null? 底层 putVal方法 中 如果key || value为空 抛出…...
SpringMVC(1)——入门程序+流程分析
MVC都是哪三层?在Spring里面分别对应什么?SpringMVC的架构是什么? 我们使用Spring开发JavaWeb项目,一般都是BS架构,也就是Browser(浏览器)-Server(服务器)架构 这种架构…...
成绩发布背后:老师的无奈与痛点
在教育的广阔天地里,教师这一角色承载着无数的期望与责任。他们不仅是知识的传播者,更是学生心灵的引路人。而对于班主任老师来说,他们的角色更加多元,他们不仅是老师,还必须是“妈妈”。除了像其他老师一样备课、上课…...
MySQL 索引之外的相关查询优化总结
在这之前先说明几个概念: 1、驱动表和被驱动表:驱动表是主表,被驱动表是从表、非驱动表。驱动表和被驱动表并非根据 from 后面表名的先后顺序而确定,而是根据 explain 语句查询得到的顺序确定;展示在前面的是驱动表&am…...
EE trade:贵金属投资的优点及缺点
贵金属(如黄金、白银、铂金和钯金)一直以来都是重要的投资和避险工具。它们具有独特的物理和化学特性,广泛应用于各种行业,同时也被视为财富储备。在进行贵金属投资时,了解其优点和缺点对于做出明智的投资决策至关重要。 一、贵金属投资的优…...
python工作目录与文件目录
工作目录 文件目录:文件所在的目录 工作目录:执行python命令所在的目录 D:. | main.py | ---data | data.txt | ---model | | model.py | | train.py | | __init__.py | | | ---nlp | | | bert.py | …...
可信和可解释的大语言模型推理-RoG
大型语言模型(LLM)在复杂任务中表现出令人印象深刻的推理能力。然而,LLM在推理过程中缺乏最新的知识和经验,这可能导致不正确的推理过程,降低他们的表现和可信度。知识图谱(Knowledge graphs, KGs)以结构化的形式存储了…...
秋招季的策略与行动指南:提前布局,高效备战,精准出击
6月即将进入尾声,一年一度的秋季招聘季正在热火进行中。对于即将毕业的学生和寻求职业发展的职场人士来说,秋招是一个不容错过的黄金时期。 秋招的序幕通常在6月至9月间拉开,名企们纷纷开启网申的大门。在此期间,求职备战是一个系…...
Java并发编程-wait与notify详解及案例实战
文章目录 概述wait()notify()作用注意事项用wait与notify手写一个内存队列wait与notify的底层原理:monitor以及wait_setMonitor(监视器)Wait Set(等待集合)Wait() 原理Notify() / NotifyAll() 原理注意事项wait与notify在代码中使用时的注意事项总结案例实战:基于wait与not…...
204.贪心算法:分发饼干(力扣)
以下来源于代码随想录 class Solution { public:int findContentChildren(vector<int>& g, vector<int>& s) {// 对孩子的胃口进行排序sort(g.begin(), g.end());// 对饼干的尺寸进行排序sort(s.begin(), s.end());int index s.size() - 1; // 从最大的饼…...
AI奥林匹克竞赛:Claude-3.5-Sonnet对决GPT-4o,谁是最聪明的AI?
目录 实验设置 评估对象 评估方法 结果与分析 针对学科的细粒度分析 GPT-4o vs. Claude-3.5-Sonnet GPT-4V vs. Gemini-1.5-Pro 结论 AI技术日新月异,Anthropic公司最新发布的Claude-3.5-Sonnet因在知识型推理、数学推理、编程任务及视觉推理等任务上设立新…...
【C++】const修饰成员函数
const修饰成员函数 常函数: 成员函数后加const后我们称为这个函数为常函数 常函数内不可以修改成员属性 成员属性声明时加关键字mutable后,在常函数中依然可以修改 class Animal { public:void fun1(){//这是一个普通的成员函数 }void fun2…...
基于模糊神经网络的时间序列预测(以hopkinsirandeath数据集为例,MATLAB)
模糊神经网络从提出发展到今天,主要有三种形式:算术神经网络、逻辑模糊神经网络和混合模糊神经网络。算术神经网络是最基本的,它主要是对输入量进行模糊化,且网络结构中的权重也是模糊权重;逻辑模糊神经网络的主要特点是模糊权值可…...
Java web应用性能分析之【prometheus监控K8s指标说明】
常规k8s的监控指标 单独 1、集群维度 集群状态集群节点数节点状态(正常、不可达、未知)节点的资源使用率(CPU、内存、IO等) 2、应用维度 应用响应时间 应用的错误率 应用的请求量 3、系统和集群组件维度 API服务器状态控…...
使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...
Ubuntu系统下交叉编译openssl
一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...
应用升级/灾备测试时使用guarantee 闪回点迅速回退
1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...
可靠性+灵活性:电力载波技术在楼宇自控中的核心价值
可靠性灵活性:电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中,电力载波技术(PLC)凭借其独特的优势,正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据,无需额外布…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序
一、开发准备 环境搭建: 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 项目创建: File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...
在四层代理中还原真实客户端ngx_stream_realip_module
一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡(如 HAProxy、AWS NLB、阿里 SLB)发起上游连接时,将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后,ngx_stream_realip_module 从中提取原始信息…...
苍穹外卖--缓存菜品
1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据,减少数据库查询操作。 缓存逻辑分析: ①每个分类下的菜品保持一份缓存数据…...
《基于Apache Flink的流处理》笔记
思维导图 1-3 章 4-7章 8-11 章 参考资料 源码: https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...
JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...
QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...
