Redis学习第九天

news2024/11/25 23:26:54

今天是Jedis!作者的Redis在游戏本上,但是Java的IDEA总是下载不了,所以只能作为概念听一听了,目前无法做到实操。

Jedis概念

Jedis实操

首先要保证redis的服务器开启,然后引入jedis依赖,最后通过服务器的IP和端口创建一个Jedis类的对象。该对象能够使用redis的基本操作。

jedis.ping()输出PONG字符串,就说明连接成功。还有其他指令:

对于事务操作,需要使用Transaction类的对象,接收jedis.multi()方法的返回值。

Jedis连接池

在数据库相关操作中,可以使用连接池连接多个资源。在频繁使用数据库进行操作时,可以直接从连接池中获取数据,用完该资源后不关闭而是直接归还到池中,无需每次都做新的申请。使用JedisPoolConfig对象管理配置,最终的连接池类是JedisPool。

不设置的时候是有默认值的!使用pool.getResource对象

注意列表对象的lpush是不断把新的元素添加到链表的头部rpush是不断把新元素添加到链表的尾部建议平常使用rpush,这个不同决定了lindex决定的元素(没有rindex)。

有序集合需要使用score分数进行排序!

Redis与Mysql整合

通常在传统数据库的基础上通过使用内存型数据库完成缓存操作。通常存放热点数据,如果redis里有,就从redis上读取数据。这就是缓存器的作用,与主存-CPU之间的cache原理一致。

首先在容器中安装mysql环境,比较简单作者不展示。就是需要进行一些权限、密码等配置。

期间老师的思想非常值得学习:

        Jedis连接池只需要执行一次,所以把所有的JedisPool创建语句放在static{ }静态代码块中。在Java中,静态代码块(也称为静态初始化器)是在类加载到JVM时执行的,且只执行一次。静态代码块主要用于初始化静态成员变量。这样设计的好处是:

  1. 效率:避免每次需要Jedis对象时都重新配置和创建一个新的JedisPool
  2. 资源管理:一个应用中通常只需要一个JedisPool实例,这样可以更有效地复用和管理Redis连接。

其实最终的理念就是上图。首先判断缓存中是否有数据,这是通过查询redis得到的。老师的代码还可以改进一下,作者认为redis数据是会大量复现的(否则也不会使用redis),所以最好是首先判断if (product != null),这样的可以更快地对redis需要复现的数据进行读取。

还需要有一些注意的点:上面的判断/读写代码只是针对于商品product的。底层mysql存储的是product,redis存储的也是hash表,加上前缀product:id表明键的信息。

是否进行其他操作是需要通过如上图CasheDemo类的方法调度。可以通过ID获取,也可以定义其他类,把读取product类的方法改成findProductByID()就好。而实现这个find方法需要在CacheDemo类中定义好两类数据库的存取操作,标注为静态方法。

还可以定义存储的方法,上面是find,不涉及到mysql的存储,但是有可能涉及到redis的存储。


Redis缓存优化

缓存穿透

缓存里没有,数据库里也没有,且有大量请求发送。

数据不在缓存中,需要经过mysql数据库将数据返回给缓存,并最终存储在缓存中。但是,缓存如果一直没有相关的数据(比如id=-1这样的,有可能是恶意攻击,也有可能处于高并发过程),这时缓存就没有任何作用,因为没有有用的数据直接从缓存中可以读到,大量数据在缓存中查不到。

解决方案是:即使没有这个数据,系统也会分配一个这样的空对象null回应,并给到缓存中。相当于给缓存一个挡箭牌,面对大量错误数据可以不打扰Mysql数据库,直接返回一个空对象“敷衍过去”。因为这样大量快速的数据往往是相同的,所以这种方法还是比较有效的。

当Mysql也没有查到数据时,创建一个假的数据作为挡箭牌给到redis中。 

缓存雪崩

