@erixhao
大數(shù)據(jù)時代,分布式緩存領域,大家可能較為熟悉Redis,當紅一哥,還有經典老將Memcached, 以及新秀Apache Ignite, 當然還有Oracle的Coherence內存數(shù)據(jù)網(wǎng)格,今天我們主要關注投行金融領域的分布式緩存一哥Gemfire。
1. 前世今生
Gemfire的第一個商業(yè)版本由GemStone公司操刀正式發(fā)布于2002-2003年間,成為業(yè)界J2EE JCache -JSR107標準的中間件,兼容Java, C++, C#, 并在CEP(Complex Event Processing)處理領域一枝獨秀。2008年借著金融危機之際憑著其實力擊敗老牌廠商Oracle, 大舉進入華爾街金融領域,而其中Citi則是Gemfire的鐵粉,據(jù)稱全球2/3的Gemfire應用跑在Citi的服務器上,尤其是固定收益類交易系統(tǒng)的最愛,各位老友看到請自動點贊舉牌。

之后GemStone被Spring之父Rod Johnson在當時的VMare時慧眼識珠,2010年收購并入SpringSource部門作為進軍Cloud以及大數(shù)據(jù)的入口,目前則與Spring一并成為Pivotal中重要的In-Memory Data Grid, 并于2015年其核心模塊開源為Apache Geode核心項目。
2. Gemfire整體分布式架構
總體來說Gemfire提供了基于內存的海量數(shù)據(jù)實時處理平臺,包括低延遲高吞吐,線性動態(tài)擴展
(流行的話叫“彈性水平擴展”),HA,MapReduce,聽起來很Hadoop, 這些是一切后SQL時代的分布式大數(shù)據(jù)產品入門款必備裝備。

可以粗略看出Gemfire一些精髓, 如支持CEP Subscribers, 數(shù)據(jù)支持Replicated, Partitioned, ?線性水平擴展,Shared Nothing Disk Persistence, Cache同步Read/Write Through與異步Write Behind。
3. 核心概念

1.?Region
Region是Gemfire中一Map的分布式實現(xiàn),同時具備了支持查詢,事務。這個是Gemfire的核心中核心,一切的一切始于此。
Replicated Region: 一個Replicated Region保存所有分區(qū)的數(shù)據(jù)拷貝。
Partitioned Region: 只保存一部分分區(qū)的數(shù)據(jù)拷貝。
2.?Shared-Nothing Persistence
支持非共享持久化,每一個peer持久化數(shù)據(jù)到本地磁盤,Gemfire持久化允許在磁盤維護一份配置的數(shù)據(jù)拷貝
3.?Distributed
Distributed Member: Gemfire托管的集群中成員
Distributed Transaction: 跨節(jié)點,集群更新事務,分布式事務。
Distrbuted Lock: 分布式集群鎖
4.?Locator & Gateway
Gemfire的Locator類似ZooKeeper, 協(xié)調客戶端與服務器成員,相互發(fā)現(xiàn),以及簡單負載均衡(非負荷均載)。
Gateway: 作為Gemfire跨WAN網(wǎng)同步數(shù)據(jù),如HK, TK, NY等。
4. 拓撲結構
1. Peer-to-Peer
緩存潛入應用,共享堆內存,適合小型緩存應用。
原以為這種架構在企業(yè),金融機構無用武之地,殊不知一些大型金融機構的小型IT項目竟然采用此架構,沒辦法cowboy,今天需求明天生產。

2. Client/Server結構
緩存層由分布式集群系統(tǒng)來組成,是多數(shù)中大型系統(tǒng)首選。

其中分布式引入Loactor來管理,結耦,離散,分布客戶端與服務器端。
客戶端服務器發(fā)現(xiàn)機制:

