Redisは、数百万の高速同時データと百万のデータのインポートをサポートする方法


Redisは読み書き性能が百万毎秒と呼ばれるnosqlデータベースとして機能していますが、実際に使用している間にこの効果が得られないのはなぜですか?どのような要因がRedisの性能に影響を及ぼしているのでしょうか.
       1.機械の性能から見ると、CPU、NIC、ディスクなどは読み書きの性能に影響します.NICから言えば、100 MのNICでRedis 200 M/sの読み書きをサポートするのは、Redisの性能に深刻な影響を与えるに違いありません.
       2.ネットワークから見ると、あなたのネットワークが何度もジャンプして最終的にRedisサーバに到達すると、ネットワークのジャンプによる時間もデータの遅延を生じるため、Redisの性能に影響を与える原因と見なすことができます.
       3.RedisのRESPプロトコルから見ると、RESPプロトコル定義は非常に効率的で読み取り可能であるため、Redisの読み書き性能が向上する.
上記の影響要因について、公式サイトでいくつかのテストデータを提供しました.
Intel(R) Xeon(R) CPU E5520 @ 2.27GHz (with pipelining)
$ ./redis-benchmark -r 1000000 -n 2000000 -t get,set,lpush,lpop -P 16 -q
SET: 552028.75 requests per second
GET: 707463.75 requests per second
LPUSH: 767459.75 requests per second
LPOP: 770119.38 requests per second

Intel(R) Xeon(R) CPU E5520 @ 2.27GHz (without pipelining)
$ ./redis-benchmark -r 1000000 -n 2000000 -t get,set,lpush,lpop -q
SET: 122556.53 requests per second
GET: 123601.76 requests per second
LPUSH: 136752.14 requests per second
LPOP: 132424.03 requests per second

Linode 2048 instance (with pipelining)
$ ./redis-benchmark -r 1000000 -n 2000000 -t get,set,lpush,lpop -q -P 16
SET: 195503.42 requests per second
GET: 250187.64 requests per second
LPUSH: 230547.55 requests per second
LPOP: 250815.16 requests per second

Linode 2048 instance (without pipelining)
$ ./redis-benchmark -r 1000000 -n 2000000 -t get,set,lpush,lpop -q
SET: 35001.75 requests per second
GET: 37481.26 requests per second
LPUSH: 36968.58 requests per second
LPOP: 35186.49 requests per second

上記のテストで物理マシンとクラウド上、pipelineメカニズムを使用するかどうかについては、読み書きデータの性能の差が大きい(より多くのテストデータが見られるhttps://redis.io/topics/benchmarks)のため,大量の高同時読み書きに対してpipelineを採用するメカニズムが性能的に優れていることも分かる.コード上で実現方式を見る
@Autowired
    private StringRedisTemplate stringRedisTemplate;
	
	
	/**
	 *   pipeline   
	 * @param batchSize
	 */
	public void pipeline(int batchSize) {
		List results = stringRedisTemplate.executePipelined(
		  new RedisCallback() {
		    public Object doInRedis(RedisConnection connection) throws DataAccessException {
		      StringRedisConnection stringRedisConn = (StringRedisConnection)connection;
		      for(int i=0; i< batchSize; i++) {
		    	// set key1 value2
		    	// set key2 value2
		        stringRedisConn.set("pipeline"+i, "xxx"+i);
		      }
		    return null;
		  }
		});
		System.out.println("pipeline over. results: "+results);
	}
public void pipeline(int batchSize) {
		Jedis jedis = new Jedis("192.168.1.5", 6379);
		Pipeline p = jedis.pipelined();
		List> list = new ArrayList>();
		long s = System.currentTimeMillis();
		for(int i=0; i< batchSize; i++) {
			Response> r = p.get("pipeline"+i);
			list.add(r);
		}
		System.out.println("write cost:"+(System.currentTimeMillis() - s));
		p.sync();
		list.forEach((e)->{
			System.out.println(e.get());
		});
		System.out.println("read cost:"+(System.currentTimeMillis() - s));
		try {
			p.close();
		} catch (IOException e1) {
			e1.printStackTrace();
		}
		jedis.close();
	}

 
Redisを使用している間に100 Wのデータが生成されている場合は、これらの大量のデータをインポートする必要があります.では、私たちにはどんな方法がありますか?
       1.txtドキュメントを開き、インポートするデータをtxtドキュメントに書き込む
SET Key0 Value0
SET Key1 Value1
...
SET KeyN ValueN

次に、次のコマンドでインポートします.
(cat data.txt; sleep 10) | nc localhost 6379 > /dev/null

しかし、この方法は、データが完全にインポートされ、エラーが発生しているかどうかを判断することができません.
       2.第1のtxtドキュメントの内容方式は依然として通過しているが、以下のコマンドを採用する.
cat data.txt | redis-cli --pipe

pipe方式では第1の方式の不足を解決する.
       3.以下に示すように、RedisのRESPプロトコルの内容によりデータを組み立てる
"*3\r
$3\r
SET\r
$3\r
key\r
$5\r
value\r
"

あるいはフォーマットできれいに見えます
*3\r
$3\r
SET\r
$3\r
key\r
$5\r
value\r

新しいRedisサーバであれば、aofファイルで直接Redisに読み込むことができ、そうでなければコードで読み取ることができます.
       4.ルビーの方式
def gen_redis_proto(*cmd)
    proto = ""
    proto << "*"+cmd.length.to_s+"\r
" cmd.each{|arg| proto << "$"+arg.to_s.bytesize.to_s+"\r
" proto << arg.to_s+"\r
" } proto end puts gen_redis_proto("SET","mykey","Hello World!").inspect
(0...1000).each{|n|
    STDOUT.write(gen_redis_proto("SET","Key#{n}","Value#{n}"))
}

またはコマンドライン方式でrubyを実行する
$ ruby proto.rb | redis-cli --pipe

       5.luaスクリプト、詳細リファレンスhttps://redis.io/commands/eval