Redis中使用Pipelining加速查詢的問題怎麼解決
Request/Response protocols and RTT
Redis是一個client-server
模式的TCP服務,也稱為Request/Response
協定的實作。
這表示通常一個請求的完成是遵循下面兩個步驟:
Client發送一個操作命令給Server,從TCP的套接字Socket中讀取Server的回應值,通常來說這是一種阻塞的方式
Server執行操作指令,然後將回應值回傳給Client
舉例
Client: INCR X Server: 1 Client: INCR X Server: 2 Client: INCR X Server: 3 Client: INCR X Server: 4
Clients和Servers是透過網路連線。網路連線速度可能會快得很快(例如本地回環網路)或慢得很慢(例如跨越多個主機的網路)。不管網路怎麼樣,一個封包從Client到Server,然後對應值又從Server回傳Client都需要一定的時間。
這個時間被稱為RTT(Round Trip Time)。當一個Client需要執行多個連續請求(例如增加許多個元素到一個list中,或是清除Redis中許多個鍵值對),那麼RTT是怎麼影響到效能的呢?這個也是很方便去計算的。例如如果RTT的時間為250ms(假設網路連線速度非常慢),即使Server可以每秒處理100k個要求,那麼最多也只能接受每秒4個請求。
如果是回環網絡,RTT將會特別的短(例如作者的127.0.0.1,RTT的回應時間為44ms),但是對於執行連續多次寫入操作時,也是一筆不小的消耗。
其實我們有其他方法可以降低這種場景的消耗,開心不?驚喜不?
Redis Pipelining
在一個Request/Response
方式的服務中有一個特性:即使Client沒有收到先前的回應值,也可以繼續傳送新的請求。這個特性意味著我們可以不需要等待Server的回應,可以率先發送許多操作指令給Server,然後在一次讀取Server的所有回應值。
這種方式被稱為Pipelining
技術,該技術近幾十年來被廣泛的使用。例如多POP3協定的實作就支援這個特性,大大的提升了從server端下載新的郵件的速度。
Redis在很早的時候就支援該項技術,所以不管你運行的是什麼版本,你都可以使用pipelining
技術,例如這裡有一個使用netcat 工具的:
$ (printf "PING\r\nPING\r\nPING\r\n"; sleep 1) | nc localhost 6379 +PONG +PONG +PONG
現在我們不需要為每個請求付出RTT的消耗了,而是一次發送三個操作命令。為了便於直覺的理解,還是拿先前的說明,使用pipelining
技術該的實作順序如下:
Client: INCR X Client: INCR X Client: INCR X Client: INCR X Server: 1 Server: 2 Server: 3 Server: 4
劃重點(敲黑板):當client使用pipelining
發送操作命令時,server端將強制使用記憶體來排列回應結果。所以在使用pipelining
發送大量的操作命令的時候,最好確定一個合理的命令條數,一批一批的發送給Server端,例如發送10k個操作命令,讀取響應結果,再發送10k個操作指令,以此類推…雖然說耗時近乎相同,但是額外的記憶體消耗將是這10k操作指令的排列回應結果所需的最大值。 (為防止記憶體耗盡,選擇一個合理的值)
It’s not just a matter of RTT
Pipelining
不是減少因為RTT 造成消耗的唯一方式,但是它確實幫助你極大的提升每秒的執行命令數量。事實的真相是:從存取相應的資料結構並且產生答案結果的角度來看,不使用pipelining
確實代價很低;但是從套接字socket I/O的角度來看,恰恰相反。因為這涉及到了read()
和write()
調用,需要從使用者狀態切換到核心狀態。這種上下文切換會特別損耗時間的。
一旦使用了pipelining
技術,許多操作指令將會從同一個read()
呼叫中執行讀取操作,大量的答覆結果將會被分發到同一個write()
呼叫中執行寫入操作。基於此,隨著管道的長度增加,每秒執行的查詢數量最開始幾乎呈直線型增加,直到不使用pipelining
技術的基準的10倍,如下圖:
Some real world code example
不翻譯,基本上就是使用了pipelining
提升了5倍效能。
Pipelining VS Scripting
Redis Scripting
(2.6+版本可用),通过使用在Server端完成大量工作的脚本Scripting
,可以更加高效的解决大量pipelining
用例。使用脚本Scripting
的最大好处就是在读和写的时候消耗更少的性能,使得像读、写、计算这样的操作更加快速。(当client需要写操作之前获取读操作的响应结果时,pepelining
就显得相形见拙。) 有时候,应用可能需要在使用pipelining
时,发送 EVAL
或者 EVALSHA
命令,这是可行的,并且Redis明确支持这么这种SCRIPT LOAD
命令。(它保证可可以调用 EVALSHA
而不会有失败的风险)。
Appendix: Why are busy loops slow even on the loopback interface?
读完全文,你可能还会感到疑问:为什么如下的Redis测试基准 benchmark
会执行这么慢,甚至在Client和Server在一个物理机上也是如此:
FOR-ONE-SECOND: Redis.SET("foo","bar") END
毕竟Redis进程和测试基准benchmark
在相同的机器上运行,并且这是没有任何实际的延迟和真实的网络参与,不就是消息通过内存从一个地方拷贝到另一个地方么? 原因是进程在操作系统中并不是一直运行。真实的情景是系统内核调度,调度到进程运行,它才会运行。比如测试基准benchmark
被允许运行,从Redis Server中读取响应内容(与最后一次执行的命令相关),并且写了一个新的命令。这时命令将在回环网络的套接字中,但是为了被Redis Server读取,系统内核需要调度Redis Server进程(当前正在系统中挂起),周而复始。所以由于系统内核调度的机制,就算是在回环网络中,仍然会涉及到网络延迟。 简言之,在网络服务器中衡量性能时,使用回环网络测试并不是一个明智的方式。应该避免使用此种方式来测试基准。
以上是Redis中使用Pipelining加速查詢的問題怎麼解決的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

