本篇將去探索twemproxy源碼的主幹流程,想來對於想要開始啃這份優秀源碼生肉的童鞋會有不小的幫助。這裡我們首先要找到 twemproxy正確的打開方式——twemproxy的文件結構,接著介紹twemproxy程式代碼框架,最後介紹twemproxy程式的主幹流程。主幹流程是本章節的重中之重。這 ...
本篇將去探索twemproxy源碼的主幹流程,想來對於想要開始啃這份優秀源碼生肉的童鞋會有不小的幫助。這裡我們首先要找到 twemproxy正確的打開方式——twemproxy的文件結構,接著介紹twemproxy程式代碼框架,最後介紹twemproxy程式的主幹流程。主幹流程是本章節的重中之重。這次主要是為了能將這份代碼較為複雜的流程進行一些簡單的模塊分解和流程分解,以方便我們後面的閱讀。
twemproxy的文件結構
當然接下來首先要上一幅圖,就是twemproxy的文件結構圖
圖1 文件結構圖
如圖1所示,src下的是我們最重要的業務代碼,這裡有幾個重要的文件夾,1文件夾里的是網路編程模型,裡面包含epoll,kqueue以及evport幾個常用的模型。2文件夾里的是哈希演算法,其主要來哈希redis協議或者memcache協議的key,包括crc16,crc32,MD5等哈希演算法。3是比較重要的文件,它是在這裡不僅完成瞭解析redis協議或者memcache協議,還完成了這兩個協議的分片工作。
這裡還有幾個重要的文件組,4是程式的入口,如圖所示,main函數就在其中,5是管理與客戶端的連接,6是用來解析配置文件的,7是實現了透明連接池的,8是可以看到主要的程式流程,9是實現了記憶體管理的記憶體池,10是數據收發的主幹流程,11是數據請求和響應,是數據收發流程10的具體實現,12是用於管理與伺服器的連接。
這裡可以初步窺視到twemproxy精緻的代碼結構和高可讀性,通過查看文件的名字,我們竟然可以大概YY出這個文件下的代碼的作用,而且是八九不離十。
通過這個我們得到了閱讀代碼的整體思路(我們本次閱讀代碼的重點是redis伺服器集群下的twemproxy)
1.首先以10,11為主線來觀察整個程式的收發流程,因為我們知道作為一個緩存中間件代理,最重要的無非是與客戶端以及伺服器的交互流程。
2.再在主幹流程上慢慢拓展,通過探索3文件夾里的解析分片功能,來談下redis協議的細節和它能進行分片的原因。
3.接著通過上述標紅的各功能點6,7,9去觀察整個程式,這樣對於程式的實現細節有一定的瞭解。
4.最後我們再去觀察一些次要的功能點,如監控,日誌記錄以及哈希演算法等功能的實現。
twemproxy的主幹流程概述
接下來我們要探索twemproxy的主幹流程,首先我們要知道twemproxy與外界如何交互的,在上文《twemproxy架構分析》中,我們知道了twemproxy架構的架構,為此,我們可以抽象出一幅圖形
圖2.twemproxy零層數據流圖
如圖2,這裡的conn是表示由客戶端發起的與twemproxy的連接,而s_conn是由twemproxy發起的twemproxy的連接
這樣我們可以將數據收發過程分成以下四步:
1.twemproxy首先接受客戶端發起的conn請求。
2.再通過哈希conn請求的key值將其切分成具有相同key哈希值的請求——s_conn請求發給服務端——redis服務集群
3.接著等待接受來自服務端——redis服務集群的s_conn響應,通過這之前的映射關係將其和conn請求關聯起來。
4.最後將每一個conn請求對應的每一個conn響應發給客戶端。
我們能收發數據的一個重要原因是redis伺服器的實現是單線程的,為此,twemproxy的實現也是單線程的。
這樣我們可以將其分成兩個部分,與客戶端交互的1,4是客戶層,與服務端交互的2,3是服務層。這樣twemproxy就被分成了下麵一幅圖。
圖3. twemproxy流程細化圖
接著,我們將服務層和客戶層細分成4個模塊,我們可以認為1是客戶層接收,2是服務層發送,3是服務層接收,4是客戶層發送。這樣無疑1,2步驟構成了圖1中11的nc_request.c的主要內容,而3,4構成了圖1中11的nc_response.c的主要內容,如圖4所示。
圖4. twemproxy模塊圖
然後,在圖1中10的nc_message代碼閱讀中我們會發現有兩個重要流程:一個是發送流程msg_send和一個接收流程msg_recv。
其實2和4是遵循同一個發送流程msg_send,而1和3是遵循同一個接收流程msg_recv。
最後在圖1中的8我們看到這兩個流程通過epoll模型感知程式究竟要執行哪個操作,即是執行msg_send流程還是執行msg_recv流程。
這樣我們通過上述的圖2,圖3以及圖4,將圖1中10、11以及8中要完成的主要流程進行了分析,構建了他們之間的基本聯繫,對於閱讀代碼有了一個骨架,相信未來通過對於這兩個流程和4個模塊的關鍵代碼分析,我們就可以“會當凌絕頂,一覽眾山小”。
總結
通過對源碼文件結構的探索,我們知道了twemproxy的主幹內容和關鍵點,明確了閱讀twemproxy代碼的流程,接著分析twemproxy的主幹內容,我們歸納出了我們未來閱讀代碼的兩個重要流程即發送流程msg_send和接收流程msg_recv,還有四個主要模塊即:客戶層接收、服務層發送、服務層接收以及客戶層發送,明確了各個模塊的功能、兩個流程與各個模塊的聯繫。下一章將首先完成兩個重要流程代碼的講解。