redis优化与一些问题

news2024/11/20 14:21:20

文章目录

  • 优化
    • 采用SSD硬盘-提升磁盘读写的速度
    • 控制 redis 的内存在10G以内,防止fork耗时太长
    • fork 注意事项
    • 设置内存淘汰策略
    • vm.overcommit_memory=1
    • 尽可能地使用 hash 哈希存储
    • 参数调优
      • swapiness
      • ulimit
      • TCP backlog
    • 客户端缓冲优化
    • 碎片优化
  • 问题
    • 缓存与数据库数据不一致
    • 将 热点库存分段
    • 穿透的解决办法
    • redis实现 黑名单
    • 如何安全的减库存
    • list可以做分页

优化

采用SSD硬盘-提升磁盘读写的速度

控制 redis 的内存在10G以内,防止fork耗时太长

fork 注意事项

fork 时,子进程 需要 拷贝 父进程的 空间内存页表
会 耗时避免复制风暴,采用树状,不要用链状

设置内存淘汰策略

allkeys-lru  #  内存淘汰策略
allkeys-lfu  #--->保证 redis 存储的都是 热点数据

vm.overcommit_memory=1

防止OOM

在这里插入图片描述
因此一般需要将这个参数的值调整为1,意思是 把所有可用的物理内存都允许分配给你

只要 有内存就给你来用,这样可以 避免申请内存失败的问题

cat /proc/sys/vm/overcommit_memory
echo 'vm.overcommit_memory=1' >> /etc/sysctl.conf
sysctl vm.overcommit_memory=1
sysctl -p

尽可能地使用 hash 哈希存储

参数调优

swapiness

cat /proc/version # 查看Linux 内核版本

在这里插入图片描述

  • 如果版本<3.5 —>swapiness设置为0,宁愿swap 也不会 oom ,killer(杀掉进程)
  • 如果版本>=3.5—>swapiness设置为1,宁愿swap 也不会 oom ,killer

保证 redis 不被杀掉

echo 0> /proc/sys/vm/swappiness
echo vm.swapiness=0  >> /etc/sysctl.conf

ulimit

是用来控制linux上的最大文件链接数的,默认值可能是1024,一般肯定是不够的

因为你在大量频繁的读写磁盘文件的时候,或者是进行网络通信的时候,都会跟这个参数有关系
对于一个中间件系统而言肯定是不能使用默认值的

如果你采用默认值,很可能在线上会出现如下错误:error: too many openfiles

echo 'ulimit -n 1000000' >> /etc/profile
ulimit -n 10032 10032 # 不同的版本会不一样

TCP backlog

在这里插入图片描述

cat /proc/sys/net/core/somaxconn 
echo 511 > /proc/sys/net/core/somaxconn

客户端缓冲优化

客户端缓存是很多内存异常增长的罪魁祸首,大部分都是普通客户端输出缓冲区异常增长导致

我们先了解下执行命令的过程,客户端发送一个或者通过pipline 发送一组请求命令给服务端,然后等待服务端的响应。
一般客户端使用阻塞模式来等待服务端响应,数据在被客户端读取前,数据是存放在客户端缓存区

.输出缓冲区的大小超过了硬性限制的大小时,这个客户端会被立即关闭

client-output-buffer-limit 
  • #表示这个客户端的输出缓冲区不限制大小
  • client-output-buffer-limit normal 0 0 0
  • 设置 从服务器 客户端的硬性限制为512MB软性限制为128MB, 软性限制的时长为120s
  • client-output-buffer-limit slave 512mb 128mb 120

优化建议:

  • 应用 不要设计大 key,大 key 尽量拆分
  • 服务端的普通客户端输出缓存区 通过参数设置,因为 内存告警的阈值大部分是使用率 80% 开始,实际 建议参数可以设置为 实例内存的 5%~15% 左右,最好不要超过 20%,避免 OOM。
  • 非 特殊情况下避免使用 monitor 命令或者 rename 该命令。
  • 在使用 pipline 的时候,pipeline 不能封装过多的命令,特别是一些返回结果集较多的命令更应该少封装。
  • 主从复制输出缓冲区大小设置参考
  • 缓冲区大小=( 主库写入命令速度 * 操作大小 - 主从库间 网络传输命令速度 * 操作大小 ) * 2