Redis集群模式通過分片將Redis實例部署到多個服務器,提高可擴展性和可用性。搭建步驟如下:創建奇數個Redis實例,端口不同;創建3個sentinel實例,監控Redis實例並進行故障轉移;配置sentinel配置文件,添加監控Redis實例信息和故障轉移設置;配置Redis實例配置文件,啟用集群模式並指定集群信息文件路徑;創建nodes.conf文件,包含各Redis實例的信息;啟動集群,執行create命令創建集群並指定副本數量;登錄集群執行CLUSTER INFO命令驗證集群狀態;使

如何清空 Redis 數據:使用 FLUSHALL 命令清除所有鍵值。使用 FLUSHDB 命令清除當前選定數據庫的鍵值。使用 SELECT 切換數據庫,再使用 FLUSHDB 清除多個數據庫。使用 DEL 命令刪除特定鍵。使用 redis-cli 工具清空數據。

要從 Redis 讀取隊列,需要獲取隊列名稱、使用 LPOP 命令讀取元素,並處理空隊列。具體步驟如下:獲取隊列名稱:以 "queue:" 前綴命名,如 "queue:my-queue"。使用 LPOP 命令:從隊列頭部彈出元素並返回其值,如 LPOP queue:my-queue。處理空隊列:如果隊列為空,LPOP 返回 nil,可先檢查隊列是否存在再讀取元素。

使用 Redis 指令需要以下步驟:打開 Redis 客戶端。輸入指令(動詞 鍵 值)。提供所需參數(因指令而異)。按 Enter 執行指令。 Redis 返迴響應,指示操作結果(通常為 OK 或 -ERR)。

使用Redis進行鎖操作需要通過SETNX命令獲取鎖,然後使用EXPIRE命令設置過期時間。具體步驟為:(1) 使用SETNX命令嘗試設置一個鍵值對;(2) 使用EXPIRE命令為鎖設置過期時間;(3) 當不再需要鎖時,使用DEL命令刪除該鎖。

在CentOS系統上,您可以通過修改Redis配置文件或使用Redis命令來限制Lua腳本的執行時間,從而防止惡意腳本佔用過多資源。方法一:修改Redis配置文件定位Redis配置文件:Redis配置文件通常位於/etc/redis/redis.conf。編輯配置文件:使用文本編輯器(例如vi或nano)打開配置文件:sudovi/etc/redis/redis.conf設置Lua腳本執行時間限制:在配置文件中添加或修改以下行,設置Lua腳本的最大執行時間(單位:毫秒)

使用 Redis 命令行工具 (redis-cli) 可通過以下步驟管理和操作 Redis:連接到服務器,指定地址和端口。使用命令名稱和參數向服務器發送命令。使用 HELP 命令查看特定命令的幫助信息。使用 QUIT 命令退出命令行工具。

Redis數據過期策略有兩種:定期刪除:定期掃描刪除過期鍵,可通過 expired-time-cap-remove-count、expired-time-cap-remove-delay 參數設置。惰性刪除:僅在讀取或寫入鍵時檢查刪除過期鍵,可通過 lazyfree-lazy-eviction、lazyfree-lazy-expire、lazyfree-lazy-user-del 參數設置。
