我有大约20亿的键值对,我想有效地将它们加载到redis上。我当前正在使用python并使用了redis-py记录的Pipe,但是我无法找到加载到redis上的任何加速
我有以下代码加载到python中的redis
import redis
def load(pdtDict):
redIs = redis.Redis()
pipe = redIs.pipeline()
for key in pdtDict.keys():
pipe.hmset(self.seller+":"+str(key),pdtDict[key])
pipe.execute()
其中pdtDict包含要存储在redis上的键值对的字典
任何想法或帮助???
答案 0 :(得分:5)
关于问题和示例代码的几点。
流水线不是灵丹妙药 - 您需要在使用之前了解它的作用。流水线操作的作用是批量发送作为批量发送的多个操作,以及它们从服务器发出的响应。您获得的是每个操作的网络往返时间由批次的网络往返时间替换。但无限大小的批次是资源的真正消耗 - 你需要保持它们的大小足够有效。根据经验,我通常会尝试以每个管道60KB为目标,并且由于每个数据都不同,管道中的实际操作数也是如此。假设您的密钥及其值大约为1KB,则需要每60次操作调用pipeline.execute()
。
除非我严重误解,否则此代码不应运行。您正在使用HMSET
,就好像它是SET
一样,因此您基本上缺少Hashes的field->值映射。哈希值(HMSET
)和字符串(SET
)是不同的数据类型,因此应该相应使用。
似乎这个小循环负责整个“十亿数据” - 如果是这样的话,不仅运行代码的服务器会像疯了一样交换,除非它有很多RAM保存字典,它也会非常无效(无论Python的速度如何)。您需要通过运行此过程的多个实例来并行化数据插入。
您是否远程连接到Redis?如果是这样,网络可能会限制您的表现。
考虑你的Redis设置 - 假设它确实是一个瓶颈,也许可以调整/调整这些设置以获得更好的性能。
答案 1 :(得分:2)
我希望您也在redis python包旁边安装了hiredis python包。请参阅https://github.com/andymccurdy/redis-py#parsers它也应该会提升性能。
self.seller
做了什么?也许这是一个瓶颈?
正如@Itamar所说,尝试定期执行管道
def load(pdtDict):
redIs = redis.Redis()
pipe = redIs.pipeline()
n = 1
for key in pdtDict.keys():
pipe.hmset(self.seller+":"+str(key),pdtDict[key])
n = n + 1
if (n % 64) == 0:
pipe.execute()
pipe = redIs.pipeline()
答案 2 :(得分:0)
要向Redis提供大量数据,请考虑使用here所述的redis大量插入功能。
为此,您需要访问redis-cli。
答案 3 :(得分:0)
您可以在管道模式下使用redis-cli,首先准备一个类似的文件(请注意,这些行应以cr / lf终止,或由-d <dilimiter>
选项设置):
SET Key0 Value0
SET Key1 Value1
...
SET KeyN ValueN
然后将其传输到redis-cli:
cat data.txt | redis-cli --pipe
答案 4 :(得分:0)
另一个考虑因素是,如果满足以下条件(来自Redis Labs),则在管道构造中设置<figure>
<img src="{{ include.url }}" alt="{{ include.description }}">
<figcaption>Photo by <a href="{{ include.authorurl }}">{{ include.author }}</a></figcaption>
</figure>
有助于提高性能:
对于需要向Redis发送多个命令的情况, 一个命令的结果不会影响到另一个命令的输入,我们 不需要它们全部以事务方式执行,只需将False传递给 pipeline()方法可以进一步提高整体Redis性能。