After the pit of the sync problem (Storm pit---sync problem), the code has recently been tweaked and refactored, and another hole that should be vigilant in storm development has been encountered. Let's talk about the general situation of the pit.
In my storm program, Abolt needs to encapsulate the data into one object and send it to Bbolt and Cbolt each, Bbolt and Cbolt to the database after processing the object. When I looked at the log, I accidentally found some data was not correct, I first doubted the algorithm, but found that some of the data is correct. The algorithm should have no problem. After the tangle print a more detailed log, by observing the rules of the strange data finally dawned: it must be Bbolt received the object after the modification of the impact on the Cbolt. Here I am almost certain: when Bbolt and Cbolt are running in the same process. They are common to the objects sent to Bbolt and Cbolt. Bbolt changes can affect Cbolt and vice versa. If Bbolt and Cbolt are not the same process, there is no such effect. This explains why some of the data is normal and abnormal.
Here's an example code to test:
Topology Building class:
public class Main {public static void main (string[] args) {Topologybuilder builder = new Topologybuilder (); Builder.setspou T ("Test", New Testwordspout ()), Builder.setbolt ("Print1", New Printbolt ("PRINTBOLT1")). Shufflegrouping ("test"); Builder.setbolt ("Print2", New Printbolt ("PRINTBOLT2")). Shufflegrouping ("test"); Config conf = new config (); Conf.setdebug (false); Conf.setnumworkers (1); Localcluster cluster = new Localcluster () cluster.submittopology ("Test-kafka-1", conf, Builder.createtopology ());}}
Spout class:
public class Testwordspout extends Baserichspout { private static final long serialversionuid = 1L; Spoutoutputcollector _collector; public void Open (Map conf, topologycontext context, Spoutoutputcollector collector) { _collector = collector; } Public void Close () { } public void Nexttuple () { utils.sleep ( +); Name name = new name (); Name.setname ("123"); _collector.emit (new Values name); } public void Declareoutputfields (Outputfieldsdeclarer declarer) { Declarer.declare (new fields ("word"));} }
Bolt class:
public class Printbolt extends Baserichbolt {private static final long Serialversionuid = 1l;private String name;int Taski D;public Printbolt (String name) {this.name = name;} @Overridepublic void Prepare (Map stormconf, Topologycontext context,outputcollector collector) {This.taskid = Context.getthistaskid ();} @Overridepublic void Execute (Tuple input) {name name = (name) Input.getvaluebyfield ("word"); System.out.println (Logprefix () +name.getname ()); Name.setname (this.name);} Private String Logprefix () {return this.name+ ":";} @Overridepublic void Declareoutputfields (Outputfieldsdeclarer declarer) {}}
Possible results of the execution:
PRINTBOLT2:123PRINTBOLT1:123PRINTBOLT2:123PRINTBOLT1:123PRINTBOLT2:123PRINTBOLT1:123PRINTBOLT2: Printbolt1printbolt2:123printbolt1:123printbolt1:123printbolt2:123printbolt1:123printbolt2:123
As you can see from the top results, PRINTBOLT2 prints the PRINTBOLT1 changes.
With this in mind, you'll need to take this into account when writing code. If an object is sent to two bolts at the same time, the cut Bolt will have to modify the object, and make sure to clone a copy before making any changes, instead of modifying it directly!
---of storm pits objects