Redis中容易啋的坑

2022-07-07 03:24:19 字數 994 閱讀 3428

我們在申請上游讀介面呼叫許可權時,往往會多問一句,這介面是否支援批量查詢。正所謂,能批量絕不單個,能非同步絕不序列。而讀介面的底層大部分是通過redis的批量mget查詢實現,沒有人敢放心地將資料庫查詢暴露給非內部的系統。

但是,每次查詢key的個數如果不加以控制的話,將是乙個隱患。比如,元素數目從10增長到100這個過程中,mget效能下降非常明顯。

因為,mget是乙個多key的操作命令,但是一次操作的n個key不在同乙個分片上的話,就會將mget命令拆分成多個mget命令,也就是說乙個請求將會被放大再合併。這是底層實現引起的限制。

這就好比,在分庫分表的場景中,如果你想對不在乙個資料庫的多表進行事務操作,神仙也無能為力。唯一的辦法就是只有場景合適時才使用,或者努力創造機會。比如,算出key對應的節點,將mget操作手動分成多個操作,減少在redis系統中的merge操作。

不過呢,當列表為空時,客戶端如果一直無腦輪詢進行空運轉的話,浪費資源。列表中有值能主動通知客戶端來取就好了,類似併發程式設計模型的生產者和消費者模型。幸運的是,redis就提供了這種特性,借助blpop命令,可以移出並獲取列表的第乙個元素,如果列表沒有元素會阻塞等待。

但是,執行緒一直阻塞在那裡的話,客戶端連線就會成為閒置連線,閒置過久,服務一般會主動斷開連線,這個時候再操作就會丟擲異常。所以,在使用阻塞佇列時,要考慮等待超時的問題。

redis這種單執行緒模型能達到這麼高的效能,很多功勞都是記憶體貢獻的,但是我們也不能無視某些記憶體機制對效能的影響。

我們知道,虛擬位址和記憶體位址是需要轉換的,轉換過程要查對映表,cpu通過內建快表tlb加速這個查表過程。

如果虛擬頁越大,表的條目數就越小,命中率就越高。所以,主流作業系統都提供了記憶體大頁機制huge page,允許我們定製超過4k的大記憶體頁。

但是,對於redis這種需要fork子程序的系統來說並不友好。redis主從同步是非同步進行的,保證了最終一致性,而fork子程序那個瞬間是阻塞主線程的。

如果對映表和記憶體頁太大,拷貝就會很慢,阻塞時間將變得更長。因此,在生產環境,通常會關閉記憶體大頁機制。

Python中not的用法和各類容易踩坑點總結

在python中not是邏輯判斷詞,用於布林型true和false,not true為false,not false為true,以下是幾個常用的not的用法 比如 a false if not a 這裡因為a是false,所以not a就是true print hello 這裡就能夠輸出結果hell...

Go語言容易踩的坑

本文章記錄go學習過程中的一些容易忽視的地方。package main import fmt 會先把defer全部出棧,看有沒有recover defer出完之後,沒有recover,則報錯 func main1 defer func defer func panic 觸發異常 func calc ...

Redis之坑 Redis與MySQL中事務的區別

redis之坑 redis與mysql中事務的區別 note 該篇討論的只是redis與mysql中事務的區別,並不能統一代表no sql與關係型sql 在 mysql 中只有使用了innodb資料庫引擎的資料庫或表才支援事務 事務使用的目的是統一管理 insert,update,delete,這些...