我有大约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()
5条答案
按热度按时间llew8vvj1#
关于问题和示例代码的几点说明。
1.流水线并不是银的--在使用它之前,您需要了解它的作用,流水线的作用是批量发送多个操作,您所得到的是,每个操作的网络往返时间被批处理的网络往返时间所取代。但是,无限大的批处理真实的会消耗资源-你需要让它们的大小足够小才能有效。2作为一个经验法则,我通常会把每个流水线的目标定在60 KB,因为每个数据都是不同的,所以流水线中实际操作的数量也是不同的。3假设你的键和它的值是~ 1 KB,需要每隔60次左右调用
pipeline.execute()
。1.除非我严重误解了,否则这段代码不应该运行。您使用
HMSET
就好像它是SET
一样,所以您基本上忽略了哈希的字段-〉值Map。哈希(HMSET
)和字符串(SET
)是不同的数据类型,因此应该相应地使用。1.看起来这一个小循环负责整个“十亿数据”--如果是这样的话,运行代码的服务器不仅会像疯了一样交换,除非它有很多RAM来保存字典,而且效率也会很低(不管Python的速度如何)。
1.您是否正在远程连接Redis?如果是,网络可能会限制您的性能。
1.考虑一下你的Redis的设置--假设这确实是一个瓶颈,也许这些设置可以被调整/调优以获得更好的性能。
2exbekwf2#
您可以在管道模式下使用
redis-cli
。1.首先,您准备一个文件,如下所示(请注意,这些行应通过cr/lf终止或通过
-d <delimiter>
选项设置):1.然后将其序列化转换为Redis RESP格式(例如,作为一个带引号的字符串,参见docs)。
1.最后,将其通过管道传输到
redis-cli
(使用--pipe
参数):fumotvh33#
另一个注意事项是,在管道构造中设置
transaction=False
有助于提高性能,前提是满足以下条件(从Redis Labs开始):如果我们想向Redis发送多个命令,一个命令的结果不会影响另一个命令的输入,并且我们不需要所有命令都以事务方式执行,那么向pipeline()方法传递False可以进一步提高Redis的整体性能。
q3aa05254#
我希望你已经安装了hiredis python软件包和redis python软件包。请参见https://github.com/andymccurdy/redis-py#parsers。它也会给予你带来性能提升。
self.seller
做了什么?也许这是一个瓶颈?正如@Itamar所说,尝试定期执行管道
kognpnkq5#
要向Redis提供大量数据,可以考虑使用Redis的海量插入功能here。
要使此功能正常工作,您需要访问redis-cli。