阿里云Redis与Tair压力测评

646 阅读4分钟

无意中发现阿里云开发社区的训练营活动,其中有一个7天玩转Redis、tair训练营计划,里面可以免费领取三个月的试用礼包,因为是参营任务,不领取都不行的那种,领取之后放着也是放着,不如跑跑数据看看Redis和Tair的性能有什么区别,简单的压力测试下,本次测试并不精确,也不具有太多参考意义,真的就是为了测试而测试。

活动地址链接见最下面的

什么是Tair

这里有具体介绍Tair的视频,里面详细介绍了阿里云Redis和自建Redis的对比分析

edu.aliyun.com/course/3114…

测试工作

本次没有使用Redis自带的Redis Benchmark工具,想着为了测试而测试,就为了测试而开发吧。

一:准备工作

  1. 领取Redis与Tair三个月免费额度
  2. 编写压力测试代码
  3. 准备测试数据。

二:测试方案设计

  1. 批量插入数据查看总体时延,与不同数据量下时延曲线表,记录总体耗时
  2. 批量数据查询,记录查询QPS,内存情况,网络流量等
  3. 将数据库内存空间打满后,查看相同淘汰策略下内容优化情况

三:进行压力测试

  1. 先进行功能测试,校验系统功能在高负载下是否正常。
  2. 加大并发用户数或请求流量,模拟峰值压力情况。
  3. 观察记录关键指标,分析系统瓶颈。

四:机器指标

为了去除本地机器、网络带来的干扰,这次的代码都会运行在ECS服务器中,但自己的ECS服务器都不是杭州区的,还是要通过外网域名的形式连接Redis、Tair,不过数据传输速率也是可靠的。

RedisTairECS服务器1ECS服务器1
规格2 GB 增强版 (vCPU shared)2 GB 增强版 (vCPU shared)4C8G4C8G
最大连接数10,00030,000
最大带宽96 MB/s96 MB/s
参考QPS100,000300,000
副本数2副本2副本
分片数量11
Redis版本Redis 5.0版本兼容性:Redis 6.0
存储空间10G10G
架构类型非集群非集群
maxmemory-policyvolatile-lru (按照LRU算法逐出原有数据,但仅逐出设置了过期时间的数据)volatile-lru (按照LRU算法逐出原有数据,但仅逐出设置了过期时间的数据)

五:运行代码:

package org.rain;

import redis.clients.jedis.*;

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

public class Main {

    public static void readTxtFile(String filePath, JedisPool pool) {
        try {
            File file = new File(filePath);
            if (file.isFile() && file.exists()) {
                InputStreamReader isr = new InputStreamReader(Files.newInputStream(file.toPath()), StandardCharsets.UTF_8);
                BufferedReader br = new BufferedReader(isr);
                String lineTxt = null;
                AtomicInteger i = new AtomicInteger();
                ExecutorService executorService = new ThreadPoolExecutor(50, 50, 100L, TimeUnit.MILLISECONDS, new SynchronousQueue<Runnable>(), new ThreadPoolExecutor.CallerRunsPolicy());

                while ((lineTxt = br.readLine()) != null) {
                    String[] textArr = lineTxt.split("\t");
                    if (textArr.length <= 6) {
                        continue;
                    }
                    executorService.submit(() -> {
                        try (Jedis jedis = pool.getResource()) {
                            jedis.setex(textArr[0] + "-" + i.getAndIncrement(), 14400, textArr[6]);
                            //                            System.out.println("已处理第" + i);
                        }
                    });
                    executorService.submit(() -> {
                        try (Jedis jedis = pool.getResource()) {
                            jedis.setex(textArr[1] + "-" + i.getAndIncrement(), 14400, textArr[6]);
                            //                            System.out.println("已处理第" + i);
                        }
                    });
                }
                System.out.println("处理完毕,共处理:" + i);
                executorService.shutdown();
                br.close();
            } else {
                System.out.println("文件不存在!");
            }
        } catch (Exception e) {
            System.out.println("文件读取错误!" + e);
        }
    }

    public static void main(String[] args) {
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxIdle(200);
        config.setMaxTotal(300);
        config.setTestOnBorrow(false);
        config.setTestOnReturn(false);
        String redisHost = "r-.redis.rds.aliyuncs.com";
        String redisUser = "r-";
        String redisPassword = "";
        String tairHost = "r-.redis.rds.aliyuncs.com";
        String tairUser = "r-";
        String tairPassword = "";
        JedisPool pool;
        if ("redis".equals(args[0])) {
            System.out.println("redis");
            pool = new JedisPool(config, redisHost, 6379, redisUser, redisPassword);
        } else {
            System.out.println("tair");
            pool = new JedisPool(config, tairHost, 6379, tairUser, tairPassword);
        }
        String filePath = "local".equals(args[1]) ? "/Users/Downloads/weibo_train_data.txt" : "/home/weibo_train_data.txt";
            System.out.println(filePath);
            readTxtFile(filePath, pool);
            }
            }

六:模拟数据

1229619条微博用户发帖数据

写入性能截图

Redis

Tair

服务器负载

从图里看,在没有调整任何参数的情况下,插入250w条数据,Redis和Tair基本没有太大的区别,只是Tair的平均时延有些高,两者的QPS都能达到1000,还没有跑满官方的参考值。

读取测试截图

代码

public static void getTxtFile(String filePath, JedisPool pool) {
    try {
        File file = new File(filePath);
        if (file.isFile() && file.exists()) {
            InputStreamReader isr = new InputStreamReader(Files.newInputStream(file.toPath()), StandardCharsets.UTF_8);
            BufferedReader br = new BufferedReader(isr);
            String lineTxt = null;
            AtomicInteger i = new AtomicInteger();
            ExecutorService executorService = new ThreadPoolExecutor(50, 50, 100L, TimeUnit.MILLISECONDS, new SynchronousQueue<Runnable>(), new ThreadPoolExecutor.CallerRunsPolicy());

            while ((lineTxt = br.readLine()) != null) {
                String[] textArr = lineTxt.split("\t");
                if (textArr.length <= 6) {
                    continue;
                }
                executorService.submit(() -> {
                    try (Jedis jedis = pool.getResource()) {
                        System.out.println(jedis.get(textArr[0] + "-" + i.getAndIncrement()));
                    }
                });
                executorService.submit(() -> {
                    try (Jedis jedis = pool.getResource()) {
                        System.out.println(jedis.get(textArr[1] + "-" + i.getAndIncrement()));
                    }
                });
            }
            System.out.println("处理完毕,共处理:" + i);
            executorService.shutdown();
            br.close();
        } else {
            System.out.println("文件不存在!");
        }
    } catch (Exception e) {
        System.out.println("文件读取错误!" + e);
    }
}

Redis

Tair

总结

通过监控报表的分析,主要的差距还是在平均时延上,在并发50情况下,QPS达到1000左右时,redis的平均时延要比Tair低很多,写入和读取时延都有所差距。其他的两者完全相似。

developer.aliyun.com/trainingcam…