Reference:
- http://xumingming.sinaapp.com/736/twitter-storm-transactional-topolgoy/
- http://xumingming.sinaapp.com/811/twitter-storm-code-analysis-coordinated-bolt/
Example code:
Packagecom.lky.topology;ImportJava.math.BigInteger;Importjava.util.ArrayList;ImportJava.util.HashMap;Importjava.util.List;ImportJava.util.Map;ImportOrg.apache.commons.logging.Log;Importorg.apache.commons.logging.LogFactory;Importorg.junit.Test;ImportCom.lky.util.FileUtil;ImportCom.lky.util.RunStorm;ImportBacktype.storm.Config;ImportBacktype.storm.coordination.BatchOutputCollector;ImportBacktype.storm.task.TopologyContext;Importbacktype.storm.testing.MemoryTransactionalSpout;ImportBacktype.storm.topology.OutputFieldsDeclarer;ImportBacktype.storm.topology.base.BaseBatchBolt;ImportBacktype.storm.topology.base.BaseTransactionalBolt;ImportBacktype.storm.transactional.ICommitter;Importbacktype.storm.transactional.TransactionAttempt;ImportBacktype.storm.transactional.TransactionalTopologyBuilder;ImportBacktype.storm.tuple.Fields;Importbacktype.storm.tuple.Tuple;Importbacktype.storm.tuple.Values; @SuppressWarnings ({"Deprecation", "Serial", "Rawtypes" })/*** @Title: Transactionalglobalcount.java * @Package com.lky.topology * @Description: Transaction topology (number of simulated real-time statistics messages) * @authorlky * @date October 25, 2015 Morning 11:23:12 *@versionV1.0*/ Public classTransactionalglobalcount {Private StaticLog Log=logfactory.getlog (Transactionalglobalcount.class); Public Static Final intPartition_take_per_batch = 3; Public Static FinalMap<integer, list<list<object>>> DATA =NewHashmap<integer, list<list<object>>>() {{put (0,NewArraylist<list<object>>() {{Add (NewValues ("Cat")); Add (NewValues ("Dog")); Add (NewValues ("Chicken")); Add (NewValues ("Cat")); Add (NewValues ("Dog")); Add (NewValues ("Apple")); } }); Put (1,NewArraylist<list<object>>() {{Add (NewValues ("Cat")); Add (NewValues ("Dog")); Add (NewValues ("Apple")); Add (NewValues ("Banana")); } }); Put (2,NewArraylist<list<object>>() {{Add (NewValues ("Cat")); Add (NewValues ("Cat")); Add (NewValues ("Cat")); Add (NewValues ("Cat")); Add (NewValues ("Cat")); Add (NewValues ("Dog")); Add (NewValues ("Dog")); Add (NewValues ("Dog")); Add (NewValues ("Dog")); } }); } }; Public Static classValue {intCount = 0; BigInteger Txid; } Public Staticmap<string, value> DATABASE =NewHashmap<string, value>(); Public Static FinalString Global_count_key = "Global-count"; /*** @Title: Transactionalglobalcount.java * @Package com.lky.topology * @Description: Processing stage (can be processed in parallel) * @authorlky * @date October 25, 2015 PM 12:14:26 *@versionV1.0*/ Public Static classBatchcountextendsBasebatchbolt {batchoutputcollector collector; Object ID; Integer _count= 0; @Override Public voidPrepare (Map conf, topologycontext context, Batchoutputcollector Collector, Object ID) { This. Collector =collector; This. ID =ID; } @Override Public voidExecute (tuple tuple) {_count++; Log.info ("-------------->" +_count); } @Override Public voidFinishbatch () {Log.info ("--------" +_count+ "----------"); Collector.emit (NewValues (ID, _count)); } @Override Public voiddeclareoutputfields (Outputfieldsdeclarer declarer) {Declarer.declare (NewFields ("id", "Count")); } } /*** @Title: Transactionalglobalcount.java * @Package com.lky.topology * @Description: Committer rollup phase (strong sequential flow) * @authorlky * @date October 25, 2015 PM 12:14:54 *@versionV1.0*/ Public Static classUpdateglobalcountextendsBasetransactionalboltImplementsIcommitter {batchoutputcollector collector; Transactionattempt ID; Integer _size= 0; @Override Public voidPrepare (Map conf, topologycontext context, Batchoutputcollector Collector, Transactionattempt ID) { This. Collector =collector; This. ID =ID; } @Override Public voidExecute (tuple tuple) {Integer sum= Tuple.getinteger (1); Log.info ("Sum---------->" +sum); if(Sum > 0) {_size+=sum; }} @Override Public voidFinishbatch () {Value OldValue=Database.get (Global_count_key); Value NewValue; //If there is no storage, or there is a new transaction arriving, the update if(NULL= = OldValue | | !oldValue.txid.equals (Id.gettransactionid ())) {NewValue=NewValue (); Newvalue.txid=Id.gettransactionid (); if(NULL==oldValue) {Newvalue.count=_size; } Else{Newvalue.count= _size +Oldvalue.count; Collector.emit (NewValues (ID, newvalue.count)); Fileutil.strtofile (Integer.valueof (Newvalue.count). toString (),"Sum.txt",true); } database.put (Global_count_key, newvalue); } Else{newvalue=OldValue; }} @Override Public voiddeclareoutputfields (Outputfieldsdeclarer declarer) {Declarer.declare (NewFields ("id", "size")); }} @Test Public voidTest () {memorytransactionalspout spout=NewMemorytransactionalspout (DATA,NewFields ("word"), Partition_take_per_batch); Transactionaltopologybuilder Builder=NewTransactionaltopologybuilder ("Global-count", "spout", spout, 3); Builder.setbolt ("Partial-count",NewBatchcount (), 5). nonegrouping ("spout"); Builder.setbolt ("Sum",NewUpdateglobalcount ()). Globalgrouping ("Partial-count"); Config config=NewConfig (); Config.setdebug (true); Config.setmaxspoutpending (3); Runstorm.runstormlocally (Builder.buildtopology (),"ss", config, 5); }}
Storm Advanced Primitives-transactional topology