Redis 在插入方面似乎比 PostgreSQL 慢
Redis seems slower than PostgreSQL on inserts
我目前正在做一个项目,我们考虑切换到 Redis 作为数据库。我们的数据性质非常简单,似乎适合 Redis。
在没有 Redis 经验的情况下,我做了一个非常小的基准测试,以在插入性能(这对我们很重要)方面将其与 PostgreSQL 进行比较。
我创建了一个 .sql 文件,其中包含 200000 个 INSERT 语句到一个简单的模式 (address [key], timestamp, value)
。插入大约用了 6 秒。
对于 Redis,每 200000 条记录的插入方式是:
HSET data:address timestamp <VALUE>
HSET data:address value <VALUE>
使用 time redis-cli < insert_data.redis
将所有内容转储到 Redis 需要 16 秒。
我意识到这个 'benchmark' 是非常基本的,但是我是否遗漏了一些让 PostgreSQL 脱颖而出的东西?我真的无法想象 Redis 在插入时实际上更慢。
这个结果合乎逻辑。要了解基准测试的结果,了解系统上触发的操作很重要。
Redis 和 PostgreSQL 客户端都与各自的服务器同步工作。对于每个语句,他们发送一个查询并在处理下一个语句之前等待回复。
在这样的卷上,内存中发生了很多事情(即使使用 PostgreSQL)。此外,您在这里没有并发性。因此,操作的成本不是由 I/Os 或索引决定的,而是由客户端和服务器之间交换的往返成本决定的。
现在,每个测试生成多少次往返?
使用 PostgreSQL,每条记录一个语句,导致 200000 次往返。使用 Redis,每条记录有两个语句,导致 400000 次往返。此外,Redis 往返系统地包括您的模式的关键字(数据、时间戳、值),并且地址每条记录发送两次。所以Redis测试交换了很多数据。
您可能还对客户端软件解析输入文件的方式有所不同。
要使用 redis-cli 提高一点结果,您可以使用命令 HMSET 每条记录只发送一条语句。
HSET data:address timestamp <VALUE>
HSET data:address value <VALUE>
变成:
HMSET data:address timestamp <VALUE> value <VALUE>
但这里真正的收获是使用 pipelining. Unfortunately, you cannot use it from redis-cli, except by relying on the --pipe option. For this option, you have to generate the actual Redis protocol instead of textual commands. That's why your test with "cat data.txt | redis-cli --pipe" cannot work. Generating Redis protocol 来自简单的 shell 命令并不方便。
对于这样的基准测试,我强烈建议使用您自己的客户端程序而不是 redis-cli。如果使用流水线,即使是用 Python、Ruby 或 Javascript 编写的内容也会产生有趣的性能。
我目前正在做一个项目,我们考虑切换到 Redis 作为数据库。我们的数据性质非常简单,似乎适合 Redis。 在没有 Redis 经验的情况下,我做了一个非常小的基准测试,以在插入性能(这对我们很重要)方面将其与 PostgreSQL 进行比较。
我创建了一个 .sql 文件,其中包含 200000 个 INSERT 语句到一个简单的模式 (address [key], timestamp, value)
。插入大约用了 6 秒。
对于 Redis,每 200000 条记录的插入方式是:
HSET data:address timestamp <VALUE>
HSET data:address value <VALUE>
使用 time redis-cli < insert_data.redis
将所有内容转储到 Redis 需要 16 秒。
我意识到这个 'benchmark' 是非常基本的,但是我是否遗漏了一些让 PostgreSQL 脱颖而出的东西?我真的无法想象 Redis 在插入时实际上更慢。
这个结果合乎逻辑。要了解基准测试的结果,了解系统上触发的操作很重要。
Redis 和 PostgreSQL 客户端都与各自的服务器同步工作。对于每个语句,他们发送一个查询并在处理下一个语句之前等待回复。
在这样的卷上,内存中发生了很多事情(即使使用 PostgreSQL)。此外,您在这里没有并发性。因此,操作的成本不是由 I/Os 或索引决定的,而是由客户端和服务器之间交换的往返成本决定的。
现在,每个测试生成多少次往返?
使用 PostgreSQL,每条记录一个语句,导致 200000 次往返。使用 Redis,每条记录有两个语句,导致 400000 次往返。此外,Redis 往返系统地包括您的模式的关键字(数据、时间戳、值),并且地址每条记录发送两次。所以Redis测试交换了很多数据。
您可能还对客户端软件解析输入文件的方式有所不同。
要使用 redis-cli 提高一点结果,您可以使用命令 HMSET 每条记录只发送一条语句。
HSET data:address timestamp <VALUE>
HSET data:address value <VALUE>
变成:
HMSET data:address timestamp <VALUE> value <VALUE>
但这里真正的收获是使用 pipelining. Unfortunately, you cannot use it from redis-cli, except by relying on the --pipe option. For this option, you have to generate the actual Redis protocol instead of textual commands. That's why your test with "cat data.txt | redis-cli --pipe" cannot work. Generating Redis protocol 来自简单的 shell 命令并不方便。
对于这样的基准测试,我强烈建议使用您自己的客户端程序而不是 redis-cli。如果使用流水线,即使是用 Python、Ruby 或 Javascript 编写的内容也会产生有趣的性能。