Redis优化笔记

news2024/11/16 23:53:00

Redis优化

一:Key:

1.1.Key的规范:

image-20240519214240615
测试如下:
image-20240519214354630

1.2.拒绝BigKey:

image-20240519214511678
我们可以用:
MEMORY USAGE name
命令来看它的大小。

在这里插入图片描述

image-20240519214823088

注意,这里的第二种之所以不使用Keys *,因为在实际生产时,会阻塞线程,而scan就不会。使用举例:
import com.heima.jedis.util.JedisConnectionFactory;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.ScanResult;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class JedisTest {
    private Jedis jedis;

    @BeforeEach
    void setUp() {
        // 1.建立连接
        // jedis = new Jedis("192.168.150.101", 6379);
        jedis = JedisConnectionFactory.getJedis();
        // 2.设置密码
        jedis.auth("123321");
        // 3.选择库
        jedis.select(0);
    }

    final static int STR_MAX_LEN = 10 * 1024;
    final static int HASH_MAX_LEN = 500;

    @Test
    void testScan() {
        int maxLen = 0;
        long len = 0;

        String cursor = "0";
        do {
            // 扫描并获取一部分key
            ScanResult<String> result = jedis.scan(cursor);
            // 记录cursor
            cursor = result.getCursor();
            List<String> list = result.getResult();
            if (list == null || list.isEmpty()) {
                break;
            }
            // 遍历
            for (String key : list) {
                // 判断key的类型
                String type = jedis.type(key);
                switch (type) {
                    case "string":
                        len = jedis.strlen(key);
                        maxLen = STR_MAX_LEN;
                        break;
                    case "hash":
                        len = jedis.hlen(key);
                        maxLen = HASH_MAX_LEN;
                        break;
                    case "list":
                        len = jedis.llen(key);
                        maxLen = HASH_MAX_LEN;
                        break;
                    case "set":
                        len = jedis.scard(key);
                        maxLen = HASH_MAX_LEN;
                        break;
                    case "zset":
                        len = jedis.zcard(key);
                        maxLen = HASH_MAX_LEN;
                        break;
                    default:
                        break;
                }
                if (len >= maxLen) {
                    System.out.printf("Found big key : %s, type: %s, length or size: %d %n", key, type, len);
                }
            }
        } while (!cursor.equals("0"));
    }
    
    @AfterEach
    void tearDown() {
        if (jedis != null) {
            jedis.close();
        }
    }

}
建议放在从节点进行。

在这里插入图片描述

1.3.合适的结构:

在这里插入图片描述

用Hash存储:

在这里插入图片描述

用string:

在这里插入图片描述

用多级Hash:

在这里插入图片描述

二:批处理优化:

2.1.MSET与Pipeline:

导入大量数据,一次导入与多次导入谁时间更优秀呢:

先来看看多次导入:

在这里插入图片描述

通过测试,导入时间主要是花在了网络传输上面了。因此,这明显不如第二种:

在这里插入图片描述

下面我们来看看基于mset的批处理:

在这里插入图片描述

但是,有很多的命令具有局限性,其他的数据结构未必有批处理,就算是集合,它的sadd也只是针对同一个key而已。所以我们使用Pipeline:

当然,在spring-redis中,也有批处理,举例如下:
import org.springframework.beans.factory.annotation.Autowired;  
import org.springframework.data.redis.core.RedisCallback;  
import org.springframework.data.redis.core.RedisTemplate;  
import org.springframework.data.redis.connection.RedisConnection;  
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;  
import io.lettuce.core.api.StatefulRedisConnection;  
import io.lettuce.core.api.sync.RedisCommands;  
  
@Service  
public class RedisPipelinedService {  
  
    @Autowired  
    private RedisTemplate<String, String> redisTemplate;  
  
    public void executePipelinedCommands() {  
        redisTemplate.executePipelined((RedisCallback<Object>) connection -> {  
            RedisCommands<String, String> commands = connection.sync();  
              
            // 添加多个命令到 pipeline  
            commands.set("key1", "value1");  
            commands.set("key2", "value2");  
            // ... 可以添加更多命令  
  
            // 注意:不需要在这里调用任何返回结果的方法,因为 pipelined 命令是异步的  
            return null; // RedisCallback 需要返回 Object,但在这里我们不需要它  
        });  
  
        // 注意:上面的 executePipelined 方法是异步的,但会返回一个 List,其中包含每个命令的响应  
        // 你可以在这里处理这些响应,但在这个例子中我们忽略了它们  
    }  
  
    // 如果你需要更底层的访问(例如,直接使用 Lettuce 的 StatefulRedisConnection),  
    // 你可以从 LettuceConnectionFactory 获取它,但通常不建议这样做,除非你有特殊需求。  
}
小细节:mset快于Pipeline。

