首先要搞清楚的問題是:Flume中的事務用來幹嘛?
Flume中的事務用來保證訊息的可靠傳遞。
當使用繼承自BasicChannelSemantics的Channel時,Flume強制在操作Channel時採用特定的程式結構,並且強制channel實現特定的方法以使得Channel本身可以應對存入或取出失敗的情況,並且使得channel的使用者有可能根據操作是否成功採取適當的方法。
Channel在Flume的架構中主要起了快取的作用,當使用FileChannel時,它是一個持久化的快取。
若把Channel類比為資料庫,而把Flume的事務類比為資料庫事務,那麼Flume通過事務來確保Source和Sink採用特定的方式訪問Channel,從而保證Channel狀態的一致性。比如當一個事務中需要把一個batch的event全放入Channel時,需要確保這個操作是原子的,要不全放進去,要不一個不放。
更高層次、更廣範圍的事務可以以此為基礎構建。
下面是Transaction註釋中對Transaction使用的舉例:
org.apache.flume.TransactionProvides the transaction boundary while accessing a channel
A Transaction instance is used to encompass channel access via the following idiom:
Channel ch = ... Transaction tx = ch.getTransaction(); try { tx.begin(); ... // ch.put(event) or ch.take() ... tx.commit(); } catch (ChannelException ex) { tx.rollback(); ... } finally { tx.close(); }
Depending upon the implementation of the channel, the transaction semantics may be strong, or best-effort only.
Transactions must be thread safe. To provide a guarantee of thread safe access to Transactions, see
BasicChannelSemantics
andBasicTransactionSemantics
.
可實現這個的事務語法,需要幾個類的合作, 需要這些類有特定的語法。包括Channel的語法和從Channel中獲取的Transaction物件的語法。
下面是事務有關的各個類
其中AbstractChannel主要實現了NamedComponent、LifecycleAware和Configurable這幾個基本的介面,和事務無關。
BasicChannelSemantics實現在在local-thread中儲存一個BasicTransactionSemantics物件的功能。它對Channel介面中take和put方法的實現為:確保當前的執行緒中有Transaction的一個可用的例項,然後把take和put代理給本執行緒transaction物件的同名方法。
BasicTransactionSemantics確保了事務相關的操作只有按正確的順序執行才可以。即tx.begin =》 channel.take/put =》 tx.commit =》 tx.close。它只保證了對Channel操作的順序,由子類實現doBegin, doTake, doPut, doCommit, doRollback, doClose等方法。
因此BasicChannelSemantic類和BasicTransactionSemantics類一起保證了操作Channel的邏,。提供了所有Channel的父類。事務中的各個操作的語義,則由BasicTransactionSemantics的子類去實現,即它的子類來說明事務開始時幹嘛,事務回滾時幹嘛,取出訊息時幹嘛、放入訊息時幹嘛等等。(可以類比下模版方法模式,不過這裡父類通過特殊的手段強制了方法的呼叫順序)