之前没有考虑到缓存的有效期问题,有效期是一个必选项!存的时候就要想好它什么时候会过期,否则大量数据持续有效、积累会导致内存溢出

并且也不能让大量数据的有效期一致,否则大量数据过期和大量数据存储同时进行时,很容易导致缓存雪崩。缓存雪崩就是缓存出现问题了,还有Redis宕机、机房停电等事件能够导致缓存雪崩:

Redis宕机可以通过集群解决,机房停电可以通过云端部署异地机房减少其影响程度。

利用随机数避免大量数据同一时刻过期。

Redis限流

某一时间段只允许一定次数的请求

本质上就是两个条件,一个是一定时间内,一个是小于某一次数。


Redis整合MySql主从集群

Mysql主从集群

对于Mysql集群,其实都是类似的配置过程。首先下载镜像,然后分别创建主、从服务器的配置文件,主要是配置服务器id和日志文件的位置。然后就可以创建容器并运行。然后分别对主从服务器授予远程访问权限:

开始配置关系:首先进入从服务器:

一定要首先尝试连接主Mysql服务器!否则会出现错误。尝试完之后就可以真正地进行操作了;

配置好状态之后,所有主服务器的写操作结果都会被自动导入从服务器中。

主从集群应用

在实际应用中如何使用主从集群呢?可以在建立连接时分清是与主服务器连接执行写操作还是与从服务器连接执行读操作。在本课程中,使用isWrite作为读写标志,在getConnection()中加上这个参数,如果isWrite=true,就把原来的url换成主服务器的地址;反之,换成从服务器的地址。对于多个从服务器甚至多个主从集群,可以考虑使用负载均衡和连接池解决。

负载均衡(Load Balancing)

负载均衡是分发网络或应用程序流量的过程,它在多个服务器(通常被称为后端或应用服务器)之间有效地分配工作负载。负载均衡的目的是优化资源使用,最大化吞吐量,最小化响应时间,同时确保无一单一服务器因为过度的工作负载而崩溃。

意义

  1. 提升性能: 通过分散处理和网络交通,负载均衡有助于提高响应时间和整体系统可靠性。
  2. 避免故障: 通过将流量分散到多个服务器,它可以防止单个服务器的过载,从而增加系统的可用性和稳定性。
  3. 扩展性: 它允许你简单地增加更多的服务器以处理更大的流量和工作负载。
  4. 灵活性和可靠性: 如果一个服务器崩溃或进行维护,流量将被重新定向到其他服务器。

应用

  • 网站和云应用:对于接收大量流量的高流量网站和应用,负载均衡有助于分散流量,从而保持网站的性能和响应时间。
  • 数据库:数据库的负载均衡可以确保查询分发得当,优化数据库性能。

负载均衡策略

轮询(Round Robin):

  • 应用场景: 适用于所有服务器处理能力大致相等的情况。
  • 优点: 简单,不需要复杂的算法实现。
  • 代码示例(基于本课程的isWrite标志): 
public Connection getConnection(boolean isWrite) {
    if (isWrite) {
        // 连接到主服务器
        return connectToUrl(masterUrl);
    } else {
        // 负载均衡:轮询连接到从服务器
        currentIndex = (currentIndex + 1) % slaveUrls.length;
        return connectToUrl(slaveUrls[currentIndex]);
    }
}

像不像计数器?currentIndex作者盲猜是静态变量,每次加1,实现无差别循环轮转。 

随机(Random):

  • 应用场景: 适用于服务器处理能力大致相等,请求处理时间不固定的场景。
  • 优点: 实现简单,不需要记录状态信息。
  • 代码示例:
public Connection getRandomConnection() {
    int index = new Random().nextInt(slaveUrls.length);
    return connectToUrl(slaveUrls[index]);
}

权重(Weighted):

  • 应用场景: 适用于不同服务器的处理能力不同的情况。
  • 优点: 能够更好地利用高性能的服务器。
  • 代码示例:
