搜狗于今年7月發布了C++異步調度服務器引擎——Workflow,除了計算通信融為一體的高性能特點以外,還集成了多種常用的網絡協議,包括:Http、Redis、MySQL,所有協議都是純自研自解析,無需依賴第三方庫,而具體協議所對應的資源復用和線程調度等都由Workflow以統一的方式去進行管理,目前獲得了越來越多開發者的青睞和肯定。而最近,Workflow又支持并發布了一項復雜的通用網絡協議:Kafka,使得所有使用Workflow及其生態項目的開發者都可以通過統一而簡便的方式與Kafka交互,這也是業內唯一一款使用C++語言實現的Kafka客戶端,值引得開源社區開發者們的關注。 一、開發背景 在Workflow發布Kafka客戶端之前,業內用得比較多的是librdkafka,但這個純C的kafka客戶端有許多不足,以下是我們原先使用時遇到的部分問題: 1、線程資源和網絡資源消耗比較多 2、接口設計比較復雜臃腫,使用成本比較高 3、Kafka版本兼容性不是很好 4、消耗資源高,但是性能卻不高 5、broker主從切換低版本出現服務hang住情況,高版本偶發丟數據問題 6、異步同步偶發出現丟數據情況 針對這些問題,更好的替代方案是Workflow的Kafka客戶端:https://github.com/sogou/workflow 由于實現在Workflow的基礎上,作為Kafka客戶端即具有超高性能、超大吞吐和極省的資源占用等特點,且和其他協議的接口一樣,此Kafka客戶端還具有接口清晰,代碼可讀性強等優點,不僅節省機器成本還節省人力維護成本,非常值得一試。 二、新一代高性能C++ Kafka客戶端 Workflow的Kafka客戶端使用接口非常簡潔,首先需要創建一個client對象: 其他使用方式與框架內的其他任務無異,使用Workflow的同學可以瞬間上手: 為什么Workflow的Kafka客戶端能有以上的優點呢?主要得益于以下三方面的細節: 一.內部基于Workflow的任務流實現。Workflow的核心設計理念是將任務抽象成"任務流"的概念,這樣一個任意復雜的任務可以拆分成若干個并行任務流和串行任務流,它們之間通過串聯、并聯等方式組成一個或者多個串并聯圖,然后由Workflow內部的引擎高效異步地執行。 以Kafka協議的fetch消息為例,下圖是執行過程中任務流的串并聯圖: 一個fetch消息的任務由一組任務組成,其中包括獲取Kafka Broker的Meta任務、一系列的消費者組相關的任務、獲取offset的任務和真正的拉取消息的任務。前面的多個任務由于有依賴關系,所以組成串聯任務;而最終拉取消息的任務和Broker的個數有關,因此可以將它轉換成一個broker數目相同的并行任務。這樣做一方面可以使得邏輯很清晰,同時也可以保證執行的高效性。 二.連接復用。傳統的網絡通信往往是在程序初始化的時候,創建大規模連接池來提高網絡吞吐,這么做的一個弊端是系統資源占用過多,會導致降低程序的魯棒性。而目前這個Kafka客戶端由于內部是基于Workflow框架,Workflow對連接的管理做了很多優化,可以在保證高效高吞吐的同時,將資源控制在一個合理的范圍內。 三.內存管理。為了方便用戶的使用,內部的所有對象都基于計數實現,通過工廠方法創建任務后,在回調函數中實現處理邏輯即可。內存的分配和釋放都是框架自動完成,全程無需手動操作任務級別的內存,非常方便;同時它的邏輯又是完備自洽的,保證了高效可靠。 三、插件式發布,與Workflow完美融合 基于Workflow精巧的層次結構,Kafka協議是以插件式發布的,即無需安裝Kafka的用戶不會把Kafka相關代碼編譯進去,由此可以看出Workflow本身的架構解耦和模塊對稱性都做得非常優秀。 而Kafka的協議由于需要多次交互,Workflow復合任務又天生支持內部交互的隱藏,使得整體使用上對用戶非常簡潔透明。基于二級工廠模式也可以把許多全局信息統一管理到內存中,也是工程上結合的一大亮點。 可以說,Kafka協議與Workflow的融合相當完美,且目前在搜狗已經大規模使用,經得住工業級檢索系統大規模請求的實際考驗,歡迎業內需要的開發同學積極嘗試并與我們熱心的開發小組進行技術交流。 |