forked from ldsimonassi/Storm-Search-Engine
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
modified shard to container, added simple-search
- Loading branch information
1 parent
c3f8090
commit 20e6dcf
Showing
8 changed files
with
277 additions
and
39 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package simplesearch; | ||
|
||
import java.util.List; | ||
import java.util.Map; | ||
|
||
import org.json.simple.JSONArray; | ||
import org.json.simple.JSONObject; | ||
import org.json.simple.JSONValue; | ||
|
||
import search.model.Item; | ||
import search.utils.SerializationUtils; | ||
import storm.utils.AbstractAnswerBolt; | ||
import backtype.storm.task.OutputCollector; | ||
import backtype.storm.task.TopologyContext; | ||
import backtype.storm.tuple.Tuple; | ||
|
||
public class AnswerQueryBolt extends AbstractAnswerBolt { | ||
private static final long serialVersionUID = 1L; | ||
SerializationUtils su; | ||
|
||
@SuppressWarnings("rawtypes") | ||
@Override | ||
public void prepare(Map stormConf, TopologyContext context, | ||
OutputCollector collector) { | ||
super.prepare(stormConf, context, collector); | ||
this.su= new SerializationUtils(); | ||
} | ||
|
||
@Override | ||
@SuppressWarnings("unchecked") | ||
public void execute(Tuple input) { | ||
String origin= input.getString(0); | ||
String requestId= input.getString(1); | ||
List<Item> finalResult= su.fromByteArray(input.getBinary(2)); | ||
|
||
JSONArray list = new JSONArray(); | ||
for (Item item : finalResult) { | ||
JSONObject obj= new JSONObject(); | ||
obj.put("title", item.title); | ||
obj.put("id", item.id); | ||
obj.put("price", item.price); | ||
list.add(obj); | ||
} | ||
String json= JSONValue.toJSONString(list); | ||
sendBack(origin, requestId, json); | ||
} | ||
|
||
@Override | ||
protected int getDestinationPort() { | ||
return 8082; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package simplesearch; | ||
|
||
import java.util.Map; | ||
|
||
import storm.utils.AbstractClientSpout; | ||
|
||
import backtype.storm.spout.SpoutOutputCollector; | ||
import backtype.storm.task.TopologyContext; | ||
|
||
public class QueriesSpout extends AbstractClientSpout { | ||
private static final long serialVersionUID = 1L; | ||
|
||
String queriesPullHost; | ||
int maxPull; | ||
|
||
@Override | ||
public void open(@SuppressWarnings("rawtypes") Map conf, TopologyContext context, | ||
SpoutOutputCollector collector) { | ||
this.queriesPullHost= (String) conf.get("queries-pull-host"); | ||
try{ | ||
this.maxPull= Integer.parseInt((String)conf.get("max-pull")); | ||
} catch(Exception ex){ | ||
this.maxPull= 1; | ||
} | ||
|
||
super.open(conf, context, collector); | ||
|
||
} | ||
|
||
@Override | ||
protected String getPullHost() { | ||
return queriesPullHost; | ||
} | ||
|
||
@Override | ||
protected int getMaxPull() { | ||
return maxPull; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
package simplesearch; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Collections; | ||
import java.util.Comparator; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
import org.apache.log4j.Logger; | ||
|
||
import search.model.Item; | ||
import search.model.ItemsContainer; | ||
import search.utils.SerializationUtils; | ||
import backtype.storm.task.OutputCollector; | ||
import backtype.storm.task.TopologyContext; | ||
import backtype.storm.topology.IRichBolt; | ||
import backtype.storm.topology.OutputFieldsDeclarer; | ||
import backtype.storm.tuple.Fields; | ||
import backtype.storm.tuple.Tuple; | ||
import backtype.storm.tuple.Values; | ||
|
||
public class SearchBolt implements IRichBolt { | ||
private static final long serialVersionUID = 1L; | ||
|
||
Logger log; | ||
OutputCollector collector; | ||
@SuppressWarnings("rawtypes") | ||
Map stormConf; | ||
TopologyContext context; | ||
int currentShard; | ||
int totalShards; | ||
int base_id; | ||
SerializationUtils su; | ||
ItemsContainer shard; | ||
|
||
|
||
|
||
@Override | ||
public void prepare(@SuppressWarnings("rawtypes") Map stormConf, | ||
TopologyContext context, | ||
OutputCollector collector) { | ||
log = Logger.getLogger(this.getClass()); | ||
this.stormConf= stormConf; | ||
this.context= context; | ||
this.collector= collector; | ||
su = new SerializationUtils(); | ||
shard = new ItemsContainer(10000); | ||
} | ||
|
||
private boolean isMine(int itemId) { | ||
int remain = itemId % totalShards; | ||
return remain == currentShard; | ||
} | ||
|
||
@Override | ||
public void execute(Tuple input) { | ||
if(input.getSourceComponent().equals("read-item-data")){ | ||
//String origin= input.getString(0); | ||
//String requestId= input.getString(1); | ||
int itemId= input.getInteger(2); | ||
if(isMine(itemId)){ | ||
log.debug("Mine! "+currentShard+"/"+totalShards); | ||
byte[] ba = input.getBinary(3); | ||
if(ba==null) { | ||
log.debug("Removing item id:"+itemId); | ||
shard.remove(itemId); | ||
} else { | ||
Item i= su.itemFromByteArray(ba); | ||
log.debug("Updating item index: "+i); | ||
shard.update(i); | ||
} | ||
} | ||
return ; | ||
} | ||
|
||
// Get request routing information | ||
String origin= input.getString(0); | ||
String requestId= input.getString(1); | ||
String query= input.getString(2); | ||
|
||
|
||
// Execute query with local data scope | ||
List<Item> results= executeLocalQuery(query, 5); | ||
log.debug("Searching ["+ query +"] in shard "+currentShard +" "+results.size()+" results found"); | ||
// Send data to next step: Merger | ||
collector.emit(new Values(origin, requestId, query, su.toByteArray(results))); | ||
} | ||
|
||
private List<Item> executeLocalQuery(String query, int quantity) { | ||
List<Item> items= new ArrayList<Item>(shard.getItemsContainingWords(query)); | ||
|
||
Collections.sort(items, new Comparator<Item>() { | ||
@Override | ||
public int compare(Item o1, Item o2) { | ||
double diff= o1.price-o2.price; | ||
if(diff>0) | ||
return 1; | ||
else | ||
return -1; | ||
} | ||
}); | ||
|
||
if(items.size()>quantity) | ||
items = items.subList(0, quantity-1); | ||
return items; | ||
} | ||
|
||
@Override | ||
public void cleanup() { | ||
} | ||
|
||
@Override | ||
public void declareOutputFields(OutputFieldsDeclarer declarer) { | ||
declarer.declare(new Fields("origin", "requestId", "query", "shardMatches")); | ||
} | ||
|
||
|
||
|
||
|
||
} |
45 changes: 45 additions & 0 deletions
45
src/main/java/simplesearch/SimpleSearchEngineTopologyStarter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package simplesearch; | ||
|
||
import backtype.storm.Config; | ||
import backtype.storm.StormSubmitter; | ||
import backtype.storm.generated.StormTopology; | ||
import backtype.storm.topology.TopologyBuilder; | ||
import backtype.storm.tuple.Fields; | ||
|
||
public class SimpleSearchEngineTopologyStarter { | ||
public static StormTopology createTopology() { | ||
TopologyBuilder builder= new TopologyBuilder(); | ||
|
||
builder.setSpout("queries-spout", new QueriesSpout(), 1); | ||
builder.setBolt("queries-processor", new SearchBolt(), 1).allGrouping("queries-spout"); | ||
builder.setBolt("answer-query", new AnswerQueryBolt(), 2).allGrouping("queries-processor"); | ||
return builder.createTopology(); | ||
} | ||
|
||
public static Config createConf(String queriesPullHost, String feedPullHost, String itemsApiHost, int maxPull) { | ||
// Custom configuration | ||
Config conf= new Config(); | ||
conf.put("queries-pull-host", queriesPullHost); | ||
conf.put("items-api-host", itemsApiHost); | ||
conf.put("max-pull", "100"); | ||
// Disable ackers mechanismo for this topology which doesn't need to be safe. | ||
conf.put(Config.TOPOLOGY_ACKERS, 0); | ||
return conf; | ||
} | ||
|
||
public static void main(String[] args) { | ||
if(args.length < 5) { | ||
System.err.println("Incorrect parameters. Use: <name> <queries-pull-host> <feed-pull-host> <items-api-host> <max-pulling>"); | ||
System.exit(-1); | ||
} | ||
|
||
System.out.println("Topology Name ["+args[0]+"]"); | ||
try { | ||
Config conf= createConf(args[1], args[2], args[3], Integer.valueOf(args[4])); | ||
conf.setNumWorkers(20); | ||
StormSubmitter.submitTopology(args[0], conf, createTopology()); | ||
} catch (Exception e) { | ||
e.printStackTrace(); | ||
} | ||
} | ||
} |
Oops, something went wrong.