public Connection getWeightedConnection() {
    int totalWeights = 10; // 假设总权重为10
    int randomWeight = new Random().nextInt(totalWeights);
    if (randomWeight < 3) return connectToUrl(slaveUrls[0]); // 权重为3
    else if (randomWeight < 7) return connectToUrl(slaveUrls[1]); // 权重为4
    else return connectToUrl(slaveUrls[2]); // 权重为3
}

其实这个权重就是用来进行概率分配的,权重越大,其被选中的概率越大!

最少连接 (Least Connections):

概念

  • 这种负载均衡策略主要是基于每个服务器当前的连接数来分配请求。
  • 系统会将新的请求分配给当前连接数最少的服务器。

应用场景

  • 当所有服务器的硬件配置大致相同,但每个请求处理时间不一致时,最少连接策略能够更有效地分发请求。

优点

  • 确保了每个服务器的工作负载大致相等,避免了某个服务器过载而其他服务器空闲的情况。

代码示例

假设每个服务器的连接数都存储在一个数组或其他数据结构中:

public Connection getLeastConnectionsConnection() {
    int index = findServerWithLeastConnections(); // 寻找当前连接数最少的服务器
    return connectToUrl(slaveUrls[index]);
}

IP Hash:

  • 应用场景: 适用于需要会话保持的场景。即用户与服务器交互的多个请求之间保持某种状态或数据的持续性。
  • 优点: 相同IP的请求总是发到同一个服务器,可以保持用户的会话状态。
  • 代码示例:
public Connection getIPHashConnection(String clientIP) {
    int hash = clientIP.hashCode() % slaveUrls.length;
    return connectToUrl(slaveUrls[hash]);
}

在使用多个服务器进行负载均衡时,会话保持尤为重要,因为不同的用户请求可能被路由到不同的服务器。如果一个服务器不知道另一个服务器上的会话状态,那么用户可能会在每个请求之间失去会话状态。为了避免这种情况,负载均衡器通常提供会话持久性功能确保来自同一用户的所有请求都被路由到同一服务器,从而提供更有个性化和便捷的用户体验。

最低延迟 (Least Latency):

概念

  • 最低延迟策略是根据每个服务器的响应时间来分配请求。
  • 系统会将请求分发给当前响应时间最短的服务器

应用场景

  • 当服务器硬件配置不同,或者网络延迟差异较大时,最低延迟策略更为合适。

优点

  • 确保了用户请求总是被发送到响应时间最短的服务器,优化了用户的访问体验。

代码示例

public Connection getLeastLatencyConnection() {
    int index = findServerWithLeastLatency(); // 寻找当前延迟时间最短的服务器
    return connectToUrl(slaveUrls[index]);
}

每种负载均衡策略都有自己的优缺点,选择哪种策略取决于具体的应用场景和需求。在实际应用中,还可能会使用这些策略的组合来实现更优的负载均衡效果。


 Redis整合Lua脚本

其实就是脚本的作用:实现重复性工作,减少人力成本

redis本质上就是对键和值的处理。对lua脚本中传入键、值就是为了更好地处理redis中的数据。

Springboot整合Redis

主要还是通过Spring的API:RedisTemplate支持所有Redis原生的API。与Jedis的方法有所不同,只是稍微增加了对于面向对象风格的改进,如;

redisTemplate.opsForValue().set(key,value);

这个API调用的方法都是以ops开头,ForValue表示它要操作的数据类型是String字符串,先通过方法确定操作数据的类型,再调用相应的set()/get()函数。

首先要通过Resource注入属性值。

会话仓库!SpringSession:只要把Session放进来,就能自动存到Redis里。

之前的session都是单体,所以只需要存储在一台机器上的特定位置。但是现在往往都使用集群,一旦session还只存储在某一台服务器上,同一个用户很容易下一次就访问到别的机器上了,所以需要一个统一存储Session的仓库,这个仓库可以是Redis/MongoDB/JDBC,宗旨就是快!

