首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >云数据库Redis开箱测评方法论:性能测试小结

云数据库Redis开箱测评方法论:性能测试小结

原创
作者头像
后台技术汇
修改2024-11-22 11:04:39
修改2024-11-22 11:04:39
17800
代码可运行
举报
运行总次数:0
代码可运行

腾讯云双十一“团战”

腾讯云双十一拼团GO热火进行中!!!

今年的腾讯云双十一活动,玩出了新花样——“百款折扣商品任意拼,双人成团PK有大礼”!

这不仅仅是一场购物狂欢,更是一场充满欢笑与惊喜的“团战”!折扣商品大乱斗,省钱又刺激

云计算、大数据、人工智能……各种热门商品齐聚一堂,价格更是低到让人尖叫!

不论你是企业大佬还是个人小透明,这里都有让你心动的宝贝。

而且,折扣力度之大,简直让人想把购物车塞满!

前言

上篇文章我们了解了腾讯云双十一薅羊毛之Redis,那么购买了服务器之后,我们要如何验证Redis配置是否符合我们的业务需求呢?下面我们简单回顾一下Redis性能的相关概念。

Redis集群部署

可以参考以下几篇文章:

  • 主从模式

深刻理解Redis集群(中):Redis主从数据同步模式

  • 哨兵模式

深刻理解Redis集群(下):Redis 哨兵(Sentinel)模式

  • AOF&RDB同步数据

深刻理解Redis集群(上):RDB快照和AOF日志

Redis监控工具Media

使用说明

(1)启动程序后填写 Redis 服务器信息进行连接:

(2)连接后便可以对键和键值进行增删改查操作:

(3)Medis 还支持直接执行终端命令:

Redis性能配置参数

要开启Redis的慢查询日志功能,你需要修改Redis的配置文件(通常是redis.conf),并进行以下配置:

配置慢查询日志

修改redis.conf文件:

  1. 设置慢查询的时间阈值:
    1. 使用slowlog-log-slower-than参数来设置命令执行时间的阈值(单位为微秒)。例如,设置为10000微秒(即10毫秒):
    代码语言:javascript
    代码运行次数:0
    运行
    复制
    slowlog-log-slower-than 10000
  2. 设置慢查询日志的最大长度:
    1. 使用slowlog-max-len参数来设置慢查询日志的最大条目数。例如,设置为128条:
代码语言:javascript
代码运行次数:0
运行
复制
slowlog-max-len 128
  1. 保存配置文件的更改后,重启Redis服务器以使配置生效
  2. 设置最大内存值:(为了方便测试性能)
代码语言:javascript
代码运行次数:0
运行
复制
maxmemory 21mb
  1. 设置数据淘汰策略
代码语言:javascript
代码运行次数:0
运行
复制
maxmemory-policy allkeys-lru

缓存数据淘汰策略

在Redis的redis.conf文件里,maxmemory-policy配置项用于设置当达到最大内存限制时,Redis如何选择要移除的数据。以下是各个淘汰策略的详细说明:

淘汰策略选项

  • volatile-lru:使用近似LRU算法淘汰设置了过期时间的键。
  • allkeys-lru:使用近似LRU算法淘汰任意键。
  • volatile-lfu:使用近似LFU算法淘汰设置了过期时间的键。
  • allkeys-lfu:使用近似LFU算法淘汰任意键。
  • volatile-random:随机淘汰设置了过期时间的键。
  • allkeys-random:随机淘汰任意键。
  • volatile-ttl:淘汰剩余过期时间最短的键。
  • noeviction:不淘汰任何数据,当内存不足时返回错误。

策略解释

  • LRU (Least Recently Used):最近最少使用,优先淘汰最长时间未被访问的键。
  • LFU (Least Frequently Used):最不经常使用,优先淘汰访问频率最低的键。
  • TTL (Time To Live):剩余生存时间,优先淘汰即将过期的键。

配置示例

redis.conf文件中,你可以设置如下配置:

代码语言:javascript
代码运行次数:0
运行
复制
maxmemory-policy allkeys-lru

这表示当Redis达到最大内存限制时,将使用近似LRU算法淘汰任意键。

注意事项

  • 这些淘汰策略都是基于近似算法实现的,可能会有一定的误差。
  • 当没有合适的键可以淘汰时,Redis会在需要更多内存的写操作上返回错误。
  • 默认策略是noeviction,即不淘汰任何数据,当内存不足时返回错误。

