Python 如何高效地向Redis插入数十亿数据?

Python 如何高效地向Redis插入数十亿数据?,python,redis,redis-py,Python,Redis,Redis Py,我有大约20亿个键值对,我想高效地将它们加载到Redis中。我目前正在使用Python,并使用了由。如何加快以下方法的速度 import redis def load(pdt_dict): """ Load data into redis. Parameters ---------- pdt_dict : Dict[str, str] To be stored in Redis """ redIs = redis.Red

我有大约20亿个键值对,我想高效地将它们加载到Redis中。我目前正在使用Python,并使用了由。如何加快以下方法的速度

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()

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

  • 管道不是万能的——在使用它之前,您需要了解它的作用。流水线所做的是批量发送多个操作,以及它们从服务器发出的响应。您得到的是,每个操作的网络往返时间被批处理的网络往返时间所取代。但无限大小的批处理确实会消耗资源——您需要将它们的大小保持在足够小的范围内,以使其有效。根据经验,我通常尝试将每个管道的目标设置为60KB,因为每个数据都是不同的,所以管道中的实际操作数也是不同的。假设您的密钥及其值为~1KB,您需要每隔60次左右调用
    pipeline.execute()

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

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

  • 您是否远程连接到Redis?如果是这样,网络可能会限制您的性能

  • 考虑一下你的Redis设置——假设它确实是一个瓶颈,也许可以对这些设置进行调整/调整,以提高此任务的性能


  • 我希望您已经在redis python包旁边安装了hiredis python包。看,它也应该给你一个性能提升

    卖方自己做了什么?也许这是一个瓶颈

    正如@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考虑使用RIIS海量插入特征描述。


    为此,您需要访问redis cli。

    您可以在管道模式下使用redis cli,首先准备一个文件,如(请注意,行应通过cr/lf终止或通过
    -d
    选项设置):

    然后通过管道将其传输到redis cli:

    cat data.txt | redis-cli --pipe
    

    另一个注意事项是,如果以下条件适用(从),则在管道构造中设置
    transaction=False
    有助于提高性能:

    对于希望向Redis发送多个命令的情况, 一个命令的结果不会影响另一个命令的输入,我们可以 不需要它们都以事务方式执行,将False传递给 pipeline()方法可以进一步提高Redis的整体性能


    实际上,您并没有使用管道。调用
    pipe.hmset
    not
    redIs.hmset
    oops这只是键入中的一个错误….请原谅我的错误….你能指导我如何在这方面实现加速吗???@JohnDeep请提供实际代码然后Hello@ItamarHaber我刚刚更新了完整的函数Better make n=0在if块中。因为问题提到了“十亿”的数据。我认为在这种情况下,保留这么大的计数没有任何用处。您需要在for_循环之后添加一个tailing
    pipe.execute()
    命令,以确保仍然缓存小于64的任何余数
    cat data.txt | redis-cli --pipe