暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

[译文] PostgreSQL vs Redis vs Memcached 性能

原创 卡雷尔·莫佩尔 2021-08-12
2710

当我最近偶然发现一篇文章比较了一些主要属性,以及两个非常流行的缓存软件的读写性能时,我立即感到心动 - 它实际上看起来如何在性能方面,PostgreSQL vs Redis vs Memcached?意思是,如果你只是跳过缓存并直接访问数据库。

尤其是在第一次看之后,我对 Redis 和 Memcache 的数字实际上并没有留下太深刻的印象。也可能是因为从链接论文中提取的实际测试数据来自 2016 年——这肯定是“互联网年”的年龄。无论哪种方式,我都很想获得某种比较点,并迅速用 Python 编写了一个小型基准测试脚本,让我的工作站开始工作。

如果原始测试使用 Java,您可能会问为什么使用 Python?好吧,Java 只是我最不喜欢的数据库项目语言之一,而且我的印象是 Python 在 Web 和临时数据库脚本中都非常流行,所以可能很适合这里——当然可能是错误的那。

测试设置

我的测试设置的一些特征:

  • AMD Ryzen 3600 CPU 设置为性能模式。我的测试脚本本质上是同步的,即基本上使用单个 CPU 内核,所以速度可能很重要。
  • Ubuntu 20.04 桌面作为操作系统,禁用交换。
  • PostgreSQL v13.3,即最新的。
  • 默认 PostgreSQL 配置,除了“shared_buffers=512MB”、“track_io_timing=on”、“shared_preload_libraries=‘pg_stat_statements’”。
  • 用于系统和数据库的单个 NVMe SSD。
  • 使用准备好的语句读取/写入 Postgres 以获得最佳查询性能,避免解析后续调用。
  • 完全适合 PostgreSQL 管理缓存(共享缓冲区)的数据集大小。
  • 异步模式用于写入数据,这意味着在服务器崩溃/重新启动的情况下,最近的数据可能会略有丢失,作为更多写入(尤其是在小事务中)性能的权衡。但这与 Redis 和 Memcached 默认处理写入的方式一致。但是,使用 Redis,还可以启用 AOF 持久性以获得 PostgreSQL 默认行为。
  • 两个读/写测试都从 1 到$rows一一遍历所有插入的随机生成的浮点数据键。不过,最初的测试并没有提到确切的访问模式。
  • 键值表在读取测试之前被提取到 Postgres 缓存中,因此不会像 Redis/Memcached 那样有冷缓存效应。
  • 我没有测量 Postgres 的内存使用情况,因为在插入和缓存所有数据之后,对于这个用例,这预计会非常稳定。
  • 执行时间记录在应用程序端,并调用系统时钟以匹配原始测试。请注意,我决定从服务器端测量执行时间也是为了更好地了解“浪费”的数量,因为毕竟 Python 并不是性能测试的最佳选择,原因有很多,我不想在这里深入研究. 再往前走一点——结果确实非常可怕,人们不应该使用 Python 来对数据库进行基准测试——很多 CPU 时间就在某处消失了!
  • 完整的测试脚本可在此处获得。运行大约需要 10-15 分钟。基本上是这样的:
CREATE UNLOGGED TABLE kv_test(key text, value int);
CREATE INDEX ON kv_test (key);
 
-- pseudo-code from the Python script
for $ROWS in [1000, 10000, 100000, 1000000]:
  truncate kv_test
  generate $ROWS random values
  for $i := 1 .. $ROWS:
    insert $key into kv_test ($rand[i], $rand[i])
  vacuum analyze the table
  for $i := 1 .. $ROWS:
    select * from kv_test where key = $rand[i]

PostgreSQL vs Redis vs Memcached:写操作

以与原始数字类似的方式表示。写入键值对的计算时间以毫秒为单位。