通过合理配置maxmemory-policy,可以确保Redis在高负载情况下仍能稳定运行,并根据应用需求优化内存使用。

Redis性能压测demo

并发大字段写入读取压测

代码语言:txt
复制
package com.bryant.controller.redis;

import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.Random;

@RestController
@RequestMapping("/redis/performance")
public class PerformanceController {

    @Resource(name = "userRedisTemplate")
    private RedisTemplate redisTemplate;

    @Autowired
    private RedissonClient redissonClient;

    private static final int _1MB = 1024 * 1024;
    private static final int _100MB = 1024 * 1024 * 100;

    @PostMapping("/write2Cache")
    public void write(
            @RequestParam(value = "id", defaultValue = "0") int id,
            @RequestParam(value = "isBigObject", defaultValue = "false") boolean isBigObject) {
        for (int i = id; i < 100; i++) {
            byte[] _1M = new byte[_100MB];
            BigObject bigObject = new BigObject(_1M);
            String key = "1M:" + i;
            if (isBigObject) {
                redisTemplate.opsForValue().set(key, bigObject);
            } else {
                redisTemplate.opsForValue().set(key, bigObject.toString());
            }
        }
    }

    @GetMapping("/readFromCache")
    public void read() {
        for (int i = 0; i < 100; i++) {
            redisTemplate.opsForValue().get("1M:" + i);
        }
    }

}

class BigObject implements Serializable {

    private static final long serialVersionUID = 589939600983368050L;

    private byte[] a;

    public BigObject(byte[] a) {
        this.a = a;
    }

    public byte[] getA() {
        return a;
    }

    public void setA(byte[] a) {
        this.a = a;
    }

}

keys指令和scan指令

(1)keys指令扫描容易引发性能问题

阻塞操作

  • KEYS 命令是一个阻塞操作,它会阻塞 Redis 服务器直到命令执行完毕。这意味着在 KEYS 命令执行期间,Redis 无法处理其他客户端的请求,导致服务不可用

时间复杂度

  • KEYS 命令的时间复杂度是 O(N),其中 N 是数据库中的 key 数量。如果数据库中有大量的 key,KEYS 命令的执行时间会非常长。

内存消耗

  • KEYS 命令会将所有的 key 加载到内存中,这可能导致内存消耗过大,甚至引发内存溢出问题。

(2)scan指令使用不当,也容易引发性能问题

SCAN 命令的基本语法如下:

代码语言:javascript
代码运行次数:0
运行
复制
SCAN cursor [MATCH pattern] [COUNT count]
  • cursor:游标的初始值为 0,表示开始遍历。每次调用 SCAN 命令后,会返回一个新的游标值,用于下一次迭代。
  • MATCH pattern:可选参数,用于指定匹配的模式,类似于 KEYS 命令中的模式匹配功能。
  • COUNT count:可选参数,用于指定每次迭代返回的 key 的数量。这个值只是一个建议,实际返回的数量可能会有所不同。

代码语言:javascript
代码运行次数:0
运行
复制
scan 命令 时间复杂度为 O(n)
理论上这个O(n) 很多的是靠 count来进行指定. 
并且理论上一个键值对的消耗时间为 1 微秒左右. 

虽然他可以在 count 值的微秒数之内返回, 
但是如果要遍历所有的键值对, 并且多个client同时遍历
那么时间损耗是非常恐怖的. 

又因为redis是单线程io复用的模型. 所以他会导致其他的核心业务卡断. 

如果非必要建议不要使用scan命令, 在高并发,大量key的场景下性能表现并不好.

缓存数据存储优化

  1. 所有的键值对除非有特殊需求,否则一律加上超时时间,避免长期驻留内存
  2. keys和scan慎重使用

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 腾讯云双十一“团战”
  • 前言
    • Redis集群部署
    • Redis监控工具Media
      • 使用说明
    • Redis性能配置参数
      • 配置慢查询日志
      • 缓存数据淘汰策略
      • 淘汰策略选项
      • 策略解释
      • 配置示例
      • 注意事项
    • Redis性能压测demo
      • 并发大字段写入读取压测
      • keys指令和scan指令
      • 缓存数据存储优化
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档