Redis簡單介紹 管道

2021-10-06 15:02:23 字數 3692 閱讀 3921

redis是乙個使用客戶機-伺服器模型和所謂的請求/響應協議的tcp伺服器。這意味著請求通常通過以下步驟完成:

客戶端和伺服器通過網路連線。這樣的鏈結可以是非常快(環迴介面)或非常慢(在internet上建立的連線,兩台主機之間有許多跳)。無論網路延遲是什麼,資料報都有一段時間從客戶機傳輸到伺服器,然後從伺服器返回到客戶機以攜帶應答。

這個時間叫做rtt(往返時間)。當客戶機需要在一行中執行多個請求時(例如向同一列表中新增多個元素,或用多個鍵填充資料庫),很容易看出這會如何影響效能。例如,如果rtt時間是250毫秒(在internet上的鏈結非常慢的情況下),即使伺服器能夠每秒處理10萬個請求,我們也將能夠每秒最多處理四個請求。

一、什麼是redis管道

redis提供了一種區別於上述響應模式的方式,客戶端無需等待單個請求響應再進行下一次請求,而是可以一次傳送多個命令給伺服器,伺服器處理完後一次性將結果返回給客戶端,這種工作方式在redis中被稱作管道。可以可出,通過管道的方式,能夠明顯的減少請求的次數,在於網路狀況不好的環境中,能明顯的提生處理的速度。

二、jedis中的管道實現

在jedis中,客戶端通過與伺服器建立socket長連線來進行通訊,主要通過乙個connection物件進行維護,可以看下這個類的定義:

public class connection implements closeable 

public connection(final string host)

public connection(final string host, final int port)

//...

}

connection物件通過outputstream傳送redis命令,通過inputstream讀取伺服器的響應,對與傳送redis命令,jedis中分為兩個動作:

我們通過乙個檢視set命令的原始碼驗證一下:

@override

public string set(final string key, final string value)

進入client.set方法:

@override

public void set(final string key, final string value)

//...

public void set(final byte key, final byte value)

//...

public void sendcommand(final protocolcommand cmd, final byte... args) catch (jedisconnectionexception ex)

} catch (exception e)

// any other exceptions related to connection?

broken = true;

throw ex;

}}

再看下protocol.sendcommand:

public static void sendcommand(final redisoutputstream os, final protocolcommand command,

final byte... args)

private static void sendcommand(final redisoutputstream os, final byte command,

final byte... args)

} catch (ioexception e)

}

到這一步,客戶端的set命令就完成了,但是這只是命令寫入到了outputstream緩衝區中,還沒有向redis伺服器實際的傳送redis命令,

我們再來看一下 client.getstatuscodereply():

public string getstatuscodereply()  else 

}

該方法會觸發flush,outputstream緩衝區中的redis命令會真正的傳送到redis伺服器上,我們理解上述過程之後,再回過頭來看下管道。

在redis客戶端中,客戶端只能處於一種模式下,要麼是普通的模式,一次傳送乙個請求,要麼處於管道模式,二者不能混用。在普通模式下,命令寫入到outputstream緩衝區後會立即觸發flush,而在管道模式模式下,flush的觸發需要顯示呼叫pipeline.sync()函式,因此可以實現一次傳送多個命令。

public void sync() 

}}public listgetmany(final int count) catch (jedisdataexception e)

}return responses;

}

三、jedis管道的資料接收

jedis中通過一次性將outputstream中的命令傳送到redis中來實現管道的特性,但這裡有乙個問題需要解決,客戶端如何接收伺服器響應。在普通模式下,客戶端傳送請求,然後同步的接收響應。在管道模式下,需要批量的接收響應,然後分發的對應的請求中去,jedis通過builder介面實現這個過程:

public abstract class builder
在jedis的builde***ctory中,對builder介面進行多種實現,主要包括將data轉換為string,int,long,float,double和boolean型別。

在通過pipeline傳送命令命令時,pipeline會返回乙個response物件代表乙個伺服器響應,可以看下這個類的實現:

public class response

public void set(object data)

public t get()

if (!set)

if (!built)

if (exception != null)

return response;

} //...

}

可以看到,response物件的建立需要乙個builder, 表示如何構造響應資料。

我們還是以set命令為例子:

@override

public responseset(final string key, final string value)

//...

protected responsegetresponse(builderbuilder)

可以看到,呼叫set命令時,pipeline會將命令的實現委託給client物件,並返回乙個指定builder的response,表示將來有資料了,通過指定的builder去構造資料。並且也會將response加入到管道維護的乙個佇列中。這個主要是為了呼叫sync()方法時,將伺服器的響應分發到每乙個response中。

public void sync() 

}}protected response<?> generateresponse(object data)

return response;

}

這個時候 response中就有了資料data,此時就可以呼叫builder去獲取實際型別的資料了。

本人對redis的管道做了簡單介紹,也簡單說了一下jedis的管道實現,假如有不對的地方,歡迎前來指正。

redis簡單介紹

多次查詢讓你懷疑人生 冗餘欄位過多會讓你看起來很傻 為啥不試試redis 大大減少了查詢數量,提高了效率 redis的api更加人性化,再也不需要構建sql語句,節省了sql的解析時間 redis 是完全開源免費的,遵守bsd協議,是乙個高效能的key value資料庫。redis 與其他 key ...

redis簡單介紹

特點 速度快,多種資料結構,簡單穩定,客戶端支援語言多,持久化,主從,高可用和分布式 速度快 基於鍵值對的nosql資料庫,將資料都放入記憶體中,使用c語言,單執行緒架構 資料結構 字串,雜湊,列表,集合,有序集合 鍵過期功能,實現快取,簡單穩定不依賴作業系統中的類庫,使用單執行緒 持久化 rdb和...

redis 簡單介紹

了解redis的資料結構有助於了解每種資料結構的優劣勢,方便設計合理的cache結構。1.string 可以儲存字串 浮點型 整型,如果是字串可以執行字串操作,如果是浮點型 整型也可以執行加減操作。redis會識別出它的具體型別。2.list 鍊錶,鍊錶中的每個node包含乙個字串。可以對鍊錶進行兩...