9

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

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

5 回答 5

18

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

  1. 流水线不是灵丹妙药——您需要在使用它之前了解它的作用。流水线的作用是批量发送多个操作,以及它们从服务器的响应。您获得的是每个操作的网络往返时间都被批处理的时间所取代。但是无限大的批次是真正的资源消耗——你需要保持它们的大小足够小才能有效。根据经验,我通常尝试将每个管道的目标设置为 60KB,并且由于每个数据都不同,因此管道中实际操作的数量也是如此。假设您的键及其值约为 1KB,您需要pipeline.execute()每 60 次左右调用一次。

  2. 除非我严重误解,否则这段代码不应该运行。你正在使用HMSETSET,所以你基本上错过了哈希的字段->值映射。哈希 ( HMSET) 和字符串 ( SET) 是不同的数据类型,因此应相应地使用。

  3. 看起来好像这个小循环负责整个“十亿数据” - 如果是这种情况,那么运行代码的服务器不仅会像疯了一样交换,除非它有很多内存来保存字典,它也将非常无效(无论 Python 的速度如何)。您需要通过运行此过程的多个实例来并行化数据插入。

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

  5. 考虑您的 Redis 设置 - 假设它确实是一个瓶颈,也许可以调整/调整这些设置以获得更好的性能。

于 2015-08-23T09:25:22.550 回答
4

您可以在管道模式下使用 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

于 2019-05-04T19:56:04.393 回答
1

另一个考虑因素是,如果以下条件适用(来自Redis Labstransaction=False ),则在管道构造中进行设置有助于提高性能:

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

于 2019-08-30T18:19:59.397 回答
1

我希望你也已经在 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()
于 2015-08-29T14:47:44.180 回答
0

要向 Redis 提供大量数据,请考虑使用此处描述的 redis 批量插入功能。

为此,您需要有权访问 redis-cli。

于 2018-05-01T03:57:20.267 回答