目錄
redis伺服器對命令的處理都是單執行緒的,但是I/O層面卻面向多個使用者端並行地提供服務,並行到內部單執行緒的轉化通過多路複用框架來實現。redis命令從傳送到執行經理以下四個過程
對redis請求進行抓包,檢視抓包內容
1、執行抓包命令
2、檢視抓包內容
redis協定位於TCP層之上,即使用者端和redis範例保持雙工的連線,互動的都是序列化後的協定資料
Redis 伺服器與使用者端通過RESP(REdis Serialization Protocol)協定通訊。
RESP 底層採用的是TCP 的連線方式,通過tcp 進行資料傳輸,然後根據解析規則解析相應資訊,完成互動。
我們可以測試下,首先執行一個serverSocket 監聽6379,來接收redis 使用者端的請求資訊。實現如下
1、建立socket連線監聽6379埠,用於接收請求並輸出
/**
* /**
* <p>模擬redis</p>
*
* @author DK
* @version V1.0
*/
public class SimulatedRedis {
public static void main(String[] args) throws IOException {
ServerSocket server = new ServerSocket(6379);
Socket rec = server.accept();
byte[] result = new byte[2048];
rec.getInputStream().read(result);
System.out.println(new String(result));
}
}
2、使用jedis客戶度端請求本地6379埠
/**
* /**
* <p>模擬redis</p>
*
* @author DK
* @version V1.0
*/
public class SimulatedRedisClient {
public static void main(String[] args) throws IOException {
Jedis jedis = new Jedis("127.0.0.1", 6379);
jedis.set("user:2", "9999");
jedis.close();
}
}
列印輸出
發現和抓包內容一致
每個欄位標示含義為:
*3 表示有幾組資料
$ 3 表示set長度為3
Set 命令
$6 表示key長度為6
User:2 key
$1 表示value長度為1
2 value
主要以下特點:從上述範例中發現,redis使用resp協定的好處為容易實現,解析快,人類可讀,並且傳輸在TCP層,可以減少不必要的資訊傳輸
/**
* /**
* <p>模擬redis</p>
*
* @author DK
* @version V1.0
*/
public class RespRedis {
public static void main(String[] args) {
SocketAddress addr = new InetSocketAddress("10.1.253.188", 6379);
Socket sk = new Socket();
try {
sk.connect(addr);
OutputStream out = sk.getOutputStream();
StringBuffer sb = new StringBuffer();
sb.append("*3\r\n");
sb.append("$3\r\n");
sb.append("SET\r\n");
sb.append("$6\r\n");
sb.append("user:0\r\n");
sb.append("$5\r\n");
sb.append("11111\r\n");
System.out.println(sb.toString());
byte[] b = sb.toString().getBytes();
out.write(b);
out.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
mysql一樣:當執行時間超過極大值時,會將發生時間 耗時 命令記錄
redis命令生命週期:傳送 排隊 執行 返回,慢查詢只統計第3個執行步驟的時間
一般有兩種方式,預設時間為10ms
1、命令方式
config set slowlog-log-slower-than 10000 //10毫秒
使用config set完後,若想將設定持久化儲存到redis.conf,要執行config rewrite
2、組態檔修改
redis.conf修改:找到slowlog-log-slower-than 10000 ,修改儲存即可
注意:slowlog-log-slower-than =0記錄所有命令 -1命令都不記錄
慢查詢記錄也是存在佇列裡的,slow-max-len 存放的記錄最大條數,
比如設定的slow-max-len=10,當有第11條慢查詢命令插入時,佇列的第一條命令
就會出列,第11條入列到慢查詢佇列中, 可以config set動態設定,
也可以修改redis.conf完成設定
獲取佇列裡慢查詢的命令:slowlog get
獲取慢查詢列表當前的長度:slowlog len //以上只有1條慢查詢,返回1;
1),對慢查詢列表清理(重置):slowlog reset //再查slowlog len 此時返回0 清空;
2),對於線上slow-max-len設定的建議:線上可加大slow-max-len的值,記錄慢查詢存長命令時redis會做截斷,不會佔用大量記憶體,線上可設定1000以上
3),對於線上slowlog-log-slower-than設定的建議:預設為10毫秒,根據redis並行量來調整,對於高並行比建議為1毫秒
4),慢查詢是先進先出的佇列,存取紀錄檔記錄出列丟失,需定期執行slowlog get,將結果儲存到其它裝置中(如mysql)
1、redis-benchmark -h 127.0.0.1 -p 6379 -c 100 -n 10000
100個並行連線,10000個請求,檢測伺服器效能