2.2.集群下的批处理:

在这里插入图片描述

在这里插入图片描述

串行:

在这里插入图片描述

并行:
我们还可以使用Spring的方法来实现并行:

在这里插入图片描述

三:服务端优化:

3.1.持久化配置:

在这里插入图片描述

关于第五点:为什么要有这样一个配置:

在这里插入图片描述

这是AOF的刷盘机制,我们可以看到,当刷盘时间大于2s,会导致主节点阻塞,而如果我们在进行刷盘时,磁盘也在进行大量的IO,比如AOF的重写,或者RDB的fork,就会很容易导致主线程等待时间过长。当然,如果设置为yes,可能会丢失一段数据。

3.2.慢查询:

在这里插入图片描述

在这里插入图片描述

当我们执行了一个keys *后,比如我们用慢查询日志来查看一下:

在这里插入图片描述

当然,在redis客户端,可以直接看到慢查询日志:

在这里插入图片描述

这是一些其他的命令;

在这里插入图片描述

3.3.命令与安全配置:

在这里插入图片描述

举例:

在这里插入图片描述

设置为“”表示不允许使用,而第一种表示要用它来替代改命令,其他人就不可能破解。

3.4.内存配置:

在这里插入图片描述

定期重启可以清除数据内存,而进程问题影响也不是很大,所以我们主要是缓冲区问题。

在这里插入图片描述

在这里插入图片描述

四:集群与主从:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

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

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

相关文章

Python | Leetcode Python题解之第101题对称二叉树

题目&#xff1a; 题解&#xff1a; class Solution:# 在【100. 相同的树】的基础上稍加改动def isSameTree(self, p: Optional[TreeNode], q: Optional[TreeNode]) -> bool:if p is None or q is None:return p is qreturn p.val q.val and self.isSameTree(p.left, q.ri…

深度学习中的优化算法二(Pytorch 19)

一 梯度下降 尽管梯度下降&#xff08;gradient descent&#xff09;很少直接用于深度学习&#xff0c;但了解它是理解下一节 随机梯度下降算法 的关键。例如&#xff0c;由于学习率过大&#xff0c;优化问题可能会发散&#xff0c;这种现象早已在梯度下降中出现。同样地&…

Spark-RDD-常用算子(方法)详解

Spark概述 Spark-RDD概述 Spark RDD 提供了丰富的方法来对数据进行转换和操作。 对 RDD&#xff08;Resilient Distributed Dataset&#xff09;的操作可以分为两大类&#xff1a;转换算子&#xff08;Transformations&#xff09;和行动算子&#xff08;Actions&#xff09;…

Tower在深度学习中的概念,tower没有确切定义

在论文UniTS中&#xff0c;来自Havard的工作。 tower更像是针对一个task的组件 tower这个概念貌似在REC&#xff08;recommendation&#xff09;推荐系统中使用较多 deep learning - What is a tower? - Data Science Stack Exchange https://developers.google.com/machin…

C语言数据结构栈的概念及结构、栈的实现、栈的初始化、销毁栈、入栈、出栈、检查是否为空、获取栈顶元素、获取有效元素个数等的介绍

文章目录 前言栈的概念及结构栈的实现一、 栈结构创建二、 初始化结构三、销毁栈四、入栈五、出栈六、检查是否为空七、获取栈顶元素八、获取有效元素的个数九、测试 1十、测试 2总结 前言 C语言数据结构栈的概念及结构、栈的实现、栈的初始化、销毁栈、入栈、出栈、检查是否为…

查找专利渠道

官方渠道 常规检索 (cnipa.gov.cn)https://pss-system.cponline.cnipa.gov.cn/conventionalSearch 佰腾网 佰腾网 - 查专利就上佰腾网_佰腾全球专利搜索平台_商标查询平台_企业工商信息查询平台 (baiten.cn)https://www.baiten.cn/

从0开始实现一个博客系统 (SSM 实现)

