无意中发现阿里云开发社区的训练营活动,其中有一个7天玩转Redis、tair训练营计划,里面可以免费领取三个月的试用礼包,因为是参营任务,不领取都不行的那种,领取之后放着也是放着,不如跑跑数据看看Redis和Tair的性能有什么区别,简单的压力测试下,本次测试并不精确,也不具有太多参考意义,真的就是为了测试而测试。
活动地址链接见最下面的
什么是Tair
这里有具体介绍Tair的视频,里面详细介绍了阿里云Redis和自建Redis的对比分析
https://edu.aliyun.com/course/3114106/lesson/19637
测试工作
本次没有使用Redis自带的Redis Benchmark工具,想着为了测试而测试,就为了测试而开发吧。
一:准备工作
- 领取Redis与Tair三个月免费额度
- 编写压力测试代码
- 准备测试数据。
二:测试方案设计
- 批量插入数据查看总体时延,与不同数据量下时延曲线表,记录总体耗时
- 批量数据查询,记录查询QPS,内存情况,网络流量等
- 将数据库内存空间打满后,查看相同淘汰策略下内容优化情况
三:进行压力测试
- 先进行功能测试,校验系统功能在高负载下是否正常。
- 加大并发用户数或请求流量,模拟峰值压力情况。
- 观察记录关键指标,分析系统瓶颈。
四:机器指标
为了去除本地机器、网络带来的干扰,这次的代码都会运行在ECS服务器中,但自己的ECS服务器都不是杭州区的,还是要通过外网域名的形式连接Redis、Tair,不过数据传输速率也是可靠的。
Redis |
Tair |
ECS服务器1 |
ECS服务器1 |
|
规格 |
2 GB 增强版 (vCPU shared) |
2 GB 增强版 (vCPU shared) |
4C8G |
4C8G |
最大连接数 |
10,000 |
30,000 |
||
最大带宽 |
96 MB/s |
96 MB/s |
||
参考QPS |
100,000 |
300,000 |
||
副本数 |
2副本 |
2副本 |
||
分片数量 |
1 |
1 |
||
Redis版本 |
Redis 5.0 |
版本兼容性:Redis 6.0 |
||
存储空间 |
10G |
10G |
||
架构类型 |
非集群 |
非集群 |
||
maxmemory-policy |
volatile-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(), 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(), 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低很多,写入和读取时延都有所差距。其他的两者完全相似。