上圖可以看出客戶端與服務器通信要先透過Locator提供的發(fā)現(xiàn)機制,當然鑒于此所有的服務器端必須與Locator進行通信廣播其生死狀態(tài),類似ZK。Locator通過JVM廣播消息或者TCP實現(xiàn)通信定位。每個新加入或者離開的成員都會更新Loactor,并從Locator上發(fā)現(xiàn)目前可用成員列表。
我們看一下客戶端完整通信圖:

另外,Locator可以提供簡單負載均衡,只是基于當前服務器是否有客戶端連接而已。
Gemfire提供了垮節(jié)點將鍵值對均勻分布到節(jié)點,以及一致性哈希算法等。
如果希望定制負載負荷均衡,Gemfire提供了Member Groups,可以把某些服務器分組,固定為某些客戶/某類請求服務,再獲得負荷均衡的優(yōu)勢同時也失去了全局分布式的優(yōu)勢,正所謂有利有弊。

Server內部提供了connection poor,queue以及subscription機制,以并行處理以CEP事件通知機制。同樣,Gemfire客戶端也提供了connection pool。

經驗豐富的老司機看到這里肯定會說,全局就一個Locator一定會造成單點故障,當然分布式系統(tǒng)的必備。Gemfire也提供了啟動多個Locator的能力。

3.多地/多數(shù)據(jù)中心WAN部署
互聯(lián)網(wǎng)世界比較流行,行話異地多活,全國甚至全球多地多數(shù)據(jù)中心部署。大型金融系統(tǒng)中也是不可或缺的,如全球多金融中心部署,NY, London, HK, TK等分布式多數(shù)據(jù)中心緩存。做的好的話,可以做到任意一個數(shù)據(jù)中心癱瘓,系統(tǒng)自動切換到其他數(shù)據(jù)中心運營,差的話就要人工干預了,不過至少不會完全癱瘓。

多數(shù)據(jù)中心的數(shù)據(jù)同步則是靠gateway來同步的,gateway receiver與gateway sender來發(fā)送接受數(shù)據(jù)中心的變化,如上圖東京如果有緩存數(shù)據(jù)變化,新增或者變化,則會通過gateway發(fā)送給紐約的集群,通過gateway receiver來更新紐約的緩存,由于跨多地,網(wǎng)絡,所以非實時同步更新,做到最終一致性。當然sender中必須提供了queue。

一個數(shù)據(jù)中心的集群是靠Locator來維系發(fā)現(xiàn)各個服務器的,對于跨多數(shù)據(jù)中心,Gemfire則通過每個集群的distributed-system-id,依靠remote-locators來發(fā)現(xiàn)數(shù)據(jù)中心集群是否存活。
如下圖定型的全球部署系統(tǒng)架構:

多數(shù)據(jù)中心支持多種拓撲結構,如Parallel則是每個數(shù)據(jù)中心均相互感知,當然其數(shù)據(jù)同步,通信也必然耗資源。

當然,還有其它多種網(wǎng)絡拓撲,介于每個數(shù)據(jù)中心網(wǎng)絡,帶寬以及其它因素,最好與網(wǎng)絡系統(tǒng)人員一起設計網(wǎng)絡拓撲結構。
部署拓撲結構
新版的Gemfire 8.x支持多種部署拓撲結構:

圖是Pivotal的黑酷炫風格,放到微信圖太小了,不解釋,基本是我們上面的細分與組合。
5. Data Region
上文介紹過,Region是Gemfire中用來管理,存儲數(shù)據(jù)的核心數(shù)據(jù)結構,本身實現(xiàn)了Map接口,類似于ConcurrentMap,同時支持分布式跨物理節(jié)點。

Region同時支持嵌套,子Region。Region又區(qū)分為Patitioned,Replicated, Distributed non-replicated, Non-distributed(local)。

