Redis开发规范与性能优化(二)

news2024/11/16 0:05:47

开发规范与性能优化

3.客户端使用

1.【推荐】避免多个应用使用一个Redis示例

正例:不相干的业务拆分,公共数据库做服务化

2.【推荐】使用带有连接池的数据库,可以有效控制链接,同时提高效率,标准使用方式如代码所示

public class Main {
 
 public static void main(String[] args){
  JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
  jedisPoolConfig.setMaxTotal(5);
  jedisPoolConfig.setMaxIdle(2);
  jedisPoolConfig.setTestOnBorrow(true);
  
  JedisPool jedisPool = new JedisPool(jedisPoolConfig, "192.168.0.60", 6379, 3000, null);
  Jedis jedis = null;
  try {
   jedis = jedisPool.getResource();
   // 具体的指令
   jedis.executeCommand();
   
  } catch (Exception e) {
   log.error("op key {} error:{}", key, e);
  } finally {
   //注意这里不是关闭链接,在JedisPool模式下,Jedis会被归还给资源池
   if (jedis != null) {
    jedis.close()
   }
  }
 }
}
连接池参数含义:

在这里插入图片描述

优化建议:
  • 1.maxTotal:最大连接数,早期的版本叫maxActive实际上这个是一个很难回答的问题,
    考虑的因素比较多:
    1.1 业务希望Redis并发量
    1.2 客户端执行命令时间
    1.3 Redis资源:例如nodes(例如应用个数) * maxTotal是不能超过redis的最大连接数maxclients
    1.4 资源开销:例如虽然希望控制空闲连接(连接池此可可马上使用的连接),但是不希望因为连接池
    的频繁释放创建连接造成不必要开销

举个例子:假设

  • 1.一次命令时间(borrow|return resource + Jedis执行命令(含网络))的平均耗时约为1ms,一个链接的QPS大约是1000
  • 2.业务期望的QPS是50000那么理论上需要的资源池大小是50000 / 1000 = 50 个。但事实上这是个理论值,还要考虑到要比理论值预留一些资源,通常来讲maxTotal可以比理论值大一些。但这个值不是越大越好,一方面连接太多占用客户端和服务端资源,另一方面对于Redis这种高QPS的服务器,一个大命令的阻塞即时设置再大资源池仍然会无济于事。
优化建议:
  • 2.maxIdle和minIdle
    maxIdle实际上才是业务需要的最大连接数,maxTotal是为了给出雨量,所以maxIdle不要设置过小,否则会有new Jedis(新连接)开销
    连接池的最佳性能是maxTotal = maxIdle,这样就避免连接池伸缩带来的性能干扰,到那时如果并发量不大或者maxTotal设置过高,会导致不必要的连接资源浪费。一般推荐maxIdle可以设置为上面的业务期望QPS计算出来的理论连接数,maxTotal可以再放大一倍。minIdle()最小空闲连接数,与其说是最小空闲连接数,不如说是"至少需要保持的空闲连接数",在使用连接的过程中如果连接数超过了minIdle那么继续建立连接,如果超过了maxIdle,当超过的连接执行完业务后会慢慢被移除连接池释放掉,如果系统启动完马上就会有很多的请求过来,那么可以给redis连接池
    做预热,比如快速的创建一些redis连接,执行简单命令,类似ping(),快速地将连接池里地空闲连接提升到minIdle地数量
public class Main {

 public static void main(String[] args){
  List<Jedis> minIdleJedisList = new ArrayList<Jedis>(jedisPoolConfig.getMinIdle());
  
  for (int i = 0; i < jedisPoolConfig.getMinIdle(); i++) {
   Jedis jedis = null;
   try {
    jedis = pool.getResource();
    minIdleJedisList.add(jedis);
    jedis.ping();
   } catch(Exception e) {
    log.error(e.getMessage(), e);
   } finally {
    // 注意,这里不能马上close将连接还回连接池,
       // 否则最后连接池里只会建立1个连接
    // jedis.close();
   }
  }
  
  // 同一将预热的连接还回连接池
  for (int i = 0; i < jedisPoolConfig.getMinDile(); i++) {
   Jedis jedis = null;
   try {
    jedis = minIdleJedisList.get(i);
    // 将连接该归还回连接池
    jedis.close();
   } catch (Exception e) {
    log.error(e.getMessage(), e);
   } finally {
    
   }
  }
 }
}

3.【建议】高并发下建议客户端添加熔断功能(例如sentinel、hystrix)

4.【推荐】设置合理的密码,如有必要可以使用SSL加密访问