碎片优化

碎片优化 可以 降低内存使用率,提高访问效率

  1. 手动整理 memery purge
  2. 自动整理
  • 【activedefrag yes 】:启用 自动碎片 清理开关
  • 【active-defrag-ignore-bytes 100mb】:内存碎片空间达到 多少才 开启碎片整理
  • 【active-defrag-threshold-lower 10】:碎片率达到 百分之多少才 开启碎片整理
  • 【active-defrag-threshold-upper 100 】:内存碎片率 超过多少,则 尽最大努力整理(占用最大资源去做碎片整理

问题

缓存与数据库数据不一致

  • 先更新缓存,再更新数据库
    更新缓存成功,更新数据库失败,会造成数据不一致,很严重!!!这种情况绝对不允许!!
  • 先更新数据库,再删除缓存,可以进行重试,使用定时任务活着mq
  • 延时双删的问题:
    延时双删的第二次删除的时间,应该大于主从复制的时间,因为有读请求过来时,会去 从库执行,避免了脏读~
    休眠时间的确定,在数据业务逻辑的耗时基础上加百毫秒
  • 设置缓存过期时间进行兜底~~

吞吐量降低----> 开启线程池进行删除,或使用MQ

将 热点库存分段

redis 的big key

造成 主线程阻塞,所有请求可能超时,超时的越来越多,当新的请求越来越多,造成 redis 连接池资源耗尽

采用异步删除 unlink key

穿透的解决办法

业务规则过滤 + 布隆过滤器 + Nginx 黑名单

redis实现 黑名单

防止恶意用户,恶意攻击 : 一分钟调用下单超过50次 ,加入临时黑名单 ,10分钟后才可继续操作,一小时允许一次跨时段弱校验。使用reids的list结构,过期时间一小时

/**
     * @param token
     * @return true 可下单
     */
    public boolean judgeUserToken(String token) {
        //获取用户下单次数 1分钟50次
        String blackUser = "shop-oms-submit-black-" + token;
        if (redis.get(blackUser) != null) {
            return false;
        }
        String keyCount = "shop-oms-submit-count-" + token;
        Long nowSecond = LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8"));
        //每一小时清一次key 过期时间1小时
        Long count = redis.rpush(keyCount, String.valueOf(nowSecond), 60 * 60);
        if (count < 50) {
            return true;
        }
        //获取第50次的时间
        List<String> secondString = redis.lrange(keyCount, count - 50, count - 49);
        Long oldSecond = Long.valueOf(secondString.get(0));
        //now > oldSecond + 60 用户可下单
        boolean result = nowSecond.compareTo(oldSecond + 60) > 0;
        if (!result) {
            //触发限制,加入黑名单,过期时间10分钟
            redis.set(blackUser, String.valueOf(nowSecond), 10 * 60);
        }
        return result;
    }

如何安全的减库存

redis + mq + mysql 保证库存安全,满足高并发处理,但相对复杂。


import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;


@RestController
@Slf4j
public class StockService {
    @Resource
    private StringRedisTemplate redis;


    /**
     * 扣库存操作,秒杀的处理方案
     *
     * @param orderCode
     * @param skuCode
     * @param num
     * @return
     */
    public boolean subtractStock(String orderCode, String skuCode, Integer num) {
        String key = "shop-product-stock" + skuCode;
        Object value = redis.opsForValue ().get (key);
        if (value == null) {
            //前提 提前将商品库存放入缓存 ,如果缓存不存在,视为没有该商品
            return false;
        }
        //先检查 库存是否充足
        Integer stock = (Integer) value;
        if (stock < num) {
            log.info ("库存不足");
            return false;
        }
        //不可在这里直接操作数据库减库存,否则导致数据不安全
        //因为此时可能有其他线程已经将redis的key修改了
        //redis 减少库存,然后才能操作数据库
        Long newStock = redis.opsForValue ().increment (key, -num.longValue ());
        //库存充足
        if (newStock >= 0) {
            log.info ("成功抢购");
            //TODO 真正扣库存操作 可用MQ 进行 redis 和 mysql 的数据同步,减少响应时间
            // 发送信息到mq ,进行redis和mq的同步
        } else {
            //库存不足,需要增加刚刚减去的库存
            redis.opsForValue ().increment (key, num.longValue ());
            log.info ("库存不足,并发");
            return false;
        }
        return true;
    }


}

increment 是个原子操作,也可以使用lua脚本

list可以做分页

比如前多少条数据,评论也可以存,因为本身是个集合 lrangelpushrpush

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

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

相关文章

换个地方写helloworld

1、Linux中I/O讲解 今天&#xff0c;我们重新学习C语言的基础&#xff0c;特别是I/O口的讲解。 所谓标准 I/O 库则是标准 C 库中用于文件 I/O 操作&#xff08;譬如读文件、写文件等&#xff09;相关的一系列库函数的集合&#xff0c;通常标准 I/O 库函数相关的函数定义都在头…

实时输出Java8 HashMap数据结构

看过 Java 8 HashMap 源码的知道底层数据结构是数组、链表和红黑树实现的&#xff0c;从Debug调试或者序列化输出的都是K,V值&#xff0c;没法直观的看到上述的数据结构&#xff0c;为了直观的看到数据结构存储方面的变化&#xff0c;本文通过动图演示HashMap的结构变化。 为了…

【6 - 完结】Sql Server - 郝斌(identity、视图、事务、索引、存储过程、触发器、游标、TL_SQL)

课程地址&#xff1a;数据库 SQLServer 视频教程全集&#xff08;99P&#xff09;| 22 小时从入门到精通_哔哩哔哩_bilibili ​ 目录 identity&#xff08;主键自动增长&#xff0c;用户不需要为identity修饰的主键赋值&#xff09; 用法 如何重新设置identity字段的值 如…

从React源码来学hooks是不是更香呢

本文将讲解 hooks 的执行过程以及常用的 hooks 的源码。 hooks 相关数据结构 要理解 hooks 的执行过程&#xff0c;首先想要大家对 hooks 相关的数据结构有所了解&#xff0c;便于后面大家顺畅地阅读代码。 Hook 每一个 hooks 方法都会生成一个类型为 Hook 的对象&#xff…

wpf布局学习二 wpf xaml 与android xml界面对比, C++图片旋转与缩放好复杂放弃

弄不明白的事&#xff0c;还是不要去做。 没懂清楚原理&#xff0c;不要尝试去修改。浪费时间。 wpf布局学习二 <Window x:Class"WpfM20UpdateFW.MainWindow"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://sch…

使用adb shell 命令接收串口发送过来的16进制数据 或者 发送16进制数据

首先执行 adb root Adb shell 找到你要发送或者接收串口数据的设备 如果我们再android设备上调试串口的时候&#xff0c;有时我们需要使用adb shell命令&#xff0c;假设我们使用串口发送的数据是16进制&#xff0c;那么使用cat 这个设备节点&#xff0c;有可能显示的是乱码例…

第6章 循环神经网络

系列文章目录 第1章 绪论 第2章 机器学习概述 第3章 线性模型 第4章 前馈神经网络 第5章 卷积神经网络 第6章 循环神经网络 第7章 网络优化与正则化 第8章 注意力机制与外部记忆 第9章 无监督学习 第10章 模型独立的学习方式 第11章 概率图模型 第12章 深度信念网络 第13章 深…

新相微在科创板过会:计划募资约15亿元,2022年业绩开始下滑

11月22日&#xff0c;上海证券交易所科创板披露的信息显示&#xff0c;上海新相微电子股份有限公司&#xff08;下称“新相微”&#xff09;获得上市委会议通过。据贝多财经了解&#xff0c;新相微于2022年6月28日在科创板递交招股书。 本次冲刺科创板上市&#xff0c;新相微计…

企业架构LB-服务器的负载均衡之LVS实现

01_学习目标和内容 02_LVS介绍和ipvsadm管理工具安装 03_LVS常见工作方式和调度算法介绍 04_需要知道的几个概念名词 05_LVS-NAT方式实现的流程原理 06_配置NAT模式准备工作 在centos中建立网卡配置信息 07_NAT模型RS真实服务器的网关配置 08_NAT模型DR调度服务器规则和转发配…

2010年数学二真题复盘

高数部分 选择题 第一题 思路分析:本要主要考察间断点的概念与极限运算. ☆首先无穷间断点属于第二类间断点,则至少有一个点不存在,要么没定义,要么就是在某个点的左极限或者右极限上趋于无穷,可以先化简,找一些分母趋于0的,那么就是无穷间断点了。 第二题 思路分…

设计模式之美——多组合少继承

组合优于继承&#xff0c;多用组合少用继承。 继承举例 假设我们要设计一个关于鸟的类。我们将“鸟类”这样一个抽象的事物概念&#xff0c;定义为一个抽象类 AbstractBird。所有更细分的鸟&#xff0c;比如麻雀、鸽子、乌鸦等&#xff0c;都继承这个抽象类。 我们知道&…

web前端期末大作业——贵州山地旅游介绍网页1页 HTML旅游网站设计与实现

&#x1f468;‍&#x1f393;学生HTML静态网页基础水平制作&#x1f469;‍&#x1f393;&#xff0c;页面排版干净简洁。使用HTMLCSS页面布局设计,web大学生网页设计作业源码&#xff0c;这是一个不错的旅游网页制作&#xff0c;画面精明&#xff0c;排版整洁&#xff0c;内容…

Qt+Win10使用QAxWidget控件实现远程桌面控制

Windows开始菜单-运行-输入mstsc&#xff0c;可以打开自带的远程桌面连接工具。如果想使用Qt来实现这个工具&#xff0c;怎么弄&#xff1f; 一、Win10环境的配置 1、Win10-我的电脑-属性-远程桌面-开启 2、打开控制面板-管理工具&#xff08;Win11是【Windows工具】&#xff…

Ubuntu16.4安装搜狗拼音输入法

Ubuntu16.04安装搜狗输入法&#xff0c;总结可以分为5步&#xff1a; 1.下载搜狗输入法的安装包 2.安装fcitx输入法框架 3.安装搜狗输入法 4.重启Ubuntu 5.配置搜狗输入法 1.下载搜狗输入法的安装包 百度搜索“搜狗输入法 linux” https://pinyin.sogou.com/linux. ​​​​…

CY3/CY5/CY7标记牛血清白蛋白/人血清白蛋白,CY3/CY5/CY7-BSA/HSA

产品名称&#xff1a;CY3/CY5/CY7标记牛血清白蛋白/人血清白蛋白 英文名称&#xff1a;CY3/CY5/CY7-BSA/HSA 血清白蛋白一般指人血白蛋白&#xff0c;是由580个氨基酸残基单链组成的蛋白质&#xff0c;由肝脏分泌&#xff0c;在血浆中含量最高&#xff0c;约占52%-68%左右。血…

Flink之ProcessFunction

ProcessFunction基本处理函数处理函数的功能和使用ProcessFunction 解析处理函数的分类按键分区处理函数&#xff08;KeyedProcessFunction&#xff09;定时器&#xff08;Timer&#xff09;和定时服务&#xff08;TimerService&#xff09;KeyedProcessFunction 的使用窗口处理…

机房动环状态综合触摸屏监控解决方案

随着移动互联网、电子商务等迅速扩张&#xff0c;大型互联网企业的用户数再创新高&#xff0c;数据量爆发式增长&#xff0c;企业对IDC资源的需求越来越大。机房状态安全的重要性对于一个企业来说一直以来都是一个令人头疼的问题。因此&#xff0c;我们推出了动环状态网络触摸屏…

Linux学习-51-进程间通信和终止线程命令

12.9 常用信号&#xff08;进程间通信&#xff09;及其含义 进程的管理主要是指进程的关闭与重启。我们一般关闭或重启软件&#xff0c;都是关闭或重启它的程序&#xff0c;而不是直接操作进程的。比如&#xff0c;要重启 apache 服务&#xff0c;一般使用命令"service ht…

旅游定制服务|基于SSM实现旅游个性化定制网站平台

旅游定制订单管理 旅游订单管理 作者主页&#xff1a;编程千纸鹤 作者简介&#xff1a;Java、前端、Pythone开发多年&#xff0c;做过高程&#xff0c;项目经理&#xff0c;架构师 主要内容&#xff1a;Java项目开发、毕业设计开发、面试技术整理、最新技术分享 收藏点赞不迷路…

大一新生HTML期末作业,网页制作作业——明星介绍易烊千玺网站HTML+CSS

&#x1f389;精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业…