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

开发规范与性能优化

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 #重置慢查询

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

AMD芯片使用Stable-Diffusion

AMD芯片使用Stable-Diffusion 由于A卡的Stable Diffusion工具的逐步完善&#xff0c;之前只能使用CPU跑&#xff0c;现在已支持AMD显卡进行AI绘图。 下载 官网链接&#xff1a;https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Install-and-Run-on-AMD-GPUs 按…

LAMP网站部署(Discuz论坛网站部署)

目录 mysql命令 语法 选项 参数 实例 安装php 安装Mariadb 关掉防火墙和selinux 启动HTTP服务 初始化数据库 查看数据库是否创建成功 修改HTTP的配置文件 浏览器打开 将以下所有目录都加上权限 最后首页效果 mysql命令 是MySQL数据库服务器的客户端工具&#xff0c;它工作在命…

【Linux下qt软件安装打包附带问题: dpkg: error processing package xxxx +解决方式+自我尝试+记录】

【Linux下qt软件安装打包附带问题&#xff1a; dpkg: error processing package xxxx 解决方式自我尝试记录】 1、前言2、实验环境3、问题说明4、我的努力与查到解决的方式&#xff08;1&#xff09;补充两个文件&#xff0c;让软件正常执行&#xff08;2&#xff09;尝试修复d…

springboot+vue学生选课系统 java+ssm+idea+_mysql

系统包含三种角色&#xff1a;管理员、老师、学生&#xff0c;系统分为前台和后台两大模块&#xff0c;主要功能如下。 ide工具&#xff1a;IDEA 或者eclipse 编程语言: java 学生网上选课系统可以实现教室管理&#xff0c;老师管理&#xff0c;课程管理&#xff0c;教学计划管…

为什么我接不到大单?

以前的领导创业多年&#xff0c;今天找我聊了一下想让我跟他一起做点事情&#xff0c;聊了一下我的现状&#xff0c;突然让我明白为何我一直都接不到大单了 说起来也不是完全没有好的机会&#xff0c;貌似有点像“公交车定律”&#xff0c;当我很忙碌的时候订单一个接一个&…

闯关升级游戏特点,闯关小程序游戏开发

闯关升级类游戏一直以来都备受玩家青睐&#xff0c;其独特的游戏性和吸引力让人们乐此不疲。这类游戏以挑战性关卡和角色成长为核心&#xff0c;让玩家在不断的冒险中获得成就感与乐趣。让我们一起深入探讨这类游戏的特点&#xff0c;以及为何它们如此受欢迎。 挑战性关卡设计…

C语言中内存函数的使用

memcpy函数的使用和模拟实现 memcpy的使用 函数使用说明&#xff1a; • 函数memcpy从source的位置开始向后复制num个字节的数据到destination指向的内存位置。 • 这个函数在遇到 \0 的时候并不会停下来。 • 如果source和destination有任何的重叠&#xff0c;复制的结…

提升数据分析效率,选择IBM SPSS Statistics专业统计分析软件

在当今信息爆炸的时代&#xff0c;数据已经成为决策的重要依据。对于研究人员、学者、企业管理者等群体来说&#xff0c;如何高效地进行数据分析并得出准确结论至关重要。而IBM SPSS Statistics作为一款专业统计分析软件&#xff0c;为用户提供了强大的工具和功能&#xff0c;助…

【SQL】1084. 销售分析III (多种解法;is null 和 =null 的区别图示 )

前述 知识点学习&#xff1a;MySQL 中 is null 和 null 的区别 题目描述 leetcode题目&#xff1a; 1084. 销售分析III 写法一 思路&#xff1a;“所有售出日期都在这个时间内”&#xff0c;也就是“在这个时间内售出的商品数量等于总商品数量” -- 解法1&#xff1a;ACCE…

【深度学习】diffusers 学习过程记录,StableDiffusion扩散原理

教程地址&#xff1a;https://huggingface.co/docs/diffusers/quicktour 文章目录 环境扩散模型噪声残差的作用原理&#xff0c;文字编码如何给入Unetschedulerguidance_scalescheduler.init_noise_sigma训练时候的反向传播 环境 python3.10安装环境&#xff1a; pip install…