Gemfire的Data Region的讀寫操作支持同步讀,同步寫,異步寫。
數(shù)據(jù)分布模型支持D-no-Ack, D-Ack, Global(鎖)。
此外,Region還進行分布式支持以下高階:
- 溢出至磁盤持久化(LRU)
- 持久化到磁盤
- 跨節(jié)點數(shù)據(jù)同步
- 外部數(shù)據(jù)源(數(shù)據(jù)庫)延遲加載數(shù)據(jù)
- OQL
1?Replicated Region
Replicated Region在每個Gemfire成員上都同步的保存一份完整的數(shù)據(jù)拷貝。Proxy:數(shù)據(jù)不存在本地緩存,Proxy成員提供了對Region的訪問,需要其它成員配置Region的Non-Proxy拷貝用以存放數(shù)據(jù)。

顯然這是以空間換時間;這種Data Region適用于小型數(shù)據(jù)集并且讀很頻繁的操作;
2?Partitioned Region
Partitioned Region顧名思義,將數(shù)據(jù)分散,每個成員近保存數(shù)據(jù)一部分,時間換空間;

既然分區(qū)存儲了,一定是適合大數(shù)據(jù)的數(shù)據(jù)集了,以及寫/修改較多的數(shù)據(jù)集,并提供給了分布式并行查詢,處理, MapReduce。
3?OQL
Region提供類SQL, 基于SQL-92子集的OQL查詢,注意可以跨分布式節(jié)點以及并行查詢,這點是很多緩存不具備的,盡管簡單。
SELECT, WHERE, DISTINCT, COUNT, IN, LIKE, 嵌套自查詢,Map查詢( p['key'] = '1.0' ),ORDER BY,。
注意,OQL僅支持COUNT,不支持其它SUM, MIN, MAX。
另外,OQL支持Limit, 類似TOP:
SELECT * FROM /Region1 limit 100;
這里還提供高階的Join, 大多數(shù)No-SQL都不支持,這里因為更類似二維表格,也提供了Join操作, 如下:
SELECT * FROM /Region1 r1, /Region2 r2 WHERE r1.status = r2.status;
可見,還是相對較熟悉,強大。當然這里的Join僅支持內連接,并不支持左右連接,畢竟沒有那么強大。
既然可以提供OQL查詢,支持Join, 那老司機又問是否可以做Index? 還真可以。

當然也支持代碼動態(tài)創(chuàng)建了。當然,沒有免費的午餐,與RDBMS類似,索引是把雙刃劍,提供索引必然會降低修改,更新性能,提升查詢性能。
用慣了Oracle了老鳥,這里居然也支持HINT,好吧。
當然,也不建議用過度負載的OQL,畢竟不是強大的RDBMS,況且考慮到兼容性,可移植性,以及沒有那么強大的調試支持。
6. 事務支持
事務的操作首先作用在數(shù)據(jù)主拷貝節(jié)點,然后分布到其它成員。其中:
- 運行事務代碼的成員被稱作事務初始化器
- 管理事務和數(shù)據(jù)的成員被稱為事務數(shù)據(jù)節(jié)點
Gemfire提供了分布式事務支持,難能可貴,在分布式世界里,提供分布式事務可比較重!所以盡量少用,開銷太大,甚至可能全局死鎖。

Gemfire同樣提供了分布式鎖支持,可以顯示創(chuàng)建分布式鎖, 在任何一個時間點,
工作原理:
在并發(fā)訪問緩存的時候, 事務之間是隔離的。每一個事務都有自己的私有空間,包括已經讀取的數(shù)據(jù)及其變更;當一個數(shù)據(jù)條目進入事務時,將在事務視圖/空間生成一個數(shù)據(jù)狀態(tài)的快照,此事務能保存數(shù)據(jù)的原始狀態(tài),快照的另一個作用則用于題解恢復寫沖突。
當事務提交成功時,事務視圖中的記錄被合并到緩存上,如果提交失敗或者回滾,則所有變更將放棄。提交事務時,Gemfire采用了兩階段提交協(xié)議, Two-Phase commit Protocol。
Gemfire甚至支持了JTA分布式事務:

