當前位置:
首頁 > 知識 > Redis pipeline

Redis pipeline

關於 Redis pipeline

為什麼需要 pipeline ?

Redis 的工作過程是基於 請求/響應 模式的。正常情況下,客戶端發送一個命令,等待 Redis 應答;Redis 接收到命令,處理後應答。請求發出到響應的時間叫做往返時間,即 RTT(Round Time Trip)。在這種情況下,如果需要執行大量的命令,就需要等待上一條命令應答後再執行。這中間不僅僅多了許多次 RTT,而且還頻繁的調用系統 IO,發送網路請求。為了提升效率,pipeline 出現了,它允許客戶端可以一次發送多條命令,而不等待上一條命令執行的結果。

實現思路

客戶端首先將執行的命令寫入到緩衝區中,最後再一次性發送 Redis。但是有一種情況就是,緩衝區的大小是有限制的:如果命令數據太大,可能會有多次發送的過程,但是仍不會處理 Redis 的應答。

實現原理

要支持 pipeline,既要服務端的支持,也要客戶端支持。對於服務端來說,所需要的是能夠處理一個客戶端通過同一個 TCP 連接發來的多個命令。可以理解為,這裡將多個命令切分,和處理單個命令一樣。對於客戶端,則是要將多個命令緩存起來,緩衝區滿了就發送,然後再寫緩衝,最後才處理 Redis 的應答。

Redis pipeline 的參考資料

Redis 官網對於 pipeline 的介紹

Spring Data Redis 對於 pipeline 的介紹

在 SpringBoot 中使用 Redis pipeline

基於 SpringBoot 的自動配置,在使用 Redis 時只需要在 pom 文件中給出 spring-boot-starter-data-redis 依賴,就可以直接使用 Spring Data Redis。關於 Redis pipeline 的使用方法,可以閱讀 Spring Data Redis 給出的解釋。下面,我給出一個簡單的例子:

import com.imooc.ad.Application;

import org.junit.Test;

import org.junit.runner.RunWith;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.boot.test.context.SpringBootTest;

import org.springframework.dao.DataAccessException;

import org.springframework.data.redis.connection.StringRedisConnection;

import org.springframework.data.redis.core.RedisCallback;

import org.springframework.data.redis.core.RedisOperations;

import org.springframework.data.redis.core.SessionCallback;

import org.springframework.data.redis.core.StringRedisTemplate;

import org.springframework.test.context.junit4.SpringRunner;

/**

*


Redis Pipeline 功能測試用例

* 參考: https://docs.spring.io/spring-data/redis/docs/1.8.1.RELEASE/reference/html/#redis:template

* Created by Qinyi.

*/

@RunWith(SpringRunner.class)

@SpringBootTest(classes = , webEnvironment = SpringBootTest.WebEnvironment.NONE)

public class RedisPipelineTest {

/** 注入 StringRedisTemplate, 使用默認配置 */

@Autowired

private StringRedisTemplate stringRedisTemplate;

@Test

@SuppressWarnings(all)

public void testExecutePipelined() {

// 使用 RedisCallback 把命令放在 pipeline 中

RedisCallback redisCallback = connection - {

StringRedisConnection stringRedisConn = (StringRedisConnection) connection;

for (int i = 0; i != 10; i) {

stringRedisConn.set(String.valueOf(i), String.valueOf(i));

}

return null; // 這裡必須要返回 null

};

// 使用 SessionCallback 把命令放在 pipeline

SessionCallback sessionCallback = new SessionCallback() {

@Override

public Object execute(RedisOperations operations) throws DataAccessException {

operations.opsForValue().set(name, qinyi);

operations.opsForValue().set(gender, male);

operations.opsForValue().set(age, 19);

return null;

}

};

System.out.println(stringRedisTemplate.executePipelined(redisCallback));

System.out.println(stringRedisTemplate.executePipelined(sessionCallback));

}

}

總結:Redis pipeline 的特性以及使用時需要注意的地方

pipeline 減少了 RTT,也減少了IO調用次數(IO 調用涉及到用戶態到內核態之間的切換)

如果某一次需要執行大量的命令,不能放到一個 pipeline 中執行。數據量過多,網路傳輸延遲會增加,且會消耗 Redis 大量的內存。應該將大量的命令切分為多個 pipeline 分別執行。

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 千鋒JAVA開發學院 的精彩文章:

分散式系統中的冪等性-zookeeper與dubbo
大數據已成為人工智慧的助推力

TAG:千鋒JAVA開發學院 |