大清已經亡了,你還停留在Redis是單線程的時代?

Redis簡介

Redis 是一個開源(BSD許可)的,內存中的數據結構存儲系統,它可以用作數據庫、緩存和消息中間件。 它支持多種類型的數據結構,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 與範圍查詢, bitmaps, hyperloglogs 和 地理空間(geospatial) 索引半徑查詢。 Redis 內置了 複製(replication),LUA腳本(Lua scripting), LRU驅動事件(LRU eviction),事務(transactions) 和不同級別的 磁盤持久化(persistence), 並通過 Redis哨兵(Sentinel)和自動 分區(Cluster)提供高可用性(high availability)。

Redis單線程時代

  • Redis在起初嚴格意義上也不算純粹的單線程

單線程指的是網絡請求模塊使用了一個線程(所以不需考慮併發安全性),即一個線程處理所有網絡請求,其他模塊仍用了多個線程。比如持久化時,Redis就會開啓一個子線程去操作。

“單線程”的Redis爲什麼會這麼快?

Redis被廣泛應用於緩存,一切皆源於Redis基於內存計算,它的讀取速度要比尋常的RMDB(關係型數據庫)快上很多。

  • Redis每秒可執行大約110000次的設置(SET)操作,每秒大約可執行81000次的讀取/獲取(GET)操作。
  • Redis操作具有原子性,能保證併發情況下數據的安全性。
  • Rdis採用請求上的單線程,避免了不必要的上下文切換和線程間的資源競爭。
  • Redis採用瞭如非阻塞IO模型、IO的多路複用等多種IO模型。

Redis的瓶頸

先來看Redis的特性,Redis是基於內存進行操作的NoSql數據庫。

  • 首先CPU不會成爲Redis的瓶頸,這也是爲什麼單線程的Redis依然恐怖如斯的寫照
  • Redis多用於高併發下做緩存,所以Redis的瓶頸最有可能是機器內存的大小或者網絡帶寬

6.0版本後的Redis線程問題

Redis的作者在 2019-12-19 發佈了Redis 6.0 RC1,但是即便是這種大佬也沒有逃過“真香定律”,Redis居然開始走上了多線程的潮流路線。也就是說從6.0開始Redis就是多線程的了,這也就意味着以後面試又多一個坑!

作者在自己博客中對新特性的介紹
加粗標紅原文地址:Redis 6.0 RC1 作者博客原文

Redis 6 被稱爲是 Redis 有史以來最大的一個版本,就在2020年五一期間,6.0穩定版本發佈了。下面單就線程方面先了解一下新版本特性:

redis的多線程不是你理解的多線程

  1. 但跟 Memcached 這種從 IO 處理到數據訪問多線程的實現模式有些差異。Redis 的多線程部分只是用來處理網絡數據的讀寫和協議解析,執行命令仍然是單線程。之所以這麼設計是不想因爲多線程而變得複雜,需要去控制 key、lua(一種輕量級腳本語言)、事務,LPUSH/LPOP(redis語法:將一個或多個值插入到列表頭部(左邊)、移出並獲取列表的第一個元素(左邊)) 等等的併發問題
  2. 主線程負責接收連接請求,讀事件到來(收到請求)則放到一個全局等待讀處理隊列
  3. 主線程處理完讀事件之後,通過 RR(Round Robin) 將這些連接分配給這些 IO 線程,然後主線程忙等待(spinlock 的效果)狀態
  4. IO 線程將請求數據讀取並解析完成(這裏只是讀數據和解析並不執行)
  5. 主線程執行所有命令並清空整個請求等待讀處理隊列(執行部分串行)

redis的多線程是默認關閉的

  1. Redis6.0的多線程默認是禁用的,只使用主線程。如需開啓需要修改redis.conf配置文件:io-threads-do-reads yes
  2. 線程數設置通過修改redis.conf配置文件:io-threads屬性指定線程數量。關於線程數的設置,官方有一個建議:4核的機器建議設置爲2或3個線程,8核的建議設置爲6個線程,線程數一定要小於機器核數。還需要注意的是,線程數並不是越大越好,官方認爲超過了8個基本就沒什麼意義了。
  3. 性能方面,Redis作者在RedisConf 2019的分享中提到,開啓多線程後的Redis性能可以提升一倍左右
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章