成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Redis的自白:我為什么在單線程的這條路上越走越遠?

數據庫 其他數據庫 Redis
Redis 的單線程曾幾何時還是我們炫耀的資本,優雅又不失高效的設計,讓無數的追求者為之著迷。

[[346765]]

我是 Redis,今年 11 歲了~

曾幾何時我是辣么的單純,辣么的可愛,而如今我竟背叛了當初“誓言”,決心在多線程這條路上義無反顧的一路狂奔,沒錯我就是你們口中那個既可愛又迷人的 Redis,你可以叫我小 R...R 😊。

一波騷操作結束,我們開始今天的正文。

我們知道在 Redis 4.0 之后就陸陸續續添加了一些多線程的功能,難道單線程不香了嗎?

單線程慢嗎?

Redis 的單線程曾幾何時還是我們炫耀的資本,優雅又不失高效的設計,讓無數的追求者為之著迷。

你要問我排第幾?Nginx 是我大哥,NodeJS 是我小弟,我在家中排名老二。

[[346766]]

我們兄弟仨可謂單線程的杰出代表,不僅演示了我們的優雅更加展現了我們的高效。

有人可能會問:為什么單線程的我,竟然如此囂張?

家中有礦唄,Redis 單線程但性能依舊很快的主要原因有以下幾點:

    1.  基于內存操作:Redis 的所有數據都存在內存中,因此所有的運算都是內存級別的,所以他的性能比較高;

    2.  數據結構簡單:Redis 的數據結構比較簡單,是為 Redis 專門設計的,而這些簡單的數據結構的查找和操作的時間復雜度都是 O(1),因此性能比較高;

    3.  多路復用和非阻塞 I/O:Redis 使用 I/O 多路復用功能來監聽多個 socket 連接客戶端,這樣就可以使用一個線程連接來處理多個請求,減少線程切換帶來的開銷,同時也避免了 I/O 阻塞操作,從而大大提高了 Redis 的性能;

    4.  避免上下文切換:因為是單線程模型,因此就避免了不必要的上下文切換和多線程競爭,這就省去了多線程切換帶來的時間和性能上的消耗,而且單線程不會導致死鎖問題的發生。

來看一下我的父親大大是如何評價我的,Redis 的 FAQ(Frequently Asked Questions,常見問題)回答了單線程的這個問題,具體內容如下:

Redis is single threaded. How can I exploit multiple CPU / cores?

It's not very frequent that CPU becomes your bottleneck with Redis, as usually Redis is either memory or network bound. For instance, using pipelining Redis running on an average Linux system can deliver even 1 million requests per second, so if your application mainly uses O(N) or O(log(N)) commands, it is hardly going to use too much CPU.

However, to maximize CPU usage you can start multiple instances of Redis in the same box and treat them as different servers. At some point a single box may not be enough anyway, so if you want to use multiple CPUs you can start thinking of some way to shard earlier.

You can find more information about using multiple Redis instances in the Partitioning page.

However with Redis 4.0 we started to make Redis more threaded. For now this is limited to deleting objects in the background, and to blocking commands implemented via Redis modules. For future releases, the plan is to make Redis more and more threaded.

詳見:https://redis.io/topics/faq

他的大體意思是說 Redis 是基于內存操作的,因此他的瓶頸可能是機器的內存或者網絡帶寬而并非 CPU,既然 CPU 不是瓶頸,那么自然就采用單線程的解決方案了,況且使用多線程比較麻煩。但是在 Redis 4.0 中開始支持多線程了,例如后臺刪除等功能。

簡單來說,Redis  4.0 之前一直采用單線程的主要原因有以下三個:

  1.  使用單線程模型是 Redis 的開發和維護更簡單,因為單線程模型方便開發和調試;
  2.  即使使用單線程模型也并發的處理多客戶端的請求,主要使用的是多路復用和非阻塞 IO;
  3.  對于 Redis 系統來說,主要的性能瓶頸是內存或者網絡帶寬而并非 CPU。

[[346767]]

為什么需要多線程?

但是單線程也有單線程的苦惱,比如當我(Redis)需要刪除一個很大的數據時,因為是單線程同步操作,這就會導致 Redis 服務卡頓,于是在 Redis 4.0 中就新增了多線程的模塊,當然此版本中的多線程主要是為了解決刪除數據效率比較低的問題的,他的相關指令有以下三個:

  1.  unlink key
  2.  flushdb async
  3.  flushall async

執行示例如下所示: 

  1. > unlink key # 后臺刪除某個 key  
  2. > OK # 執行成功  
  3. > flushall async # 清空所有數據  
  4. > OK # 執行成功 

這樣我就可以把這些壞人“瞬間”拉黑(刪除)了。

[[346768]]

所謂的“瞬間”刪除其實有些夸張,只是從返回的結果來看是刪除成功了,但是這只是把刪除工作交給了后臺的小弟(子線程)異步來刪除數據了。

小貼士:正常情況下使用 del 指令可以很快的刪除數據,而當被刪除的 key 是一個非常大的對象時,例如時包含了成千上萬個元素的 hash 集合時,那么 del 指令就會造成 Redis 主線程卡頓,因此使用惰性刪除可以有效的避免 Redis 卡頓的問題。

Redis 6 中的多線程

之前在 Redis 4.0 中你說刪除比較慢,騙我開大(多線程)來處理也就罷了,為毛 Redis 6.0 還要多線程嘞?

其實是這樣的在 Redis 4.0 版本中雖然引入了多線程,但此版本中的多線程只能用于大數據量的異步刪除,然而對于非刪除操作的意義并不是很大。