在配置以上依赖后,再在Controller中使用Session就完全不一样了,它会自动读取配置文件连接的Redis信息,最终存储在Redis中。

这样session就会被自动存储在Redis中,用多级目录存储,防止存储冲突。

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

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

相关文章

【学习笔记】深度学习分布式系统

深度学习分布式系统 前言1. 数据并行&#xff1a;参数服务器2. 流水线并行&#xff1a;GPipe3. 张量并行&#xff1a;Megatron LM4. 切片并行&#xff1a;ZeRO5. 异步分布式&#xff1a;PATHWAYS总结参考链接 前言 最近跟着李沐老师的视频学习了深度学习分布式系统的发展。这里…

作用域 CSS 回来了

几年前&#xff0c;消失的作用域 CSS&#xff0c;如今它回来了&#xff0c;而且比以前的版本要好得多。 更好的是&#xff0c;W3C规范基本稳定&#xff0c;现在Chrome中已经有一个工作原型。我们只需要社区稍微关注一下&#xff0c;引诱其他浏览器构建它们的实现&#xff0c;并…

嵌入式数据库sqlite3基本命令操作基础(05)

前言 数据在实际工作中应用非常广泛&#xff0c;数据库的产品也比较多&#xff0c;oracle、DB2、SQL2000、mySQL&#xff1b;基于嵌入式linux的数据库主要有SQLite, Firebird, Berkeley DB, eXtremeDB。 本文主要讲解数据库SQLite&#xff0c;通过这个开源的小型的嵌入式数据…

MySQL5.7高级函数:JSON_ARRAYAGG和JSON_OBJECT的使用