相关技术 Spring Spring Boot Spring MVC MyBatis Html Css JS pom 文件我就不放出来了, 之前用的 jdk8 做的, MySQL 用的 5.7, 都有点老了, 你们自己看着配版本就好 实现功能 用户注册 - 密码加盐加密 (md5 加密)前后端用户信息存储 - 令牌技术用户登录 - (使用 拦截…

c++(三)

C&#xff08;三&#xff09; staticc语言的staticc中的staticstatic修饰的成员变量static 修饰成员函数 constc语言cconst修饰成员变量const修饰的成员函数const修饰的类对象 mutable友元普通函数作为友元类的成员函数作为友元友元类 static c语言的static C语言中static的作…

【test】Windows11下通过sshfs挂载远程服务器目录

下载安装下面三个软件&#xff1a; sshfs-win&#xff1a;https://github.com/billziss-gh/sshfs-win/releases winfsp&#xff1a;https://github.com/billziss-gh/winfsp/releases SSHFS-Win Manager&#xff1a;https://github.com/evsar3/sshfs-win-manager/releases 安装…

增强ev代码签名证书2300

代码签名证书是软件开发者们确保软件完整性和安全性的重要工具之一。在各种类型的代码签名证书中&#xff0c;增强EV代码签名证书拥有许多独特的功能而受到企业开发者的欢迎&#xff0c;今天就随SSL盾小编了解增强EV代码签名证书的申请条件以及申请流程。 1.增强型EV代码签名证…

Linux——Dockerfile

在这里我们来整理一下docker容器、dockerfile、docker镜像的关系&#xff1a; dockerfile是面向开发的&#xff0c;发布项目做镜像的时候就要编写dockerfile文件。 dockerfile&#xff1a;构建文件&#xff0c;定义了一切的步骤&#xff0c;源代码。 dockerImanges&#xff1a…

【AI绘画Stable Diffusion】单人LoRA模型训练,打造你的专属模型,新手入门宝典请收藏!

大家好&#xff0c;我是灵魂画师向阳 本期我将教大家如何进行LoRA模型训练&#xff0c;打造你的专属模型&#xff0c;内容比较干&#xff0c;还请耐心看完&#xff01; 随着AIGC的发展&#xff0c;许多传统工作岗位正逐渐被AI取代。同时&#xff0c;AI变革也在创造前所未有的…

STM32 学习——1. STM32最小系统

这是一个最小系统的测试&#xff0c;LED灯会进行闪烁。选用PC13口&#xff0c;因为STM32F103C8T6 硬件开发板中&#xff0c;这个端口是一个LED 1. proteus8.15 原理图 2. cubemx 新建工程 3. keil 代码 while (1){HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);HAL_Delay(100);…

《计算机网络微课堂》1-3 三种交换方式

本节课我们介绍三种交换方式&#xff0c;分别是电路交换&#xff08;Circuit Switching&#xff09;&#xff0c;分组交换&#xff08;Packet Switching&#xff09;以及报文&#xff08;Message Switching&#xff09;交换。 我们首先来看电路交换&#xff0c;在电话问世后不…

探索未来,与移动云共舞

探索未来&#xff0c;与移动云共舞 在数字化飞速发展的今天&#xff0c;云计算已经成为企业、政府乃至个人用户不可或缺的一部分。而在众多云服务提供商中&#xff0c;移动云凭借其独特的优势&#xff0c;为用户带来前所未有的体验。接下来&#xff0c;让我们一起走进移动云的世…

Python--List列表

list列表⭐⭐ 1高级数据类型 Python中的数据类型可以分为&#xff1a;数字型&#xff08;基本数据类型&#xff09;和非数字型&#xff08;高级数据类型&#xff09; ●数字型包含&#xff1a;整型int、浮点型float、布尔型bool、复数型complex ●非数字型包含&#xff1a;字符…

Python实现数据可视化效果图总结

一、JSON格式 JSON是一种轻量级的数据交互格式。可以按照JSON指定的格式去组织和封装数据。 JSON本质上是一个带有特定格式的字符串 Json格式 JSON数据格式在Python中可以是字典、又可以是列表中嵌套着字典的格式。 Pyhton数据和Json数据相互转化 二、pyecharts模块 如果想…

SpringMVC接收请求参数的方式:

接收简单变量的请求参数 直接使用简单变量作为形参进行接收&#xff08;这里简单变量名称需要与接收的参数名称保持一致&#xff0c;否则需要加上RequestParam注解&#xff09;&#xff1a; 细节&#xff1a; 1&#xff1a;SpringMVC会针对常见类型&#xff08;八种基本类型及…

翻译《The Old New Thing》- The importance of the FORMAT_MESSAGE_IGNORE_INSERTS flag

The importance of the FORMAT_MESSAGE_IGNORE_INSERTS flag - The Old New Thing (microsoft.com)https://devblogs.microsoft.com/oldnewthing/20071128-00/?p24353 Raymond Chen 2007年11月28日 FORMAT_MESSAGE_IGNORE_INSERTS 标志的重要性 简要 文章讨论了使用FormatMes…

数据结构----堆的实现(附代码)

当大家看了鄙人的上一篇博客栈后&#xff0c;稍微猜一下应该知道鄙人下一篇想写的博客就是堆了吧。毕竟堆栈在C语言中常常是一起出现的。那么堆是什么&#xff0c;是如何实现的嘞。接下来我就带大家去尝试实现一下堆。 堆的含义 首先我们要写出一个堆&#xff0c;那么我们就需…