2016-12-15 120 views
1

我目前正在研究一个项目,我们考虑将其切换为Redis作为数据库。我们的数据的性质非常简单,似乎适用于Redis。 没有Redis的经验,我做了一个非常小的基准测试,将其与PostgreSQL在插入性能(这对我们很重要)方面进行比较。Redis在插入时似乎比PostgreSQL慢

我创建了一个包含200000个INSERT语句的.sql文件,并将其写入一个简单模式(address [key], timestamp, value)。插入花费了大约6秒钟。

对于Redis的,每个200000条记录由插入:

HSET data:address timestamp <VALUE> 
HSET data:address value <VALUE> 

倾倒到一切Redis的与time redis-cli < insert_data.redis需要16秒。 我意识到这个'基准'是非常基本的,但我错过了让PostgreSQL出现在顶端的东西吗?我无法真正想象Redis实际上插入速度较慢。

+0

PostgreSQL需要多长时间?你是否尝试过流水线请求?客户端开销可能会降低整体时间。 –

+0

这是6s(Redis)vs 16s(PostgreSQL)。我试过'猫的数据。txt | redis-cli --pipe'首先,因为这是在这里描述:https://redis.io/topics/mass-insert,似乎更合理。但是,上面显示的HSET语句不被接受,而是我接收到语法错误消息。 – user318592009

+0

什么是错误? –

回答

2

这个结果是合乎逻辑的。要了解基准的结果,了解系统触发的操作很重要。

Redis和PostgreSQL客户端都与其各自的服务器同步工作。对于每条语句,他们都会在处理下一条语句之前发送查询并等待答复。

在这样的数量上,很多事情都发生在内存中(即使使用PostgreSQL)。而且,你在这里没有并发性。因此,操作成本不受I/O或索引支配,而是通过客户端和服务器之间的往返交换。

现在,每个测试会产生多少往返?

使用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。不幸的是,除了依靠--pipe选项外,你不能在redis-cli中使用它。对于这个选项,你必须生成实际的Redis协议,而不是文本命令。这就是为什么你使用“cat data.txt | redis-cli --pipe”的测试无法工作的原因。从简单的shell命令生成Redis protocol不方便。

对于这样的标杆,我会强烈建议使用自己的客户端程序,而不是Redis的-CLI。即使是一些写在Python和Ruby或JavaScript将导致有趣的表现提供采用流水线方式。

+0

感谢您的详细解释,真的有所帮助。我偶然发现了Redis协议,但对我来说似乎非常困惑,我不知道如何翻译HSET或HMSET命令。正如你所建议的那样,我将切换到一个小型的Python客户端,并为PostgreSQL做同样的工作来平衡游戏领域。 – user318592009