前置准备 DROP TABLE IF EXISTS t_user; CREATE TABLE t_user (id bigint(20) NOT NULL,name varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci …

Unity - 实践: Metallic流程贴图 转 Specular流程贴图

文章目录 目的Metallic Flow - SP - 输出输出的 MRA (MGA) 贴图 Metallic->Specular (根据教程一步一步实践)1. Base color Metallic -> Diffuse2. Base color Metallic -> Specular3. Roughness -> Glossiness输出贴图&#xff0c;在 unity 中展示&#xff1a;M…

内网测速工具-LibreSpeed

github链接&#xff1a; https://github.com/librespeed/speedtest-android

如何系列 如何使用OpenCV进行图像操作

文章目录 简介集成代码示例加载和显示图像编辑和保存图像边缘检测图片属性图像旋转图像缩放图像拼接颜色空间转换图像模糊平滑化腐蚀和膨胀直方图均衡化图像分割模板匹配图像特征提取图像拟合图像标注轮廓检测背景减除图像混合颜色分割图像旋转裁剪在图像上写文字检测和裁剪人脸…

大模型Tuning分类

类型总结 微调&#xff08;Fine-tunning&#xff09; 语言模型的参数需要一起参与梯度更新 轻量微调&#xff08;lightweight fine-tunning&#xff09; 冻结了大部分预训练参数&#xff0c;仅添加任务层&#xff0c;语言模型层参数不变 适配器微调 &#xff08;Adapter-t…

Java项目-文件搜索工具

目录 项目背景 项目效果 SQLite的下载安装 使用JDBC操作SQLite 第三方库pinyin4j pinyin4j的具体使用 封装pinyin4j 数据库的设计 创建实体类 实现DBUtil 封装FileDao 设计scan方法 多线程扫描 周期性扫描 控制台版本的客户端 图形化界面 设计图形化界面 项目…

PyTorch - 模型训练损失 (Loss) NaN 问题的解决方案

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/133378367 在模型训练中&#xff0c;如果出现 NaN 的问题&#xff0c;严重影响 Loss 的反传过程&#xff0c;因此&#xff0c;需要加入一些微小值…

什么是 Spring Boot?与传统 Spring 框架的区别

什么是 Spring Boot&#xff1f;与传统 Spring 框架的区别 引言 Spring框架是一个在Java应用程序开发中广泛使用的框架&#xff0c;它提供了一种构建企业级Java应用程序的强大方式。然而&#xff0c;Spring框架在一些方面存在复杂性和繁琐的配置&#xff0c;这促使Spring社区…

leetcode:561. 数组拆分(python3解法)

难度&#xff1a;简单 给定长度为 2n 的整数数组 nums &#xff0c;你的任务是将这些数分成 n 对, 例如 (a1, b1), (a2, b2), ..., (an, bn) &#xff0c;使得从 1 到 n 的 min(ai, bi) 总和最大。 返回该 最大总和 。 示例 1&#xff1a; 输入&#xff1a;nums [1,4,3,2] 输出…

软件设计模式系列之十八——迭代器模式

1 模式的定义 迭代器模式是一种行为型设计模式&#xff0c;它允许客户端逐个访问一个聚合对象中的元素&#xff0c;而不暴露该对象的内部表示。迭代器模式提供了一种统一的方式来遍历不同类型的集合&#xff0c;使客户端代码更加简洁和可复用。 2 举例说明 为了更好地理解迭…

护眼灯买哪种好?分享五款护眼灯

家里顶灯太暗了且高度太高&#xff0c;还是原始的LED灯&#xff0c;晚上用着眼睛都有点难受&#xff0c;还好遇到了儿童护眼灯。下面小编为大家介绍下儿童护眼灯哪个牌子好&#xff1f;什么护眼台灯比较专业 1、色温 台灯的色温也是一个需要考虑的因素&#xff0c;所谓的色温其…

数学建模常用模型

作为数学建模的编程手还掌握一些各类模型常用算法&#xff0c;数学建模评价类模型、分类模型、预测类模型比较常用的方法总结如下&#xff1a; 接下来对这些比较典型的模型进行详细进行介绍说明。 一、评价模型 在数学建模中&#xff0c;评价模型是比较基础的模型之一&#x…

云部署家里的服务器

1.固定静态ip 查看ip地址&#xff0c;en开头的 ifconfig查看路由器ip&#xff0c;via开头的 ip route修改配置文件 cd /etc/netplan/ #来到这个文件夹 sudo cp 01-network-manager-all.yaml 01-network-manager-all.yaml.bak #先备…

ChatGPT架构师:语言大模型的多模态能力、幻觉与研究经验

来源 | The Robot Brains Podcast OneFlow编译 翻译&#xff5c;宛子琳、杨婷 9月26日&#xff0c;OpenAI宣布ChatGPT新增了图片识别和语音能力&#xff0c;使得ChatGPT不仅可以进行文字交流&#xff0c;还可以给它展示图片并进行互动&#xff0c;这是一次ChatGPT向多模态进化的…

基于微信小程序的物流快递信息查询平台同城急送小程序(亮点:寄件、发票申请、在线聊天)

文章目录 前言系统主要功能&#xff1a;具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计…

css画一条0.5px的直线

【css】画一条0.5px的直线_css画一条0.5px的直线_a堅強的泡沫的博客-CSDN博客 一些用来装饰的图形&#xff0c;比如字体的前面或者后面设置图标&#xff0c;画一条线 如果要画很细很细的线&#xff0c;0.5px ,怎么画 用到css3的transform的scaleY(0.5)函数&#xff0c;对象图…

机器人中的数值优化|【七】线性搜索牛顿共轭梯度法、可信域牛顿共轭梯度法

机器人中的数值优化|【七】线性搜索牛顿共轭梯度法、可信域牛顿共轭梯度法 Line Search Newton-CG, Trust Region Newton-CG 往期回顾 机器人中的数值优化|【一】数值优化基础 机器人中的数值优化|【二】最速下降法&#xff0c;可行牛顿法的python实现&#xff0c;以Rosenbro…