Gitee配置SSH登录

一、背景 新入手的电脑&#xff0c;需要对Gitee上存放的项目进行更改上传&#xff0c;发现上传不了需要登录&#xff0c;便采用SSH密钥进行登录&#xff0c;防止远程管理工程中的信息泄露 二、前提 电脑已下载Git Bash工具&#xff0c;在项目下点击鼠标右键&#xff0c;进入…

halconOCR文字识别

1、OCR文字识别 FontFile : Universal_0-9_NoRej dev_update_window (off) read_image (bottle, bottle2) get_image_size (bottle, Width, Height) dev_open_window (0, 0, Width, Height, black, WindowHandle) set_display_font (WindowHandle, 16, mono, true, false) dev…

适用于系统版本:CentOS 6/7/8的基线安全检测脚本

#!/bin/bash #适用于系统版本&#xff1a;CentOS 6/7/8 echo "----------------检测是否符合密码复杂度要求----------------" #把minlen&#xff08;密码最小长度&#xff09;设置为8-32位&#xff0c;把minclass&#xff08;至少包含小写字母、大写字母、数字、特殊…

JVM及垃圾回收算法

一、JVM 1、jvm的内存组成 五大内存区域&#xff0c;分1.7和1.8 1.堆内存&#xff1a;引用类型的数据&#xff0c;内部组成&#xff1a;1.新生代&#xff08;伊甸区和幸存者区&#xff09;2.老年代。该区域经常发生垃圾回收的操作 堆是JVM中最大的一块内存区域&#xff0c;用…

mac安全干净卸载Anaconda3

使用which python显示当前使用的是/Users/username/anaconda3/bin/python 现在想卸载Anaconda&#xff0c;恢复使用mac系统自带的Python 删除隐藏文件目录 rm -rf ~/.anaconda修改~/.bash_profile文件&#xff0c;将anaconda相关删除 也有可能不是~/.bash_profile而是~/.zs…

声卡喊话IP喇叭,IP网络吸顶天花喇叭

声卡喊话IP喇叭&#xff0c;IP网络吸顶天花喇叭 SV-7043VP是一款ip/sip网络吸顶喇叭&#xff0c;具有10/100M以太网接口&#xff0c;从网络接口接收网络的音频数据后播放。本网络吸顶喇叭可以与其他广播主机、服务器软件和采播主机配合使用&#xff0c;实现音频的播放&#xf…

【DL经典回顾】深度学习概述

深度学习概述 一、引言 在过去的几年里&#xff0c;深度学习已经从学术研究的领域走向了主流&#xff0c;彻底改变了我们对人工智能的认识和应用。这种强大的技术&#xff0c;以其独特的能力模仿人脑处理和分析复杂数据的方式&#xff0c;不仅在科学界引起了革命&#xff0c;…

ThingsBoard Edge 安装部署

文章目录 一、概述1.官方文档2.部署说明3.安装准备3.1. 克隆服务器3.2.安装 Docker3.3.安装 Java 113.4.安装 PostgreSQL3.5.下载安装包 二、安装部署1.创建 Edge 实例2.创建数据库3.Edge 服务安装3.1.安装服务3.2.配置 Edge3.3.运行安装脚本3.4.重新启动服务 4.访问 Edge5.故障…

基于PHP的数字化档案管理系统

有需要请加文章底部Q哦 可远程调试 基于PHP的数字化档案管理系统 一 介绍 此数字化档案管理系统基于原生PHP&#xff0c;MVC架构开发&#xff0c;数据库mysql&#xff0c;前端bootstrap。系统角色分为用户和管理员。 技术栈 php(mvc)mysqlbootstrapphpstudyvscode 二 功能 …

django-comment-migrate 模型注释的使用

django-comment-migrate 的使用 django-comment-migrate 是一个 Django 应用&#xff0c;用于将模型注释自动迁移到数据库表注释中。它可以帮助您保持数据库表注释与模型定义的一致性&#xff0c;并提高代码的可读性。 安装 要使用 django-comment-migrate&#xff0c;您需要…