一、redis簡介
Redis作者: 意大利人 Salvatore Sanfilippo(網名 Antirez) 開發(fā)。Antirez 不僅帥的不像實力派,也非常有趣。Antirez 今年已經四十歲了,依舊在孜孜不倦地寫代碼,為 Redis 的開源事業(yè)持續(xù)貢獻力量。
Redis是一個開放源代碼(BSD許可)內存中的數據結構存儲,用作數據庫、緩存和消息代理。它支持字符串、哈希、列表、集合、帶范圍查詢的排序集合、位圖、超日志和流的地理空間索引等數據結構。Redis具有內置的復制、lua腳本、lru回收、事務和不同級別的磁盤上持久性,并通過Redis Sentinel和Redis集群的自動分區(qū)提供高可用性。
Redis為啥如此快
1、Redis是用C語言實現的,一般來說C語言實現的程序“距離”操作系統(tǒng)更近,執(zhí)行速度相對會更快。
2、完全基于內存,絕大部分請求是純粹的內存操作,非常快速。數據存在內存中,類似于HashMap,HashMap的優(yōu)勢就是查找和操作的時間復雜度都是O(1);正因為 Redis 是單線程,所以要小心使用 Redis 指令,對于那些時間復雜度為 O(n) 級別的指令,一定要謹慎使用,一不小心就可能會導致 Redis 卡頓。
3、數據結構簡單,對數據操作也簡單,Redis中的數據結構是專門進行設計的;采用單線程,避免了不必要的上下文切換和競爭條件,也不存在多進程或者多線程導致的切換而消耗 CPU,不用去考慮各種鎖的問題,不存在加鎖釋放鎖操作,沒有因為可能出現死鎖而導致的性能消耗。
4、使用多路I/O復用模型,非阻塞IO,Redis 單線程處理大量的并發(fā)客戶端連接的模型。
5、使用底層模型不同,它們之間底層實現方式以及與客戶端之間通信的應用協議不一樣,Redis直接自己構建了VM 機制 ,因為一般的系統(tǒng)調用系統(tǒng)函數的話,會浪費一定的時間去移動和請求;協議簡單采用RESP協議。
作者對于Redis源代碼可以說是精打細磨,曾經有人評價Redis是少有的集性能和優(yōu)雅于一身的開源代碼。
二、Redis整體架構
通信架構
第一層:客戶端,大家熟知的如原生redis-cli、JAVA語言Jedis、Python語言redis-py等
第二層:通信,傳輸層基于TCP的resp協議
第三層:服務端,多路復用、事件循環(huán)、持久化等
三、文件事件處理器
每當一個套接字貯備好連接應答、寫入、讀取關閉等操作的時候就會產生一個文件事件。也就是說客戶端服務器發(fā)送連接、讀、寫命令都屬于文件事件。
Redis基于Reactor模式開發(fā)了自己的網絡時間處理器,稱為文件事件處理器。
文件事件處理器由四部分組成,分別是套接字,I/O多路復用程序,文件事件分派器,以及事件處理器。I/O多路復用程序,既可以讓文件處理器以單線程方式運行,保持redis內部設計的簡單性。同時又可以同時監(jiān)聽多個套接字。
I/O多路復用程序會將多個并發(fā)產生的文件事件放在一個隊列中,通過隊列有序、同步的、每次一個套接字的方式向文件事件分派器傳送套接字。只有上一個套接字處理完畢后,I/O多路復用程序才會向文件事件分派器派發(fā)下一個套接字。
處理器分類
1、連接應答處理器
2、命令請求處理器
3、命令回復處理器
四、時間事件
分類
Redis的時間事件分為以下兩類:
1、定時事件:讓一段程序在指定的時間之后執(zhí)行一次。比如說,讓程序X在當前時間的10ms之后執(zhí)行一次。
2、周期性事件:讓一段程序每隔指定時間就執(zhí)行一次。比如說:讓程序Y每隔10ms執(zhí)行一次。
實現
服務器將所有的時間事件都放在一個無序的鏈表中,每當時間事件執(zhí)行器運行時,它就遍歷整個鏈表,查找所有已到達的時間事件,并調用相應的事件處理器。