Redisは、数百万の高速同時データと百万のデータのインポートをサポートする方法
4861 ワード
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)
Intel(R) Xeon(R) CPU E5520 @ 2.27GHz (without pipelining)
Linode 2048 instance (with pipelining)
Linode 2048 instance (without pipelining)
上記のテストで物理マシンとクラウド上、pipelineメカニズムを使用するかどうかについては、読み書きデータの性能の差が大きい(より多くのテストデータが見られるhttps://redis.io/topics/benchmarks)のため,大量の高同時読み書きに対してpipelineを採用するメカニズムが性能的に優れていることも分かる.コード上で実現方式を見る
Redisを使用している間に100 Wのデータが生成されている場合は、これらの大量のデータをインポートする必要があります.では、私たちにはどんな方法がありますか?
1.txtドキュメントを開き、インポートするデータをtxtドキュメントに書き込む
次に、次のコマンドでインポートします.
しかし、この方法は、データが完全にインポートされ、エラーが発生しているかどうかを判断することができません.
2.第1のtxtドキュメントの内容方式は依然として通過しているが、以下のコマンドを採用する.
pipe方式では第1の方式の不足を解決する.
3.以下に示すように、RedisのRESPプロトコルの内容によりデータを組み立てる
あるいはフォーマットできれいに見えます
新しいRedisサーバであれば、aofファイルで直接Redisに読み込むことができ、そうでなければコードで読み取ることができます.
4.ルビーの方式
またはコマンドライン方式でrubyを実行する
5.luaスクリプト、詳細リファレンスhttps://redis.io/commands/eval
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
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