性能文章>【译】如果把MySQL当成Redis用,和Redis本身比性能如何?>

【译】如果把MySQL当成Redis用,和Redis本身比性能如何?转载

2年前
392815

这是我围绕UUID集缓存的“研究”的一部分。基准测试了Map Performance Java与Scala二进制搜索而不是HashSet,甚至将Set缓存移动到Redis。现在是时候将MySQL作为此类缓存进行基准测试了。

我知道这是一个愚蠢的基准。但就整个情况而言:)希望我不会用它来衡量其他不成程序的东西。

不过,我还是想再测试一件与JDBC有关的事情,如果感兴趣的同学可以看一看!

我们在测试什么?

我的用例很简单——我有一大套内存UUID,大约100万个密钥。这就是我将其存储在MySQL中的方式:

CREATE TABLE set1m (
  id BINARY(16) NOT NULL PRIMARY KEY
) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;

将UUID转换为BINARY(16)代码(这只是JDBC中的字节数组):

public static byte[] toBytes(UUID value) {
    byte[] array = new byte[16];
    ByteBuffer bb = ByteBuffer.wrap(array);
    bb.putLong(value.getMostSignificantBits());
    bb.putLong(value.getLeastSignificantBits());
    return array;
}

基准

基准代码相对简单:N线程逐一获取UUID并进行简单的查询:

SELECT 1 FROM set1m WHERE id = ?

我把一个线程的基准测试为10个线程。

调味!

一段时间以来,我一直在想连接池的开销。在Wix,我们不久前开始使用HikariCP

我们和一位朋友讨论了这个问题,他声称在屏蔽环境中使用连接池是不明智的,你可以简单地使用具有连接和一些家政服务的线程本地人,这样会更有效率。

当然,这种方法存在一些问题:

  • 如果Jetty(或任何其他servlet容器)使用池中的所有线程,那么我们将使用比实际应该使用更多的连接。
  • 管家很棘手。此外,无法预热连接,或者至少不简单(启动时发出HTTP调用?)

无论如何,在基准测试中,这是一个很好的机会,可以实际检查它,而无需编写复杂的连接内部管理代码等。因此,这就是我所做的:将HikariCP与预热连接与存储在ThreadLocal中的预热连接进行了比较。

结果

中位查询时间并不真正取决于表的大小。然而,10M表略慢(几微秒):

带有3条线的线图,适用于3种不同的设置尺寸:100K、1M、10M。

相反,最大查询时间似乎有点取决于表大小。我想知道为什么?我把innodb_buffer_pool_size设置为1G,这比表大小大。

带有3条线的线图,适用于3种不同的设置尺寸:100K、1M、10M。

HikariCP vs Thread Local

线程本地的中位时间始终更好,相差3-8微秒。这对于查询本地主机来说大约是10%,但通常我们通过网络查询MySQL,因此它将是开销的1%或更少。不是很好,也不可怕。

带有2行的hikari和线程本地连接池的线图

MySQL vs Redis

可以预见,Redis的性能优于MySQL。尽管MySQL中的数据集真的很小(数百兆字节),但SQL的开销似乎太重要了。

Redis和MySQL有2行的线图

如果我们查看请求的最大持续时间,情况就更糟了。这意味着MySQL消耗的CPU比Redis多得多:

Redis和MySQL有2行的线图

结论

当然,MySQL根本不适合这个用例。这很有道理,MySQL的优势不在于稳定性、复制、事务等。

对MySQL的不同方面进行基准测试很有趣(像往常一样)。我也很高兴我不需要为线程本地连接池编写家政代码来基准测试它(我想我的积压已经超过4年了),因为我宁愿探索对MySQL的异步访问,而不是阻止。

MySQLMySQL与Redis的完整数据和图表。源代码在GitHub上。

原文作者:Dmitry Komanov

点赞收藏
willberthos

keep foolish!

请先登录,查看1条精彩评论吧
快去登录吧,你将获得
  • 浏览更多精彩评论
  • 和开发者讨论交流,共同进步
5
1