5.【建议】Redis对于过期键有三种清除策略:
  • 5.1 被动删除:当读/写一个已经过期的key时,会触发惰性删除策略,直接删除掉这个过期key
  • 5.2 主动删除:由于惰性删除策略无法保证冷数据被即时删除,所以Redis会定期主动淘汰一批已过期的key
  • 5.3 当前医用内存超过maxmemory限定时,触发主动清理策略

主动清理策略在Redis4.0之前以供实现了6中内存淘汰策略,在4.0之后又加了2种策略,总共8种:

  • a.针对设置了过期时间的key做处理
    a.1 volatile-ttl 在筛选时,会针对设置了过期时间的键值对,根据过期时间的先后进行删除,越早
    过期的越先被删除
    a.2 volatile-random 就像它的名称一样,在设置了过期时间的键值对种,进行随机删除
    a.3 volatile-lru 会使用LRU算法筛选设置了过期时间的键值对删除
    a.4 volatile-lfu 会使用LFU算法筛选设置了过期时间的键值对删除
  • b.针对所有的key做处理
    b.1 allkeys-random:从所有键值对中随机选择并删除数据
    b.2 allkeys-lru 使用LRU算法在所有数据中进行筛选删除
    b.3 allkeys-lfu 使用LFU算法在所有数据中进行筛选删除
  • c.不处理
    c.1 noeviction:不会剔除任何数据,拒绝所有写入操作并返回客户端错误信息error OOM command not allowed when used memory,此时Redis只相应读操作

当存在热点数据时,LRU的效率很好,但偶发性的、周期性的批量操作会导致LRU命中率急剧下降,缓存污染情况比较严重。这时使用LFU可能更好点.

根据自身业务类型,配置好maxmemory-policy(默认时noeviction)推荐使用volatile-lru.如果不设置最大内存,当Redis内存超出物理内存限制时,内存的数据会开始和磁盘产生频繁的交换(swap)会让redis的性能急剧下降。当Redis运行在主从模式时,只有主节点才会执行过期删除策略,然后把删除操作"del key"同步到从节点删除数据

LRU算法(least Recently Used,最近最少使用)
淘汰很久没有被访问过的数据,以最近一次访问时间作为参考

LFU算法(Least Frequently Used,最不经常使用)
淘汰最近一段时间被访问次数最少的数据,以次数作为参考

4.系统内核参数优化

vm.swapiness

swap对于操作系统来说比较重要,当物理内存不足时可以将一部分内存页进行swap到硬盘上,以解燃眉之急。但世界上没有免费午餐,swap空间由硬盘提供,对于需要高并发、高吞吐的应用来说,磁盘IO通常会称为系统瓶颈。在Linux中,并不是等到所有物理内存都使用完才会使用到swap,
系统参数swappniess会决定操作系统使用swap的倾向程度。swappiness的取只范围是0~100,swappiness的值越大,说明操作系统可能使用swap的概率越高,swappiness值越低,表示操作系统更加倾向于使用物理内存。swappiness的取值越大,说明操作系统可能使用swap的概率越高,越低则越倾向于使用物理内存。如果linux内核版本小于3.5 那么wappiness设置为0,这样系统宁愿swap不会oom killer(杀掉进程)
如果linux内核版本>=3.5,那么swappiness设置为1,这样系统宁愿swap也不会oom killer一般需要保证redis不会被kill掉

cat /proc/version # 查看linux内核版本
echo 1> /proc/sys/vm/swappiness
echo vm.swappiness = 1 >> /etc/sysctl.cnf

PS:OOM killer机制是指Linux操作系统发现可用内存不足时,强制杀死一些用户进程(非内核进程),来保证系统有足够的可用内存进行分配

vm.overcommit_memory(默认0)

  • 0:表示内核将检查是否有足够的可用物理内存(实际不一定用满)供应用进程使用;如果有足够的可用物理内存,内存申请允许;否则,内存申请失败,并把错误返回给应用进程
  • 1:表示内核允许分配所有的物理内存,而不管当前的内存状态如何,如果是0的化,可能导致类似fork等操作执行失败,申请不倒足够的内存空间
    Redis建议把这个值设置为1,就是为了让fork操作能够在低内存下也能执行成功
cat /proc/sys/vm/overcommit_memory
echo "vm.overcoimmit_memory=1" >> /etc/sysctl.conf
sysctl vm.overcommit_memory =1

合理设置文件句柄数。

操作系统进程试图打开一个文件(或者叫句柄),但是现在进程打开的句柄数已经达到了上限,继续打开会报错"Too many open files"

ulimit -a # 查看系统文件句柄数,看open files选项
ulimt -n 65535 # 设置系统文件句柄数