但如果我們使用我們在非刪除的環境下使用多線程的話就可以分攤 Redis 同步讀寫 I/O 的壓力,以及充分的利用多核 CPU 的資源了,這樣就可以有效的提升 Redis 的 QPS(Query Per Second,每秒查詢率)了。

在 Redis 中雖然使用了 I/O 多路復用,并且是基于非阻塞 I/O 進行操作的,但 I/O 的讀和寫本身是堵塞的,比如當 socket 中有數據時,Redis 會通過調用先將數據從內核態空間拷貝到用戶態空間,再交給 Redis 調用,而這個拷貝的過程就是阻塞的,當數據量越大時拷貝所需要的時間就越多,而這些操作都是基于單線程完成的。

[[346769]]

I/O 多路復用,簡單來說就是通過監測文件的讀寫事件,再通知線程執行相關操作,保證 Redis 的非阻塞 I/O 能夠順利執行完成的機制。

因此在 Redis 6.0 中新增了多線程的功能來提高 I/O 的讀寫性能,他的主要實現思路是將主線程的 IO 讀寫任務拆分給一組獨立的線程去執行,這樣就可以使多個 socket 的讀寫可以并行化了,但 Redis 的命令依舊是由主線程串行執行的。

需要注意的是 Redis 6.0 默認是禁用多線程的,可以通過修改 Redis 的配置文件 redis.conf 中的 io-threads-do-reads 等于 true 來開啟多線程,完整配置為 io-threads-do-reads true,除此之外我們還需要設置線程的數量才能正確的開啟多線程的功能,同樣是修改 Redis 的配置,例如設置 io-threads 4 表示開啟 4 個線程。

小貼士:關于線程數的設置,官方的建議是如果為 4 核的 CPU,建議線程數設置為 2 或 3,如果為 8 核 CPU 建議線程數設置為 6,線程數一定要小于機器核數,線程數并不是越大越好。

關于 Redis 的性能,我的父王  antirez(Redis 作者)在 RedisConf 2019 分享時曾提到,Redis 6 引入的多線程 I/O 特性對性能提升至少是一倍以上。國內也有人在阿里云使用 4 個線程的 Redis 版本和單線程的 Redis 進行比較測試,發現測試的結果和 antirez 給出的結論基本吻合,性能基本可以提高一倍。

[[346770]]

總結

Redis 雖然依靠自己的:基于內存操作、數據結構簡單、多路復用和非阻塞 I/O、避免了不必要的線程上下文切換等特性,在單線程的環境下依然很快;但對于大數據的 key 刪除還是卡的飛起,因此在 Redis 4.0 引入了多線程:unlink key/flushall async 等命令,主要用于 Redis 數據的刪除,而在 Redis 6.0 中引入了 I/O 多線程的讀寫,這樣就可以更加高效的處理更多的任務了,Redis 只是將 I/O 讀寫變成了多線程,而命令的執行依舊是由主線程串行執行的,因此在多線程下操作 Redis 不會出現線程安全的問題。

Redis 無論是當初的單線程設計,還是如今與當初設計相背的多線程,目的只有一個:讓 Redis 變得越來越快。

所以 Redis 依舊沒變,他還是那個曾經的追風少年~ 

 

責任編輯:龐桂玉 來源: Java知音
相關推薦

2015-11-04 14:45:24

數據分析大數據創業

2023-10-15 12:23:10

單線程Redis

2023-03-21 08:02:36

Redis6.0IO多線程

2019-05-07 09:44:45

Redis高并發模型

2019-06-17 14:20:51

Redis數據庫Java

2020-10-30 16:20:38

Redis單線程高并發

2020-06-11 09:35:39

Redis單線程Java

2023-08-17 14:12:17

2021-03-03 08:01:58

Redis多線程程序

2019-02-18 08:10:53

2019-05-06 11:12:18

Redis高并發單線程

2025-01-17 08:23:33

2025-04-24 08:15:00

Redis單線程線程

2020-11-17 10:20:53

Redis多線程單線程

2025-06-17 00:22:00

2021-12-28 09:50:18

Redis單線程高并發

2022-01-04 11:11:32

Redis單線程Reactor

2024-08-30 14:31:48

2019-04-02 11:20:48

Redis高并發單線程

2024-08-21 10:28:54

Redis數據結構內存
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 精品欧美激情精品一区 | 九九精品在线 | 日韩综合在线视频 | 六月色婷 | 日韩美女一区二区三区在线观看 | 亚洲视频欧美视频 | 视频一区二区在线观看 | 97久久久久久久久 | 国产高清不卡 | 久久伊| 欧美日韩精品影院 | 亚洲精品视频在线 | 久久免费香蕉视频 | 久久久91 | 日韩福利| 牛牛热在线视频 | 天天欧美 | 国产欧美精品一区二区三区 | 国产综合第一页 | 亚洲成人av在线 | 欧美精品久久久久久久久久 | 自拍偷拍亚洲一区 | 国产亚洲精品精品国产亚洲综合 | 亚洲一区在线免费观看 | 国产一区二区三区网站 | 午夜影院在线视频 | 亚洲 中文 欧美 日韩 在线观看 | 亚洲永久入口 | 久久曰视频| 欧美国产日本一区 | 91精品国产综合久久久动漫日韩 | 欧美精品在线一区 | 一区二区av | 狠狠色网 | 国产美女在线播放 | 国产精品1区2区 | 91视频网| 五月综合色啪 | 国产亚洲一区精品 | 91免费在线视频 | 免费久久久 |