1. 程式人生 > >redis的一些知識-使用pipeline來大幅提升redis的處理速度

redis的一些知識-使用pipeline來大幅提升redis的處理速度

redis通過tcp來對外提供服務,client通過socket連線發起請求,每個請求在命令發出後會阻塞等待redis伺服器進行處理,處理完畢後將結果返回給client。

其實和一個http的伺服器類似,一問一答,請求一次給一次響應。而這個過程在排除掉redis服務本身做複雜操作時的耗時的話,可以看到最耗時的就是這個網路傳輸過程。每一個命令都對應了傳送、接收兩個網路傳輸,假如一個流程需要0.1秒,那麼一秒最多隻能處理10個請求,將嚴重製約redis的效能。

在很多場景下,我們要完成一個業務,可能會對redis做連續的多個操作,譬如庫存減一、訂單加一、餘額扣減等等,這有很多個步驟是需要依次連續執行的。這樣的場景,網路傳輸的耗時將是限制redis處理量的主要瓶頸。那麼此時就可以引入pipeline了,pipeline管道就是解決執行大量命令時、會產生大量同學次數而導致延遲的技術。

其實原理很簡單,pipeline就是把所有的命令一次發過去,避免頻繁的傳送、接收帶來的網路開銷,redis在打包接收到一堆命令後,依次執行,然後把結果再打包返回給客戶端。

拿例子來演示一下:

Long time = System.currentTimeMillis();
		for (int i = 0; i < 10000; i++) {
			stringRedisTemplate.opsForValue().increment("pipline", 1);
		}
		System.out.println("耗時:" + (System.currentTimeMillis() - time));
		time = System.currentTimeMillis();
		stringRedisTemplate.executePipelined(new SessionCallback<Object>() {
			@Override
			public <K, V> Object execute(RedisOperations<K, V> redisOperations) throws DataAccessException {
				for (int i = 0; i < 10000; i++) {
					stringRedisTemplate.opsForValue().increment("pipline", 1L);
				}
				return null;
			}
		});
		System.out.println("耗時:" + (System.currentTimeMillis() - time));
這裡就是演示不使用和使用pipeline時,執行10000個increment操作的耗時。使用的是RedisTemplate工具類,在建立Springboot工程時勾選redis即可。


通過多次測試,在本機上耗時差距在10倍以上。

需要注意RedisTemplate執行executePipelined方法是有返回值的,List<Object>,這個list裡面就是你在execute方法中執行的所有命令的返回值集合。在execute方法中要return null,否則會拋異常。