慢查询日志:slowlog

Redis满日志命令说明

  • config get slow* #查看有关满日志的配置信息

  • config set slowlog-log-slower-than 20000 #设置满日志使用时间阈值,此处为20毫秒,即超过20毫秒的操作都会记录下来,生产环境建议设置1000,也就是1ms,这样理论上redis并发至少达到1000,如果要求
    单机并发达到1万以上,这个值可能设置为100

  • config set slowlog-max-len 1024 # 设置慢日志记录保存数量,如果保存数量已满,会删除最早的记录,最新的日志追加进来,记录慢查询日志时Redis会对长命令做截断操作,并不会占用大量内存,建议设置稍大些,防止丢失日志

  • config rewrite #将服务器当前所使用的配置保存到redis.conf

  • slowlog len #获取慢查询日志列表的当前长度

  • slowlog get 5 # 获取最新的5条慢查询日志,慢查询日志由四个属性组成:标识ID,发生时间戳,命令耗时,执行命令和参数

  • slowlog reset #重置慢查询

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

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

相关文章

Python Web开发记录 Day10:Django part4 靓号管理与优化

名人说&#xff1a;莫道桑榆晚&#xff0c;为霞尚满天。——刘禹锡&#xff08;刘梦得&#xff0c;诗豪&#xff09; 创作者&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 目录 1、数据库准备2、靓号列表3、新建靓号4、编辑靓…

无人机自动返航算法部署与飞行控制实践

一、环境准备 无人机硬件&#xff1a;确保你有一台支持自定义飞行控制的无人机&#xff0c;通常配备有Pixhawk或其他类似的飞行控制器。 地面站软件&#xff1a;安装如Mission Planner或QGroundControl等地面站软件&#xff0c;用于配置无人机参数和上传飞行控制代码。 编程环…

Hadoop大数据应用:NFS网关 连接 HDFS集群

目录 一、实验 1.环境 2.NFS网关 连接 HDFS集群 3. NFS客户端挂载HDFS文件系统 二、问题 1.关闭服务报错 2.rsync 同步报错 3. mount挂载有哪些参数 一、实验 1.环境 &#xff08;1&#xff09;主机 表1 主机 主机架构软件版本IP备注hadoop NameNode &#xff08;…

ASP.NET

Web控件 Web控件-内部控件 ASP.NET引入一组称为”内部控件”的新控件&#xff0c;它们专门用于ASP.NET 内部控件的使用方法与HTML控件相同&#xff0c;它们映射到HTML元素并通过使用 runat”server”属性在服务器上执行 Web控件-列表控件 这些控件用于在Web页中创建数据列表…

Revit二次开发,tuple,valuetuple,anonymousType匿名类型的区别,笔记记录

Revit二次开发&#xff0c;tuple&#xff0c;valuetuple&#xff0c;anonymousType匿名类型的区别&#xff0c;笔记记录 Tuple<int, string> tuple new Tuple<int, string>(1, "hello");//tuple ValueTuple<int, string> valueTuple (1, "…

叶顺舟:手机SoC音频趋势洞察与端侧AI技术探讨 | 演讲嘉宾公布

后续将陆续揭秘更多演讲嘉宾&#xff01; 请持续关注&#xff01; 2024中国国际音频产业大会(GAS)将于2024年3.27 - 28日在上海张江科学会堂举办。大会将以“音无界&#xff0c;未来&#xff08;Audio&#xff0c; Future&#xff09;”为主题。大会由中国电子音响行业协会、上…

Hive3.0.0安装初始化过程,schematool -dbType mysql -initSchema报错

详细如下&#xff1a; 从字面意思理解&#xff0c;是在hive-site.xml文件3213行出现了非法字符&#xff0c;处理步骤如下 1、使用vi 3213 hive-site.xml打开文件 2、删除“&#8”&#xff0c;保存文件 3、再次执行初始化命令 schematool -dbType mysql -initSchema 4、登…

交换机/路由器的存储介质-华三

