多節點在不依賴外部組件的情況下。實現的方法有兩種:
1. 如果節點不多,可以每個節點都保留一個副本,所有的時間線判斷都在本地完成。
2. 如果節點比較多,可以采用分布式存儲,當本地判斷不存在時,需要廣播所有的節點判斷返回該時間線是否存在,然后更新統計計數。
因此篩選了3個java的組件,可用于實現節點之間的同步。
Atomix
atomix是基于事件驅動、有良好容錯的分布式框架。支持集群管理,異步消息,分組,選主,異步并發控制,切片以及復制等功能。
提供了大量的分布式數據結構,例如:
AtomicValue、AtomicCounter、AtomicMap、AtomicMuliteMap、DistributedSet、DistributedList等等。
atomix本質還是采用c/s模式,這里的server是一個cluster,所有要先引導一個獨立的集群。然后建立一個AtomixClient,設置cluster,即可與之通訊,使用分布式數據結構,發送消息隊列。
infinispan
infinispan是一個分布式內存k/v數據存儲。可以用java lib方式嵌入java服務中,也可以作為單獨的服務提供遠程接口。infinispan提供以下4種模式:
- Local: 只支持本地存儲,不會和其他節點分享數據
- Invalidation caches: 該模式也不會分享數據,僅當數據失效時會通知其他的節點
- Replicated caches: 該模式下所有節點的數據會相互同步,適合讀多寫少的情形。
- Distributed caches: 分布式緩存數據,infinispan會幫你平衡數據,適合擴展。
infinispan是在jGroups上實現的,同時提供豐富功能:有效期、緩存上限、持久化、事務、查詢和索引、事件以及對應的監聽器。
jGroups
jGroups是一個可靠的消息工具,它通過創建一個集群讓內部節點相互通訊。主要功能如下:
- 集群的創建與刪除,集群節點間通過端口相互訪問,支持節點的加入和刪除。
- 探測成員的加入、離開以及碰撞并通知集群節點。
- 發送點對點消息,發送廣播消息。
jGroups支持多種協議。相比前兩種,jGroups只負責保證收發消息,使用起來也比較簡單。
總結
-
atomix提供了各種豐富的組件,可以選主,也有消息傳輸。如果依托atomix實現時間線控制。可采用
atomix+bloomFilter+rocksdb方式。實現如下:- 通過atomix選出主機器A,A機器保存最全的時間線
- 一條新的時間線T過來,本地判斷T是否為新時間線,然后A機器判斷是否為新時間線,確認為新時間線那就保存本地和hbase,同時通知A機器
- 判斷時間線是否超過限制,可以通過A機器的計數決定。
- 時間線ttl就更加簡單,直接在A機器開啟定時器,掃描所有的時間線,通知所有節點和hbase清理時間線,其他節點需要每天更新的時間線時間同步到A機器,再由A機器同步至hbase
- 普通機器失效,直接將hbase數據同步至本地,連接上atomix集群即可
- A機器失效,atomix重新選主,系統暫停服務。等到將hbase的數據同步至新主服務再對外提供服務
- 缺點:A機器承擔了判斷時間線和同步功能,壓力比較大。主服務器失效的情況下影響很大,時間線到期未清理同時主服務器失效可能會導致有些時間線一直得不到清理。
-
infinispan可以看成是redis的替代品,它就是一個內存k/v數據庫。如果采用infinispan控制時間線,可以使用
infinispan+bloomFilter的方式實現。實現如下:- infinispan采用第4種方式,分布式緩存數據,保證集群有一定的副本。
- 判斷時間線則先本地bloomFilter驗證,直接infinispan驗證,最后驗證infinispan的總數,保證infinispan內存上數據是準確的
- 時間線ttl則讓前端每天定時通過nginx發送一條消息,消息只會落到一臺機器,就由這臺機器清理infinispan上的時間線和hbase的時間線。最后返回前端,由前端通知所有節點重建bloomFilter。infinispan自帶有效期和事件監聽器,或許可以利用這一功能實現ttl,避免和前端交互。
- 如果infinispan集群的驗證和遍歷速度很快,那就可以省去bloomFilter。
- 缺點:節點少的情況,單個節點內存保存的數據量很大,機器集體失效的情況下,時間線寫入時間數據會丟失。infinispan沒有進行測試,目前不知道性能如何,能否扛住每秒6萬的打擊。
-
jGroups可以看成一個消息同步工具。采用就jGroup就需要使用
jGroups+bloomFilter+rocksdb方式實現。實現如下:- 新的時間線過來本地判斷。如果本地判斷為新時間線,則發送至jGroup集群,通知所有節點,接收到消息的節點則經過判斷本地是否存在之后則保存至bloomFilter和rocksdb。
- 所有的節點同時也需要記錄下每天更新了數據已存在時間線,然后定時通知其他節點,保證所有節點的時間線的時間每天都有更新
- 前端每天定時發起清理時間線請求,收到請求的機器則清理本地時間線和hbase時間線,通知其他節點清理時間線,重建bloomFilter。
- 缺點:所有節點都要相互通知,io請求比較多。每個節點都保存最全的數據,有可能會出現不一致情況。每天ttl清理時間線,重建bloomFilter期間,數據判斷可能出現問題。