Redis如何大批量处理数据

情景(面试题)

有些时候,Redis实例需要装载大量用户在短时间内产生的数据。该怎么做?

分析

如果我们直接循环要插入的数据,每一条数据通过set方法插入数据库,这势必会消耗大量的网络连接和耗时。

解决方法

1.管道(pipe)

就是把n个命令通过一个pipe发送到服务器端,服务器端处理完成以后再返回一个响应结果。而一条一条set需要n次请求n次处理n次响应,而管道只要一次请求n次处理一次响应。由此可以见,pipe不是原子性的。

    JedisPool jedisPool = new JedisPool(new JedisPoolConfig(), "127.0.0.1", 6379);
    Jedis jedis = jedisPool.getResource();
    long start = System.currentTimeMillis();
    Pipeline pipeline = jedis.pipelined();
    for (int i = 0; i < 1000000; i++) {
        pipeline.set("Key" + i, "Value" + i);
    }

    pipeline.sync();
    long end = System.currentTimeMillis();
    System.out.println(end - start);

优点:减少网络耗时。
弊端:不是原子操作。需要适当去处理每个pipe传输命令的多少,因为会在回复这个pipe的返回值,会占有大量内存。

2.通过pipe mode模式

这种方式需要手动生成Redis命令集合。然后使用cat data.txt | redis-cli --pipe 命令在客户端命令行执行。

测试脚本:
#! /bin/bash/

for((i=1;i<=1000000;i++))
    do
    echo "SET key${i} value${i}" >> redis.txt 
done
startTime=`date +'%s'`
cat redis.txt | redis-cli --pipe -a password
endTime=`date +'%s'`
echo ${endTime}
echo `expr ${endTime} - ${startTime}` >>time

优点:很快。通过上面两个执行100w条命令,pipe-mode执行大约是3s,pipe命令是5.4s。(官网)大量插入数据的同时又需要执行其他新命令时,这时读取数据的同时需要确保请可能快的的写入数据。
缺点:可能需要手动生成命令集合的文本。

猜你喜欢

转载自blog.csdn.net/hongchenshijie/article/details/105673511
今日推荐