Working on a system to support multiple database queries in parallel. Considering there is a lot of data to query from each, the requirement is to keep each database query separated from others. Meaning, load on one database/table should not have impact on other Table queries. I developed a solution in Java using ExecutorService. Using one ExecutorService(Fixed size with 1 Thread) per Database. I maintain a map of DB name TO ExecutorService and direct the calls to respective executor service on receiving query requests. Considering there can be one hundred databases being queried in parallel, not sure if ExecutorService is the right choice...! I have done some valuation and initial results look okay. One challenge I have with this solution is, as I am creating ExecutorServices dynamically, it's getting tough for me to shutdown them gracefully when application stops.
Other ways to tackle this problem is to maintain a global(meaning, across all Databases) pool of query worker threads, and reuse them in random for incoming requests. But, this will not guarantee all Database queries are given equal priority.
DatasetFactory.java
public class DataSetExecutorFactory {
private static Map<String, DataSetExecutor> executorMap = Collections.synchronizedMap(new HashMap<String, DataSetExecutor>());
public static DataSetExecutor getDataSetExecutor(String dbName){
DataSetExecutor executor = null;
executor = executorMap.get(dbName);
if(executor == null){
executor = new DataSetExecutor(dbName);
executorMap.put(dbName, executor);
}
return executor;
}
}
}
DataSetExecutor.java
public class DataSetExecutor {
private ExecutorService executor = Executors.newFixedThreadPool(1);
public List<Map<String, Object>> execQuery(String collecName, Map<String, Object> queryParams){
//Construct Query job.
//QueryWorker extends 'Callable' and does the actual query to DB
QueryWorker queryWorker = new QueryWorker(Map queryParams);
Future<QueryResult> result = null;
try{
result = executor.submit(queryWorker);
}catch (Exception e){
//Catch Exception here
e.printStackTrace();
}
}
parallelif you are pushing all onto a single thread executor service.