如何高效地插入十亿数据进行Redis?

2024-06-01 04:49:17 发布

您现在位置:Python中文网/ 问答频道 /正文

我有大约20亿个键值对,我想把它们高效地加载到Redis中。我目前正在使用Python,并使用了由redis-py所记录的管道。我怎样才能加快下一步的速度?

import redis

def load(pdt_dict):
    """
    Load data into redis.

    Parameters
    ----------
    pdt_dict : Dict[str, str]
        To be stored in Redis
    """
    redIs = redis.Redis()
    pipe = redIs.pipeline()
    for key in pdt_dict.keys():
        pipe.hmset(self.seller + ":" + str(key), pdt_dict[key])
    pipe.execute()

Tags: keyinpyimportredis管道记录速度
3条回答

我希望您在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()

可以在管道模式下使用redis cli,首先准备一个类似的文件(注意,这些行应该以cr/lf结尾,或者由-d <dilimiter>选项设置):

SET Key0 Value0
SET Key1 Value1
...
SET KeyN ValueN

然后通过管道将其发送到redis cli:

cat data.txt | redis-cli --pipe

https://redis.io/topics/mass-insert

关于问题和示例代码的几点。

  1. 流水线不是灵丹妙药,你需要在使用它之前了解它的作用。流水线所做的是成批处理几个作为批量发送的操作,以及它们来自服务器的响应。您得到的结果是,每个操作的网络往返时间被批处理的往返时间所代替。但是无限大小的批处理是一个真正的资源消耗-你需要保持他们的大小足够小,以有效。根据经验,我通常尝试每个管道60KB,因为每个数据都不同,所以管道中的实际操作数也不同。假设您的密钥及其值为~1KB,则需要每隔60次左右调用pipeline.execute()

  2. 除非我严重误解,否则这段代码不应该运行。您使用的是HMSET,就好像它是SET,所以基本上缺少散列的字段值映射。散列(HMSET)和字符串(SET)是不同的数据类型,因此应该相应地使用它们。

  3. 似乎这一个小循环负责整个“十亿数据”——如果是这样的话,运行代码的服务器不仅会疯狂地交换代码,除非它有大量的RAM来保存字典,否则它也会非常无效(不管Python的速度如何)。您需要通过运行此进程的多个实例来并行化数据插入。

  4. 你在远程连接Redis吗?如果是这样,网络可能会限制您的性能。

  5. 考虑一下你的Redis设置——假设它确实是一个瓶颈,也许可以对这些设置进行调整,以获得更好的性能。

相关问题 更多 >