持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第29天,点击查看活动详情
回顾
上文我们说到,对比mysql和redis的读取速度时,当使用程序单线程多次查询,二者表现相差无几,redis以较小的优势胜出。那么我们今天在不同的测试场景下,二者的表现效果又当如何呢?让我们拭目以待吧~
环境配置
今天我们需要测试的包括单线程多次写入、多线程多次读取、多线程写入的情况。
这里新建了一个比较简单的test数据库表,同理在redis中新建了一个key为k1值为1的数据。
具体环境和之前相同,如下所示
虚拟机CentOS7.6 分一核二线程,2G运行内存
mysql-5.7.26 在虚拟机运行
redis-6.2.6 在虚拟机运行
测试数据库hmdp中,test表修改(只有一条数据)
单线程多次更新
废话不多说,直接开始测试耗时,test代码如下
@SpringBootTest
class RedisvsmysqlApplicationTests {
@Resource
private StringRedisTemplate stringRedisTemplate;
@Resource
private TestServiceImpl testService;
@Test
void contextLoads() {
int times = 1;
long start;
long end;
for (int i = 0; i < 6; i++) {
start = System.currentTimeMillis();
for (int j = 0; j < times; j++) {
testService.update().setSql("val = val + 1").eq("id", 1).update();
}
end = System.currentTimeMillis();
System.out.println(times + "次 \t更新mysql数据库耗时" + (end - start) + "ms");
start = System.currentTimeMillis();
for (int j = 0; j < times; j++) {
stringRedisTemplate.opsForValue().increment("k1", 1L);
}
end = System.currentTimeMillis();
System.out.println(times + "次 \t更新redis数据库耗时" + (end - start) + "ms");
times = times * 10;
}
}
}
经过漫长的等待,总算是跑完了,纵向对比发现更新数据确实比查询数据慢了许多倍,十万次的sql更新,耗时已经来到了两分多钟。
横向对比发现redis在更新数据方面比mysql有接近70%的性能提升,效果还是很明显的。
结果了上次的单线程多次查询,和上文的单线程多次更新,我们可以对比发现其中redis在查询时的优势并不明显。但是真实业务场景中同一个用户同时发出大量请求的可能性还是比较小的,那么有点好奇多线程并发查询更新数据库的性能对比又是怎样呢?
多线程多次查询
下面我们就测试下多线程的访问。
首先写两个controller接口用来访问,浏览器上查询测试一下是否可用。
@RestController
@RequestMapping("/test")
public class TestController {
@Autowired
private TestServiceImpl testService;
@Autowired
private StringRedisTemplate stringRedisTemplate;
@GetMapping("/selectRedis")
public String getRedis() {
return "Redis结果" + stringRedisTemplate.opsForValue().get("k1");
}
@GetMapping("/selectMysql")
public String getMysql() {
return "Mysql结果" + testService.getById(1).getVal().toString();
}
}
这里我们使用jmeter来进行测试,设置一秒钟内5000次的并发访问,分别对redis和mysql进行查询,聚合报告如下图
redis的平均耗时居然时mysql的6-7倍,结果确实出人意料啊。我们都知道redis是默认单线程访问的,而mysql不加事务时是可以多线程并发访问到,那么造成这个结果的原因也就呼之欲出了。
那我们再来测试一下多线程修改,先增加两个接口。同样是5000次的并发访问,来看看两个数据库的访问结果吧。
@PostMapping("/updateRedis")
public void updateRedis() {
stringRedisTemplate.opsForValue().increment("k1", 1L);
}
@PostMapping("/updateMysql")
public void updateMysql() {
testService.update().eq("id", 1).setSql("val = val + 1").update();
}
测试结果显示了redis的修改速度基本达到了mysql的30%。
通过以上几种不同场景下的对比测试,其实我们通常说的redis比mysql快,他有一定的局限性,在选择数据库的时候,还是要根据具体业务的类型来选择,并不是说任何业务任何数据redis的效果一定比mysql好,mysql作为数据库界的扛把子,他的自身优化也是十分好的,在对于他不是很在行的数据结构和使用场景时,我们再去考虑引入其他数据库。