2013年2月26日 星期二

如何對Map 集合做sort

Java所提供的Map class並無提供任何排序(sort)的函式
所以必需自行撰寫,範例參考如下

   
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;


public class sortMap {
 public static void main(String[] args){
  
  Map<String, Integer> sortMap = new TreeMap<String, Integer>();
  sortMap.put("N1", 5);
  sortMap.put("N2", 3);
  sortMap.put("N3", 1);
  sortMap.put("N4", 2);
  sortMap.put("N5", 4);
  Collection<Integer> sortMapTmp = sortMap.values();
  
  System.out.println("--unsort Map--");
  printSortMap(sortMap);
  
  sortMap = sortMapByComparator(sortMap);
  
  System.out.println("--sorted Map--");
  printSortMap(sortMap);
 }
 
 private static Map<String, Integer> sortMapByComparator(Map<String, Integer> unsortMap){
  
  List<Entry<String, Integer>> list = new LinkedList<Entry<String, Integer>>(unsortMap.entrySet());
  
  // Sorting the list based on values
  Collections.sort(list, new Comparator<Entry<String, Integer>>()
  {
    public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2)
    {
      //若要由小排到大
      //如果 o1 > o2 => 回傳  1
      //     o1 = o2 => 回傳  0 
      //     o1 < o2 => 回傳 -1
      return o1.getValue().compareTo(o2.getValue());
    }
  });
  
  Map<String, Integer> sortedMap = new LinkedHashMap<String, Integer>();
  for (Entry<String, Integer> entry : list)
        {
            sortedMap.put(entry.getKey(), entry.getValue());
        }
  
  return sortedMap;
 }
 
 private static void printSortMap(Map<String, Integer> sortMap){
  
  for(Entry<String, Integer> entry : sortMap.entrySet()){
   System.out.println("Key : " + entry.getKey() + " Value : "+ entry.getValue());
  }
 }
}


[Reference]
http://stackoverflow.com/questions/1448369/how-to-sort-a-treemap-based-on-its-values

2013年2月25日 星期一

Dimensions expected after this token

在宣告 Map 物件時, 需注意內部的<key, value>宣告用法
裡頭不得為常用的 int , 而必須是 Integer

否則會出現"Syntax error on token "int", Dimensions expected after this token "

Example:
(X) Map<String, int> list_test = new TreeMap<String, int>();
(O) Map<String, Integer> list_test = new TreeMap<String, Integer>();

2012年11月26日 星期一

TaskTracker send heartbeat cases

 可以看到TaskTracker中對於 heartbeat傳送時機有兩種


TaskTracker.java
...
private long getHeartbeatInterval(int numFinishedTasks) {
    return (heartbeatInterval / (numFinishedTasks * oobHeartbeatDamper + 1));
  }

...

heartbeatInterval預設是 HEARTBEAT_INTERVAL_MIN 為 3*1000 ms = 3sec
numFinishedTasks是此TaskTracker目前完成的Task數量
oobHeartbeatDamper是預設1000,000

也就是說getHeartbeatInterval(int numFinishedTasks)回傳的值是:
1. 當TaskTracker尚未完成任何task >>> 3000/(0*1000,000+1) = 3000ms = 3sec
    即3sec才傳一次heartbeat

2. 當TaskTracker完成一個以上task時 >>> 3000/(1*1000,000+1) = 0.00299 = 0sec
    即馬上傳一次heartbeat告知JobTracker有task完成

2012年11月12日 星期一

Ubuntu 網路速度限制

當需要去限制Ubuntu的網路其 上傳/下載 的速度時
可透過 Wondershaper 這個工具


安裝:
  sudo apt-get install wondershaper

使用:
  sudo wondershaper  [link type]   [download speed(kbps)]  [upload speed(kbps)]
  ex:
    sudo wondershaper eth0 512 64

    這樣 eth0的網路連線  下載速度上限就為512Kbps  上傳速度上限為 64 Kbps


[Reference]
Wondershaper流量監控工具
[分享] 在面板顯示上傳下載流量 [論壇 - Ubuntu基本設定]

2012年10月31日 星期三

java.lang.NullPointerException 問題

在開發大型程式時, 經常會用到物件導向的概念,
但有時會不小心忘了使用到一個"尚未存在的物件",  存取使用其物件所屬類別的函式,
就會造成
java.lang.NullPointerException 的問題

ex:
...
Job job;
job.setconf(); //setconf() 為Job class中的一個函式
...

就會有問題
因為實際上 Job job; 只是宣告了一個是宣告了一個Job type的變數

應該要宣告出一個實際的物件, 才能去使用其函式

...
Job job = new Job();
job.setconf();
...


[Note] 所以當發生java.lang.NullPointerException此問題時, 可以去檢查一下是否有物件尚未被new出來

2012年9月30日 星期日

Reduce Task assign 時機

在Hadoop中, Reduce task 並非等到所有 Map task 做完才被assign下去做,
預設:

JobInProgress.java
...
public synchronized Task obtainNewReduceTask(TaskTrackerStatus tts, int clusterSize,
int numUniqueHosts) throws IOException {
...
if (!scheduleReduces()) {
      return null;
    }
...
}
...
public synchronized boolean scheduleReduces() {
    return finishedMapTasks >= completedMapsForReduceSlowstart;
  }

completedMapsForReduceSlowstart
=(預設DEFAULT_COMPLETED_MAPS_PERCENT_FOR_REDUCE_SLOWSTART)*numMapTasks
= 0.05*這個job的map task 數量

目的:Ensure we have sufficient map outputs ready to shuffle before scheduling reduces

...............................................................................................................
舉例來說, 假設此Job有 40 map tasks, 1 reduce task
則此Job的completedMapsForReduceSlowstart = 0.05*40=2

及表示這個Job至少必須完成 2 個map tasks, 才可以assign reduce task

2012年6月18日 星期一

task complete percent

在執行hadoop job時, 可以從管理的網頁觀察到 job 運行的狀態,
亦可觀察到job中的 task 運作的情況,
如下圖
好奇的是, 每個 task 的"Complete"的%數是怎麼來的

簡單去查看了一下jobtasks.jsp source code,
發現他是用到 Hadoop API 中的 TaskReports 這個class裡面的 getProgress()

getProgress() 是以 0~1 表現task完成度
所以 jobtasks.jsp 中在

--------
...
for (int i = start_index ; i < end_index; i++) {
          TaskReport report = reports[i];
          out.print("<tr><td><a href=\"taskdetails.jsp?tipid=" +
            report.getTaskID() + "\">"  + report.getTaskID() + "</a></td>");
         out.print("<td>" + StringUtils.formatPercent(report.getProgress(),2) +
                   ServletUtil.percentageGraph(report.getProgress() * 100f, 80) + "</td>");
...
----------

乘上100來便於觀測完成的%數