1.一、Reactor多線程前端
1.二、處理流程mysql
1) NIOAccetpor中的Selector只接收SocketChannel的accept事件;
2) 從NIOReactor[]數組中依次獲取一個NIOReactor;
3) 將此SocketChannel放到對應NIOReactor中的Queue中;
4) 由NIOReactor新建的Thread,不斷循環將Queue中的SocketChannel取出並註冊到當前NIOReactor關聯的Selector上面;
5) 不斷循環Selector返回的SelectionKey進行數據讀取;
6) 從DirectByteBufferPoll中先分配一塊內存(trunk=4k);
7) 讀取SocketChannel中的數據,若是一個trunk能夠讀完數據則進行認證、mysql協議解析,encode、並調用對應的handler處理。不然計算報文的長度根據size分配足夠的內存,並將以前讀取的數據copy進來,繼續讀取直至讀完。sql
1.三、流程圖數據庫
1.四、優勢後端
1) 一個NIOAcceptor(聚合了一個Selector,一個線程)能夠處理成百上千的客戶端鏈接,每當有一個新的客戶端鏈接時,就從NIOReactor[]數組中順序獲取一個NIOReactor,當達到數組上限時從新返回0,基本保障了NIOReactor間的負載均衡。
2) 經過NIOReactor[]線程組實現了串行化線程水平並行執行,線程之間沒有交集,充分利用多核提高並行處理能力。
3) NIOReactor[]線程組互不影響,起到故障隔離做用。
4) 報文的讀取、解析、編碼、以及後續Handler的執行,始終都在一個NIOReactor 的IO線程上面操做,避免了線程上下文切換和併發修復的風險。數組
1.五、缺點網絡
1) 維護性差:IO線程和handler業務線程爲同一個線程,一旦handler處理(認證、解析、PS渲染、SQL解析、SQL路由)出現延遲,這些延遲毛刺定位難度很大。多線程
1.六、思考併發
1、爲何不使用主從Reactor?
2、爲何或怎麼能夠把IO線程和業務Handler分開?負載均衡
DirectByteBufferPool啓動時向系統申請固定數量(PROCESSORS * 20),大小(512 * 4096)同樣的連續內存空間用於建立ByteBufferPage,ByteBufferPage被切分爲固定大小的trunk(4096)塊。經過BitSet位圖進行內存的分配和回收,1表明已使用,0表明未使用,在每一個ByteBufferPage上面經過AtomicBoolean實現併發控制。
2.一、分配流程
1) 根據size計算須要的trunk數量,整塊連續分配,size<4K則分配一個trunk;
2) 根據上次分配的Page+1,依次從ByteBufferPage[]中取出一個進行分配,報錯分配分配相對均衡,同時必定程度上緩解了線程間的競爭。
3) 分配時先對ByteBufferPage經過AtomicBoolean進行加鎖,找到符合數量(BitSet爲0)的連續空間,經過ByteBuffer的limit()和position()以及slice()進行分配,同時將對應的BitSet位圖置爲1,若是找不到則去下個Page中分配;
4) 若是都沒有空間,則再分配異常,再沒有則使用HeapByteBuffer。
2.二、優勢
1) DirectByteBuffer的分配和釋放比堆內慢10-20倍,進行池化能夠快速分配內存;
2) 池化技術可使對象複用,下降GC頻率。
3) trunk塊大小相同,BitSet位圖內存分配和回收簡單;
4) 作爲全局數據,經過設置ByteBufferPage[]數量,緩解多線程環境下的鎖競爭;
2.三、缺點
1) 一次性申請完成以後,不能動態擴展;
2) 固定大小內存,管理的粒度很粗,碎片較大;
2.四、Netty內存管理
Netty內存池的層級結構主要分爲,Arena,ChunkList、Chunk、Page、SubPage
Arena:表明一個內存區域,內存池由Arena[]數組組成,分配時每一個線程按照輪訓策略選擇一個Arena分配。一個Arena由兩個PoolSubPage和ChunkList雙向鏈表組成。
ChunkList:由多個Chunk組成的雙向鏈表,可動態變化。
Chunk:每一個Chunk由默認由2048個Page組成。
Page:大小固定,默認8K,經過徹底二叉樹管理Page的分配和釋放。
SubPage:大小不固定,又分爲tinySubPage,區間[16,512)和smallSubPage,區間[512,4096),經過位圖分配和釋放。
代碼結構:
1、Parser:將SQL轉換成AST(抽象語法樹),包括Parser(語法解析)和Lexer(詞法解析)
2、AST(Abstract Syntax Tree)
3、Visitor:遍歷AST的工具
4、執行流程:詞法解析(SQL詞庫) -> 語法解析(校驗是否符合語法邏輯,如from 後面要跟表名) -> 輸出AST
4.一、定時任務
1) 後端鏈接檢測:SQL執行超時(300s)檢查、Idle檢查;
2) 前端鏈接檢測:Idle檢查(默認30min);
3) 後端鏈接健康心跳檢測:鏈接是否正常(被對端關閉,網絡斷開重連等),維持最小鏈接;
4) 數據節點DataHost心跳檢測:檢測datasource是否可用;
5) 全局表一致性檢測:數據量是否一致;
5.一、優化
1) 聚焦而不是膨脹,核心功能和業務需求以前的平滑;
2) 提高統一內存池管理效率,緩解多線程分配時的鎖競爭,減小內存碎片;
3) 雜亂的ScheduledExecutorService定時任務(10個)打亂了NIOReactor串行化設計思想,形成了沒有必要的線程上下文切換,可統一管理這些定時任務,參考Netty中的時間輪定時任務;
5.二、將來
一、多維度、立體化、全方位監控體系;
二、便捷、易用的管控運維平臺;
3、分佈式數據庫(動態擴容、Percolator分佈式事務);
Ref:
http://www.javashuo.com/article/p-wtfscydu-cy.html