運行程序 | 平均耗時(s) | 耗時比例java (和原程序相比) |
平均吞吐量(條/s) | 吞吐量比例node (和原程序相比) |
原程序(1機器) | 44.75 | 100.00% | 7490.903759 | 100.00% |
Ignite並行計算,2實例(2機器) | 26.63 | 59.50% | 13974.03663 | 186.55% |
Ignite並行計算,4實例(4機器) | 18.50 | 41.34% | 18342.28861 | 244.86% |
Ignite並行計算,8實例(8機器) | 10.63 | 23.74% | 33336.30975 | 445.02% |
如今看測試結果,水平計算擴展的效果已經展示,但不是很是顯著,這裏應該還有優化空間。------------------------------------------------------------乾貨分割線---------------------------------------------------緩存
測試場景是有真實項目對應的,該項目使用java開發的單進程應用,而且結合Redis存儲大規模內存數據用於計算,目前並無達到性能瓶頸。沒有遠慮必有近憂,這不但願尋找分佈式解決方案,且可以較容易進行架構遷移。 Ignite既支持計算網格(分佈式計算),又支持數據網格(分佈式緩存)。沒有理由不試一試。網絡
第一個方案,直接把原程序的全局類數據結構轉換爲Ignite的Cache,使用把原程序的計算模塊總體抽取放到Ignite集羣進行分佈式計算:數據結構
compute.run(new MatchingJob(m_mapReadyDataPara));
這個架構的轉換很是容易,很快就從單進程應用遷移到Ignite分佈式框架下了,可是,執行的效果很是糟糕,即便多臺機器組成的Ignite集羣,執行效率也不及原單進程應用。嘗試了調整Ignite的線程池: publicThreadPoolSize 、 systemThreadPoolSize ,也沒有起太大做用。 卡在這個方案好久,才從新深刻理解業務和它的數據模型,又進行了一系列的方案改進:架構
compute.broadcast( new IgniteRunnable() { @Override public void run() { Iterator<Cache.Entry<String, Map<Long, List<baselink>>>> it = mapMatchingData.localEntries(CachePeekMode.ALL).iterator(); ... }} )
匹配計算完成後寫計算結果耗時巨大,進行重構,經過計算和數據並置,讓寫結果的數據寫本地,避免網絡傳輸。 按車輛進行並置,一個car的數據做爲1個job計算。 結果:較以前方案,效率提高顯著, 但水平擴展效果不佳。緣由:job粒度過細。框架
先根據carID的並置關係,預先分類在同一Ignite實例上計算的car數據,再根據實例CPU核數啓動job數。 結果:不論和原程序比較,仍是水平擴展,效果均達預期。分佈式
UUID nodeID = ignite.affinity("MapMatchingData").mapKeyToNode(car_key).id();
總結: Ignite這樣一個功能全面的內存框架,由java語言開發,部署很是簡單,能夠說開箱即用。尤爲對於java開發人員,簡直沒有學習成本,借用官方的說法,Spark用於大數據處理,而Ignite則用於快數據處理。後面,還會寫一寫Ignite在支持SQL方面的表現,敬請關注。ide