Adding config file for sharing.
[iot2.git] / iotjava / iotruntime / master / LoadBalancer.java
1 package iotruntime.master;
2
3 import java.util.Collection;
4 import java.util.HashMap;
5 import java.util.Map;
6
7 import java.util.Arrays;
8
9 import iotinstaller.MySQLInterface;
10 import iotinstaller.TableProperty;
11 import iotinstaller.Table;
12
13 /** Class LoadBalancer is a class that derives information
14  *  about hosts (compute nodes) from the database and select
15  *  a certain host to do a computation at a certain situation
16  *  based on the metrics given to calculate the most load-balanced
17  *  job assignment
18  *
19  * @author      Rahmadi Trimananda <rahmadi.trimananda @ uci.edu>
20  * @version     1.0
21  * @since       2016-01-18
22  */
23 public final class LoadBalancer {
24
25         /**
26          * LoadBalancer class properties
27          * <p>
28          * Class properties to contain host information from table
29          * HOSTADDRESS is in the form of MAC address that gets translated
30          * through DHCP
31          * hmNumProcesses tracks the usage of a certain host/compute node
32          * hmLoadScore tracks the score of the load for each host;
33          * host selection for the next process is based on these scores
34          * +----------------------+-----------+--------+------------+
35          * | HOSTADDRESS          | PROCESSOR | MEMORY | #PROCESSES |
36          * +----------------------+-----------+--------+------------+
37          * | XX:XX:XX:XX:XX:XX    |      3500 |     32 |          1 |
38          * | XX:XX:XX:XX:XX:XX    |      3500 |     32 |          4 |
39          * | ...                  |      ...  |    ... |        ... |
40          * | ...                  |      ...  |    ... |        ... |
41          * +----------------------+-----------+--------+------------+
42          */
43         private HashMap<String, Integer> hmHostAddress;
44         private int[] arrProcessor;
45         private int[] arrMemory;
46         private int[] arrNumProcesses;
47         private int[] arrLoadScore;
48         private Table tbl;
49         private boolean bVerbose;
50
51         /**
52          * LoadBalancer class constants
53          */
54     private static final String STR_TABLE_COMPUTE_NODE = "IoTComputeNode";
55
56         /**
57          * Class constructor
58          */
59         public LoadBalancer(boolean _bVerbose) {
60
61                 hmHostAddress = new HashMap<String, Integer>();
62                 arrProcessor = null;
63                 arrMemory = null;
64                 arrNumProcesses = null;
65                 arrLoadScore = null;
66                 tbl = new Table(STR_TABLE_COMPUTE_NODE, _bVerbose);
67                 bVerbose = _bVerbose;
68                 RuntimeOutput.print("LoadBalancer: Creating a load-balancer!", bVerbose);
69         }
70
71         /**
72          * setupLoadBalancer() method loads host information from DB
73          *
74          * @return  void
75          */
76         public void setupLoadBalancer() {
77
78                 String[][] arrTbl = tbl.getGeneralDBTable();
79                 arrProcessor = new int[arrTbl.length];
80                 arrMemory = new int[arrTbl.length];
81                 arrNumProcesses = new int[arrTbl.length];
82                 arrLoadScore = new int[arrTbl.length];
83
84                 for(int i=0; i<arrTbl.length; i++) {
85
86                         // Iterate per row from the DB table
87                         hmHostAddress.put((String) arrTbl[i][0], i);
88                         arrProcessor[i] = Integer.parseInt((String) arrTbl[i][1]);
89                         arrMemory[i] = Integer.parseInt((String) arrTbl[i][2]);
90
91                         // Initialize #process to 0 for all entries in the beginning
92                         // Initialize load score to maximum integer value
93                         arrNumProcesses[i] = 0;
94                         arrLoadScore[i] = Integer.MAX_VALUE;
95                 }
96                 RuntimeOutput.print("LoadBalancer: Initializing load balancer...", bVerbose);
97         }
98
99         /**
100          * selectHost() method selects a host based on the metrics
101          *
102          * @return  void
103          */
104         public String selectHost() {
105
106                 // Variable for highest score that we are going to select
107                 int iHighestScore = 0;
108
109                 //String strHostMACAddress = null;
110                 String strHostIPAddress = null;
111
112                 RuntimeOutput.print("LoadBalancer: Host address number: " + hmHostAddress.size(), bVerbose);
113
114                 // Get the first host address from the hashmap
115                 strHostIPAddress = (String) hmHostAddress.keySet().toArray()[0];
116                 for(Map.Entry<String, Integer> mapHost : hmHostAddress.entrySet()) {
117
118                         // Get the current entry load score
119                         int iEntryScore = arrLoadScore[mapHost.getValue()];
120
121                         // Compare highest score and entry score; select the highest
122                         if (iHighestScore < iEntryScore) {
123                                 iHighestScore = iEntryScore;
124                                 strHostIPAddress = mapHost.getKey();
125                         }
126                 }
127
128                 // Calculate the new score for this host and return the host address
129                 calculateHostScore(strHostIPAddress);
130                 RuntimeOutput.print("LoadBalancer: Selected host: " + strHostIPAddress, bVerbose);
131
132                 return strHostIPAddress;
133         }
134
135         /**
136          * calculateHostScore() calculates score for a host based on the metrics
137          * <p>
138          * It also stores the results back to the corresponding hashmaps
139          *
140          * @param   strHostAddress   String host address
141          * @return                   void
142          */
143         private void calculateHostScore(String strHostAddress) {
144
145                 // Get the previous values
146                 int iIndex = hmHostAddress.get(strHostAddress);
147                 int iPrevNumProcesses = arrNumProcesses[iIndex];
148
149                 // Calculate the current values
150                 // Every time we call this method, we increment #process by 1
151                 // (we add one new process)
152                 int iCurrNumProcesses = iPrevNumProcesses + 1;
153                 int iProcessor = arrProcessor[iIndex];
154                 int iMemory = arrMemory[iIndex];
155
156                 // We calculate the score simply with this formula
157                 // Score = (Processor/current #process) x (Memory/current #process)
158                 // The more processes a certain node has, the lower its score is.
159                 // Therefore, we always choose a node that has the highest score.
160                 // P.S. In this formula we also take the processor and memory specs
161                 // into account
162                 int iCurrScore = (iProcessor * iMemory) / iCurrNumProcesses;
163                 arrLoadScore[iIndex] = iCurrScore;
164                 arrNumProcesses[iIndex] = iCurrNumProcesses;
165                 RuntimeOutput.print("LoadBalancer: Calculate host load score for " + strHostAddress, bVerbose);
166         }
167
168         /**
169          * printHostInfo() method prints the host information at runtime
170          *
171          * @return  void
172          */
173         public void printHostInfo() {
174
175                 for(Map.Entry<String, Integer> mapHost : hmHostAddress.entrySet()) {
176
177                         RuntimeOutput.print("Host address        : " + mapHost.getKey(), bVerbose);
178                         RuntimeOutput.print("Processor           : " + arrProcessor[mapHost.getValue()], bVerbose);
179                         RuntimeOutput.print("Memory              : " + arrMemory[mapHost.getValue()], bVerbose);
180                         RuntimeOutput.print("Number of processes : " + arrNumProcesses[mapHost.getValue()], bVerbose);
181                         RuntimeOutput.print("Host score          : " + arrLoadScore[mapHost.getValue()], bVerbose);
182                 }
183         }
184
185         public static void main(String[] args) {
186
187                 LoadBalancer lb = new LoadBalancer(true);
188                 lb.setupLoadBalancer();
189                 System.out.println("Chosen host: " + lb.selectHost());
190                 System.out.println("Chosen host: " + lb.selectHost());
191                 System.out.println("Chosen host: " + lb.selectHost());
192                 System.out.println("Chosen host: " + lb.selectHost());
193                 System.out.println("Chosen host: " + lb.selectHost());
194                 System.out.println("Chosen host: " + lb.selectHost());
195                 System.out.println("Chosen host: " + lb.selectHost());
196                 System.out.println("Chosen host: " + lb.selectHost());
197                 lb.printHostInfo();
198         }
199 }