共計 4516 個字符,預計需要花費 12 分鐘才能閱讀完成。
自動寫代碼機器人,免費開通
這篇文章主要介紹 redis 6.0 版本新特性有哪些,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!
Redis 6.0 穩定版本
Redis 6.0.0 穩定版本提供了很多新特性及功能改進,例如新網絡協議 RESP3、新的集群代理、ACL 等。我想大家最關注的可能還是“多線程”,下面我們就來看看 redis 6.0 版本有哪些新特性吧。
1. Redis6.0 之前的版本真的是單線程嗎?
Redis 在處理客戶端的請求時,包括獲取 (socket 讀)、解析、執行、內容返回 (socket 寫) 等都由一個順序串行的主線程處理,這就是所謂的“單線程”。但如果嚴格來講從 Redis4.0 之后并不是單線程,除了主線程外,它也有后臺線程在處理一些較為緩慢的操作,例如清理臟數據、無用連接的釋放、大 key 的刪除等等。
2. Redis6.0 之前為什么一直不使用多線程?
官方曾做過類似問題的回復:使用 Redis 時,幾乎不存在 CPU 成為瓶頸的情況,Redis 主要受限于內存和網絡。例如在一個普通的 Linux 系統上,Redis 通過使用 pipelining 每秒可以處理 100 萬個請求,所以如果應用程序主要使用 O(N) 或 O(log(N)) 的命令,它幾乎不會占用太多 CPU。
使用了單線程后,可維護性高。多線程模型雖然在某些方面表現優異,但是它卻引入了程序執行順序的不確定性,帶來了并發讀寫的一系列問題,增加了系統復雜度、同時可能存在線程切換、甚至加鎖解鎖、死鎖造成的性能損耗。Redis 通過 AE 事件模型以及 IO 多路復用等技術,處理性能非常高,因此沒有必要使用多線程。單線程機制使得 Redis 內部實現的復雜度大大降低,Hash 的惰性 Rehash、Lpush 等等“線程不安全”的命令都可以無鎖進行。
3.Redis6.0 為什么要引入多線程呢?
Redis 將所有數據放在內存中,內存的響應時長大約為 100 納秒,對于小數據包,Redis 服務器可以處理 80,000 到 100,000 QPS,這也是 Redis 處理的極限了,對于 80% 的公司來說,單線程的 Redis 已經足夠使用了。
但隨著越來越復雜的業務場景,有些公司動不動就上億的交易量,因此需要更大的 QPS。常見的解決方案是在分布式架構中對數據進行分區并采用多個服務器,但該方案有非常大的缺點,例如要管理的 Redis 服務器太多,維護代價大;某些適用于單個 Redis 服務器的命令不適用于數據分區;數據分區無法解決熱點讀 / 寫問題;數據偏斜,重新分配和放大 / 縮小變得更加復雜等等。
從 Redis 自身角度來說,因為讀寫網絡的 read/write 系統調用占用了 Redis 執行期間大部分 CPU 時間,瓶頸主要在于網絡的 IO 消耗, 優化主要有兩個方向:
? 提高網絡 IO 性能,典型的實現比如使用 DPDK 來替代內核網絡棧的方式
? 使用多線程充分利用多核,典型的實現比如 Memcached。
協議棧優化的這種方式跟 Redis 關系不大,支持多線程是一種最有效最便捷的操作方式。所以總結起來,redis 支持多線程主要就是兩個原因:
? 可以充分利用服務器 CPU 資源,目前主線程只能利用一個核
? 多線程任務可以分攤 Redis 同步 IO 讀寫負荷
4.Redis6.0 默認是否開啟了多線程?
Redis6.0 的多線程默認是禁用的,只使用主線程。如需開啟需要修改 redis.conf 配置文件:io-threads-do-reads yes
5.Redis6.0 多線程開啟時,線程數如何設置?
開啟多線程后,還需要設置線程數,否則是不生效的。同樣修改 redis.conf 配置文件
關于線程數的設置,官方有一個建議:4 核的機器建議設置為 2 或 3 個線程,8 核的建議設置為 6 個線程,線程數一定要小于機器核數。還需要注意的是,線程數并不是越大越好,官方認為超過了 8 個基本就沒什么意義了。
6.Redis6.0 采用多線程后,性能的提升效果如何?
Redis 作者 antirez 在 RedisConf 2019 分享時曾提到:Redis 6 引入的多線程 IO 特性對性能提升至少是一倍以上。國內也有大牛曾使用 unstable 版本在阿里云 esc 進行過測試,GET/SET 命令在 4 線程 IO 時性能相比單線程是幾乎是翻倍了。
測試環境:
Redis Server: 阿里云 Ubuntu 18.04,8 CPU 2.5 GHZ, 8G 內存,主機型號 ecs.ic5.2xlarge
Redis Benchmark Client: 阿里云 Ubuntu 18.04,8 2.5 GHZ CPU, 8G 內存,主機型號 ecs.ic5.2xlarge
測試結果:
詳見:https://zhuanlan.zhihu.com/p/76788470
說明 1:這些性能驗證的測試并沒有針對嚴謹的延時控制和不同并發的場景進行壓測。數據僅供驗證參考而不能作為線上指標。
說明 2:如果開啟多線程,至少要 4 核的機器,且 Redis 實例已經占用相當大的 CPU 耗時的時候才建議采用,否則使用多線程沒有意義。所以估計 80% 的公司開發人員看看就好。
7.Redis6.0 多線程的實現機制?
流程簡述如下:
1、主線程負責接收建立連接請求,獲取 socket 放入全局等待讀處理隊列
2、主線程處理完讀事件之后,通過 RR(Round Robin) 將這些連接分配給這些 IO 線程
3、主線程阻塞等待 IO 線程讀取 socket 完畢
4、主線程通過單線程的方式執行請求命令,請求數據讀取并解析完成,但并不執行
5、主線程阻塞等待 IO 線程將數據回寫 socket 完畢
6、解除綁定,清空等待隊列
(圖片來源:https://ruby-china.org/topics/38957)
該設計有如下特點:
1、IO 線程要么同時在讀 socket,要么同時在寫,不會同時讀或寫
2、IO 線程只負責讀寫 socket 解析命令,不負責命令處理
8. 開啟多線程后,是否會存在線程并發安全問題?
從上面的實現機制可以看出,Redis 的多線程部分只是用來處理網絡數據的讀寫和協議解析,執行命令仍然是單線程順序執行。所以我們不需要去考慮控制 key、lua、事務,LPUSH/LPOP 等等的并發及線程安全問題。
9.Linux 環境上如何安裝 Redis6.0.1(6.0 的正式版是 6.0.1)?
這個和安裝其他版本的 redis 沒有任何區別,整個流程跑下來也沒有任何的坑,所以這里就不做描述了。唯一要注意的就是配置多線程數一定要小于 cpu 的核心數,查看核心數量命令:
[root@centos7.5 ~]# lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 4
On-line CPU(s) list: 0-3
10.Redis6.0 的多線程和 Memcached 多線程模型進行對比
前些年 memcached 是各大互聯網公司常用的緩存方案,因此 redis 和 memcached 的區別基本成了面試官緩存方面必問的面試題,最近幾年 memcached 用的少了,基本都是 redis。不過隨著 Redis6.0 加入了多線程特性,類似的問題可能還會出現,接下來我們只針對多線程模型來簡單比較一下。
如上圖所示:Memcached 服務器采用 master-woker 模式進行工作,服務端采用 socket 與客戶端通訊。主線程、工作線程 采用 pipe 管道進行通訊。主線程采用 libevent 監聽 listen、accept 的讀事件,事件響應后將連接信息的數據結構封裝起來,根據算法選擇合適的工作線程,將連接任務攜帶連接信息分發出去,相應的線程利用連接描述符建立與客戶端的 socket 連接 并進行后續的存取數據操作。
Redis6.0 與 Memcached 多線程模型對比:
相同點:都采用了 master 線程 -worker 線程的模型
不同點:Memcached 執行主邏輯也是在 worker 線程里,模型更加簡單,實現了真正的線程隔離,符合我們對線程隔離的常規理解。而 Redis 把處理邏輯交還給 master 線程,雖然一定程度上增加了模型復雜度,但也解決了線程并發安全等問題。
11.Redis 作者是如何點評“多線程”這個新特性的?
關于多線程這個特性,在 6.0 RC1 時,Antirez 曾做過說明:
Redis 支持多線程有 2 種可行的方式:第一種就是像“memcached”那樣,一個 Redis 實例開啟多個線程,從而提升 GET/SET 等簡單命令中每秒可以執行的操作。這涉及到 I /O、命令解析等多線程處理,因此,我們將其稱之為“I/O threading”。另一種就是允許在不同的線程中執行較耗時較慢的命令,以確保其它客戶端不被阻塞,我們將這種線程模型稱為“Slow commands threading”。
經過深思熟慮,Redis 不會采用“I/O threading”,redis 在運行時主要受制于網絡和內存,所以提升 redis 性能主要是通過在多個 redis 實例,特別是 redis 集群。接下來我們主要會考慮改進兩個方面:
1.Redis 集群的多個實例通過編排能夠合理地使用本地實例的磁盤,避免同時重寫 AOF。
2. 提供一個 Redis 集群代理,便于用戶在沒有較好的集群協議客戶端時抽象出一個集群。
補充說明一下,Redis 和 memcached 一樣是一個內存系統,但不同于 Memcached。多線程是復雜的,必須考慮使用簡單的數據模型,執行 LPUSH 的線程需要服務其他執行 LPOP 的線程。
我真正期望的實際是“slow operations threading”,在 redis6 或 redis7 中,將提供“key-level locking”,使得線程可以完全獲得對鍵的控制以處理緩慢的操作。
詳見:http://antirez.com/news/126
12.Redis 線程中經常提到 IO 多路復用,如何理解?
這是 IO 模型的一種,即經典的 Reactor 設計模式,有時也稱為異步阻塞 IO。
多路指的是多個 socket 連接,復用指的是復用一個線程。多路復用主要有三種技術:select,poll,epoll。epoll 是最新的也是目前最好的多路復用技術。采用多路 I/O 復用技術可以讓單個線程高效的處理多個連接請求(盡量減少網絡 IO 的時間消耗),且 Redis 在內存中操作數據的速度非??欤▋却鎯鹊牟僮鞑粫蔀檫@里的性能瓶頸),主要以上兩點造就了 Redis 具有很高的吞吐量。
13. 你知道 Redis 的彩蛋 LOLWUT 嗎?
這個其實從 Redis5.0 就開始有了,但是原諒我剛剛知道。作者是這么描述這個功能的《LOLWUT: a piece of art inside a database command》,“數據庫命令中的一件藝術品”。你可以把它稱之為情懷,也可以稱之為彩蛋,具體是什么,我就不透露了。和我一樣不清楚是什么的小伙伴可以參見:http://antirez.com/news/123,每次運行都會隨機生成的噢。
以上是“redis 6.0 版本新特性有哪些”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注丸趣 TV 行業資訊頻道!
向 AI 問一下細節