记录数
数据库 1,000 10,000 100,000 1,000,000
Redis (v3.0.7) 34 214 1,666 14,638
Memcached (v1.4.14) 23 100 276 [ 2,813
PostgreSQL (v13.3) 29.6 304 2,888 31,230

PostgreSQL vs Redis vs Memcached:读操作

计算的读取键值对的时间(毫秒)。

记录数
数据库 1,000 10,000 100,000 1,000,000
Redis (v3.0.7) 8 6 8 8
Memcached (v1.4.14) 9 14 14 30
PostgreSQL (v13.3) 0.026 0.028 0.027 0.029

结论

简而言之——对于 Postgres 的阅读测试来说,这些数字看起来非常好!我无法想象原始测试是如何在整个数据集的随机密钥读取中获得如此高的个位数毫秒结果的。对于我的测试,我只看到了最大行数的 1ms+ 最坏情况。顺便说一下,这些数据也可以在名为“results”的“pg_stat_statements”快照表中查找。

很遗憾,我仍然不能太欣喜若狂,因为关于原始测试的确切执行方式的细节缺失了很多信息,所以最终可能还是有点“苹果到橙子”的情况,我耽心。与 Postgres 相比,Redis/Memcached 的平均键读取时间似乎太慢了。我怀疑他们仍然使用远程机器作为缓存,尽管论文没有提到它并讨论了单个 Core i7 节点。

但是关于键值数据的写入速度——好吧:Postgres 并没有真正在更高的行数上竞争。🙁 但这也或多或少在意料之中!为什么?像 Postgres 这样成熟的关系数据库引擎不遗余力地确保我们不能插入违反某些约束的无效数据,加上 WAL 写入(尽管对于未记录的表来说是最小的,但仍然如此)和磁盘格式开销——内部列、对齐,页面拆分时的一些索引膨胀等。所有这些都会放大写入!所以基本上,我认为最终的结果仍然不错。对于 100k 和 1M 行计数,仅比 Redis 慢 2 倍。缓存的主要思想是,与无论如何写入/更新相比,只有当我们从它们中读取更多内容时,它们才有用!

但是无论是在绝对数量上与其他 DB 的比较如何,很高兴看到 Postgres 对不断增长的数据集的响应的相对稳定性非常非常好!甚至击败了在 100 万行上恶化 2 倍的 Memcached!这一切都可能表明,为 PostgreSQL 选择的算法在数学上是合理的,并且实现得很好!

但可以肯定的是——Postgres 的性能至少对于少量行的“缓存用例”来说绝对足够好。因此,对于您的下一个项目,您可能需要问一问,您真的需要另一个外部组件吗?

或者也许只是:

  1. 向数据库添加更多内存/CPU 并更加努力地敲打它——实际上对于读取来说非常安全;

  2. 使用您的 HA 副本进行负载平衡并实现更好的总资源利用率,并享受在“真正持久化”级别处理关系数据时不必更改思维模型的好处。

其他想法/笔记

  • 再一次——不要忘记:使用的缓存软件现在已经有 5 年的历史了!但同时,即使对于 Postgres,我也仍然保留了一点——例如,当使用相对较新的(v11+)“覆盖”索引功能或什至可能使用哈希时,甚至可以获得稍微更好的读取性能索引。

  • 这篇发人深省的文章实际上很好地说明了这一点:“内存中键值数据存储之间的性能比较更多的是一种智力练习,而不是任何实际重要性 - 除非您部署的系统规模如此之大,以至于这变得有趣节约成本的措施。这是因为此类存储受 IO 限制,并且通常网络延迟在应用程序感知延迟中可能比数据库延迟发挥更大的作用。”。简而言之——不要过多考虑本地测试的毫秒或微秒缓存响应时间。现实生活中的网络延迟可以而且会消耗掉大部分时间!

  • 请注意,从“应用程序端”和“数据库端”测量的查询执行时间之间的差异是巨大的,在行数很少的最坏情况下高达 10 倍!但正如前一章所述——对于现实生活中的数据库应用程序,语言的选择通常与性能无关。

  • 测试的最大行数 100 万在今天的上下文中我认为实际上太小了——即使在具有相对较大磁盘格式的 Postgres 的情况下,数据和索引也只有大约 128MB。我怀疑现在普通的智能手表甚至可以保存更多的数据。

  • 但请注意,Redis 肯定不仅仅是链接文章中提到的简单易失性缓存。然而,在实践中,它主要用作键值存储……Postgres 也可以是,它是一个通用管理系统,没有专门针对特定工作负载进行调整。

  • 成本方面——配置一个有大量内存的功能强大的现代数据库服务器通常比一个简单的“可丢弃”计算节点的成本高得多,尽管可以选择内存优化计算节点。所以使用缓存可能仍然是一个非常好的主意。

  • 如果您需要非常努力地锤击它们,专用缓存总是会表现得更好——因为通常没有权限检查、会话、快照、复杂的锁定场景等。

  • 请注意,在某些情况下,您还可以使用完全透明的 PostgreSQL 缓存!这是可悲的不是一个内置的Postgres的功能,但例如,比较流行的连接池软件,这些小块称为pgpool2之一将它作为一个额外的功能,因此可能是值得检查出。

文章来源:https://www.cybertec-postgresql.com/en/postgresql-vs-redis-vs-memcached-performance/

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论