交换机/路由器的存储介质-华三 本文主要介绍网络设备的存储介质组成。 ROM(read-only memory&#xff0c;只读存储器) 用于存储 BootROM程序。BootROM程序是一个微缩的引导程序&#xff0c;主要任务是查找应用程序文件并引导到操作系统&#xff0c;在应用程序文件或配置文件出…

基于检索增强的 GPT-3.5 的文本到 SQL 框架,具有样本感知提示和动态修订链。

文章目录 一、论文关键信息二、基础概念三、主要内容1. Motivations2. Insights3. 解决方案的关键4. 实验 四、总结与讨论 &#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 一、论文关键信息 论文标题&#xff1a;Retrieval-augmented GPT-3.5-based T…

Windows安装及配置jdk

Windows安装及配置jdk Windows安装及配置jdk下载安装环境变量配置JAVA_HOME和JRE_HOME 配置Path验证环境 Windows安装及配置jdk 下载安装 JDK的下载是免费的&#xff0c;可以直接去官网下载最新版本&#xff0c;比较安全&#xff0c;安装的时候直接点击下一步到底&#xff0c;…

人生就像是一场旅行,房子和车子不过是旅途中的临时栖息地和代步工具

图片由AI生成 人生就像是一场漫无目的的旅行&#xff0c;房子和车子不过是旅途中的临时栖息地和代步工具。 我们费尽心思&#xff0c;经过无数个日夜的奋斗&#xff0c;终于有了自己的车和房&#xff0c;以为这就是生活的全部。 但&#xff0c;物质的堆砌永远无法定义我们的价值…

unity3d Animal Controller的Animal组件中Speeds,States和modes基础部分理解

Speeds 速度集是修改你可以做的原始动画,增加或减少运动,旋转,或动画速度。它们与 州 所以,当动物在运动状态下,在飞行或游泳时,你可以有不同的速度 如果你的性格动画是 (已到位), 你一定要调整速度 位置 和 旋转 每一种的价值观 速度装置 …否则,它们不会移动或旋转。 每个速…

微服务分布式springcloud研究生志愿填报辅助系统

本文讲述了研究生志愿填报辅助系统。结合电子管理系统的特点&#xff0c;分析了研究生志愿填报辅助系统的背景&#xff0c;给出了研究生志愿填报辅助系统实现的设计方案。 本论文主要完成不同用户的权限划分&#xff0c;不同用户具有不同权限的操作功能&#xff0c;在用户模块&…

Spring状态机简单实现

一、什么是状态机 状态机&#xff0c;又称有限状态自动机&#xff0c;是表示有限个状态以及在这些状态之间的转移和动作等行为的计算模型。状态机的概念其实可以应用的各种领域&#xff0c;包括电子工程、语言学、哲学、生物学、数学和逻辑学等&#xff0c;例如日常生活中的电…

SpringBoot之Bean扫描、Bean注册

目录 Bean扫描 Bean注册 Bean lmport 自定义注解 注册条件 Bean扫描 Bean扫描有两种方式 1、标签:<context:component-scan base-package"com.mybatis"/> 2、注解: ComponentScan(basePackages "com.mybatis") springboot启动类注解可以自…

Android 异常重启--踩坑归来--干货篇

如果你未对自己的app进行过处理&#xff0c;那么线上各种偶发莫名其妙的闪退、白屏、数据丢失&#xff0c;请检查一下是否因此而引发的。 起因 异常重建指的是非配置变更情况下导致的 Activity 重新创建。 常见场景大多是因为内存等资源不足&#xff0c;从而导致后台应用被系…

python统计分析——单变量分布的特征描述之分布中心

参考资料&#xff1a;python统计分析【托马斯】 也可查看&#xff1a;python统计分析——单变量描述统计-CSDN博客 当我们有一个来自分布的数据样本时&#xff0c;我们可以用不同的参数来描述分布中心。因此&#xff0c;数据可以用两种方式来评估&#xff1a; &#xff08;1&a…

Xcode15.3 -Library ‘iconv2.4.0‘ not found

今天升级了一下Mac mini 和Xcode15.3&#xff0c;运行项目就报 Library ‘iconv2.4.0’ not found的错误 xcode升级到&#xff1a;15.3(15A240d) 项目在旧版本下&#xff0c;是能通过编译 并且能运行的。 解决方法&#xff1a; 方案1&#xff1a;在Build Phases --> Link…

SSL VPN基础原理

目录 SSL ---安全传输协议&#xff08;安全套接层&#xff09;---TLS ----传输层安全协议 SSL的工作原理 SSL会话建立的过程 ​编辑 数据传输过程中的封装示意图 无客户端认证的过程 有客户端认证的过程 SSL VPN的核心技术---虚拟网关技术 服务器验证的点&#xff1a; 资源…

Gitlab光速发起Merge Request

前言 在我们日常开发过程中需要经常使用到Merge Request&#xff0c;在使用过程中我们需要来回在开发工具和UI界面之前来回切换&#xff0c;十分麻烦。那有没有一种办法可以时间直接开发开工具中直接发起Merge Request呢&#xff1f; 答案是有的。 使用 Git 命令方式创建 Me…