慘不忍睹,自己官方文檔都放不下該圖,可見復雜。不推薦,不建議。
通常,非必需,不建議使用分布式事務,因為會大大降低整體的性能,這與使用緩存的本意背馳。
7 ?分布式鎖
Gemfire也提供了分布式鎖支持,在任何一個時間節(jié)點,Gemfire系統(tǒng)保證只有一個線程可以用于該鎖。另外線程將鎖定整個服務,防止系統(tǒng)中其它線程鎖定這個服務??梢娖涑杀局?。
分布式鎖分為隱式鎖與顯示鎖。大多數(shù)情況下,系統(tǒng)自動利用隱式鎖進行數(shù)據(jù)操作。鎖服務從系統(tǒng)成員接受鎖請求,并放入隊列,按順序授予鎖。授予者負責運行鎖服務。
當分布式鎖服務創(chuàng)建時,分布式系統(tǒng)中某個成員通過選舉成為分布式鎖服務的授予者,授予者負責管理這個鎖。當這個成員出現(xiàn)故障時,鎖授予功能將被遷移到其它成員,且不丟失鎖狀態(tài);這些細節(jié)處處可以看到分布式設計的目標及精髓。
8. Map Reduce
Gemfire與時俱進,提供了在分布式節(jié)點進行Map Reduce的操作函數(shù)。

函數(shù)用Java自行編寫,部署,運行。Gemfire支持兩種形式的函數(shù)運行模式,方式1,提前注冊并部署自定義函數(shù)到每個成員,運行時指定函數(shù)名字,顯然不靈活,高耦合,每次改動函數(shù)都要全局部署;方式2,運行時動態(tài)ship函數(shù),所謂ship function rather than data;更加現(xiàn)代的模式(從Gemfire 6.x開始支持)當然為了做到這種高效,必然要RPC + 序列化,所謂有利有弊,好處顯然易見,首選推薦。
9. Management
分布式系統(tǒng)的Dev & Ops中的Ops也是重中之重,側面反映一個分布式系統(tǒng)的成熟度。

Gemfire支持gfsh command-line執(zhí)行啟動/停止,部署,創(chuàng)建region,執(zhí)行函數(shù),管理硬盤存儲,倒入導出緩存數(shù)據(jù),監(jiān)控process等等,靈活強大;
同時Gemfire支持JMX, ?Gemfire Pulse, Data Browser, VSD, JConsole/JVisualVM等。

JMX太土?當然,Gemfire提供很多集成工具用來監(jiān)控內存,磁盤,Region, 網(wǎng)絡, 統(tǒng)計分析等等。
下面我們看幾個Gemfire Pulse的監(jiān)控視圖:
Cluster監(jiān)控

集群中每個member的狀況:

Region View:

Data Browser, 緩存當然需要一個即視的數(shù)據(jù)瀏覽器支持了。

10. 12306
是的,12306;國內Gemfire最牛X至少是最著名的應用。當與老外同事介紹時,'12306', 一臉萌相,這名字起的。好吧‘China's Largest Online Trading System’ , 聽懂了,有時候需要吹一下。

12306的架構正是運行在Linux X86的集群Gemfire, 水平彈性擴展,當年鐵道部想必也是調研了眾多分布式產品,多重分析評估,最終Gemfire勝出。Gemfire在支持萬次/每秒查詢,以及高頻寫/修改,二者兼?zhèn)涞馁摺?/p>
11. DT時代的Gemfire
臨時加一章了,老東家的Gemfire鐵粉太多,得來點干貨了。
1
Roadmap

DT時代,Gemfire當然要配合,整合自家的PaaS平臺,以及支持HDFS, Spark, Off-heap存儲,以及在云端。
2?Architecture

大數(shù)據(jù)時代,Pivotal重新定位了Gemfire以及組織了產品線。

大數(shù)據(jù)的三駕馬車,涉獵In-Memory Data Grid, Data Warehouse, Haddop SQL。
總結
Gemfire是一款在金融領域稱霸,被證實的好產品,目前在新秀Pivotal的領導下,全面進入下一個時代,我們拭目以待。
關注公眾號:技術極客TechBooster
