Windows環境下大數據處理的構想(一)

来源:https://www.cnblogs.com/zkfc/archive/2019/09/26/11593688.html
-Advertisement-
Play Games

為什麼不呢?我們有了RPC/RMI和MAP,為什麼不能在windows環境下處理大數據呢?windows是迄今為止最普及的操作系統,據市調公司NetMarketShare最新(2019年5月)統計數據,在桌面操作系統方面,目前Windows 10的市場占有率已達45.73%。而Windows 7的市 ...


為什麼不呢?我們有了RPC/RMI和MAP,為什麼不能在windows環境下處理大數據呢?windows是迄今為止最普及的操作系統,據市調公司NetMarketShare最新(2019年5月)統計數據,在桌面操作系統方面,目前Windows 10的市場占有率已達45.73%。而Windows 7的市場占有率為35.44%。排在第三位的是Windows 8.1,市場份額為3.97%。這三個版本的windows市場占有率之和為:85.14%。可以說windows占據了絕大多數用戶的心。這與windows界面友好統一、易操作、功能豐富、軟硬體相容性都高密不可分。我們或絕大多數人(目前非公司)在Windows上產生的數據要遠遠多於在Linux上產生的數據,如果能直接在Windows處理這些數據,那就太方便太好了。
 既然Windows這麼普及,又這麼方便實用,而且個人在Windows上產生的數據又那麼多(如果在Windows上能直接處理大數據的話,以後Windows伺服器的數量肯定會超過Linux伺服器),那為什麼從大數據處理技術誕生之日起都是基於Linux的,從最早的hadoop到國人主導的kylin再到較新的flink,莫不如是?這要從Linux和Windows的文件系統和目錄結構說起,Linux操作系統中有一個重要的概念:一切皆文件。Linux將獨立的文件系統組合成了一個層次化的樹形結構,並且由一個統一的、虛擬的根目錄代表整個文件系統。Linux將新的文件系統通過一個稱為“掛裝”或“掛上”的操作將其掛裝到根目錄的某個子目錄上,從而讓不同的文件系統結合成為一個“整體”。這個“整體”即Linux文件系統,實際上是每個實際文件系統從操作系統和系統服務中分離出來,通過一個介面層:虛擬文件系統或VFS來通訊。虛擬文件系統既沒有文件,也不直接管理文件,它只是用戶與實際文件系統之間的介面。我們操作的Linux目錄或文件被虛擬文件系統映射到真實的磁碟存儲區域。VFS使得Linux可以支持多個不同的文件系統,每個表示一個VFS的通用介面。Linux支持的文件系統包括: FAT、VFAT、FAT32、MINIX 等不同類型的文件系統,但ExtN才是Linux的“原配”文件系統。由於軟體將Linux文件系統的所有細節進行了轉換,所以Linux核心的其它部分及系統中運行的程式將看到統一的文件系統。Linux的虛擬文件系統允許用戶同時能透明地安裝許多不同的文件系統,而不需要具體地加以區別,即用戶和進程不需要知道文件所在的文件系統類型,而只需要像使用ExtN文件系統中的文件一樣使用它們。這一點正是Windows所不具備的。
 Windows採用地是多根目錄文件系統,即一棵獨立或多棵併列(根據磁碟分區的多少,一個分區對應一棵目錄樹)的樹形結構;而Linux採用地是統一根目錄結構,只有一棵巨大的樹結構。如果用Windows作為伺服器來處理大數據,每台伺服器的磁碟分區數根據自身磁碟容量、使用者分區習慣大概率不相同,導致盤符參差不齊。數據就有可能在這台伺服器存儲在D盤,在另一臺存儲在E盤等等,很難統一管理。而Linux就不存在這樣的問題,因為它的文件系統利用VFS屏蔽了分區細節,可以在每台Linux伺服器上根目錄下或根目錄的某個子目錄下建立一致的數據存儲目錄。但我們的命題就是要在Windows上處理大數據,如何解決Windows數據統一存儲管理問題呢?暫時想到兩個辦法:一是約定俗成,約定同一個集群的Windows伺服器分區數相同,盤符相同,或至少都有某一個分區,數據存放在該分區;二是由客戶端向集群提交任務時,附帶提交一個數據存儲地址/目錄表,表裡記錄得是待處理分析的數據具體在某台伺服器或節點上的某個具體位置,比如說:某節點:port/某分區/某目錄/某文件.xxx(如果整個目錄都是,就不需要具體到文件),這樣就可以將數據存儲到具體伺服器不同的盤符下。第二種方法靈活,易於在現實中的機器上搭建集群,但麻煩,需要占用額外的存儲,可以用Map等集合類對象存儲,至於具體怎樣實現,等到“構想”完集群、模擬提交任務時再說。
 大數據,故名思義,數據量很大,單結點(主機)的存儲容量有限,需要多結點、分散式地存儲。而且任一個節點的數據量也往往遠遠大於要分析處理數據的應用代碼量,所以計算向數據移動,可以大大減少IO(包括磁碟IO和網路IO),從時間上和空間上降低成本。無論是將代碼發往數據節點,還是shuffle階段從map端向reduce端拉取數據,都需要數據遷移。而數據遷移就要用到RPC(Remote Procedure Call)——遠程過程調用,在百度百科中是這樣解釋的:它是一種通過網路從遠程電腦程式上請求服務,而不需要瞭解底層網路技術的協議。RPC協議假定某些傳輸協議的存在,如TCP或UDP,為通信程式之間攜帶信息數據。在OSI網路通信模型中,RPC跨越了傳輸層和應用層。RPC使得開發包括網路分散式多程式在內的應用程式更加容易。RPC採用客戶機/伺服器模式。請求程式就是一個客戶機,而服務提供程式就是一個伺服器。首先,客戶機調用進程發送一個有進程參數的調用信息到服務進程,然後等待應答信息。在伺服器端,進程保持睡眠狀態直到調用信息到達為止。當一個調用信息到達,伺服器獲得進程參數,計算結果,發送答覆信息,然後等待下一個調用信息,最後,客戶端調用進程接收答覆信息,獲得進程結果,然後調用執行繼續進行。有多種 RPC模式和執行。最初由 Sun 公司提出。IETF ONC 憲章重新修訂了 Sun 版本,使得 ONC RPC 協議成為 IETF 標準協議。現在使用最普遍的模式和執行是開放式軟體基礎的分散式計算環境(DCE)。DCE也是大數據框架執行的基礎。在Java中叫RMI。無論hadoop還是spark底層都是先搭建一個RPC框架,各個角色對象在此基礎上進行通信和數據傳輸。
 有了RPC/RMI,我們就可以在Windows伺服器間傳輸各種數據包括代碼數據和待分析處理數據了。當然還有很多問題需要解決,等遇到時再說。我們先從最簡單的說起,RPC/RMI可以在Windows下輕而易舉地編程、實現、應用。舉例如下,wordCount在本地是這樣實現的:
public class StringValueMemStore  implements  Serializable {

 /**
  * xxxxx
  */
 private static final long serialVersionUID = -4505251514307025804L;
 ......(省略)
 /**
  * 重點是下麵這個方法
  */
 public  static  Map<String, Integer>  wordCount(String  filePath, String  separator) {
  Map<String, Integer>  map = new  HashMap<>();
  int  one = 1;
  int  val;
  
  Path  path = Paths.get(filePath);
  
  if (Files.notExists(path)) {
   System.err.println(path + " dose not exist.");
            return  null;
  }
  
  if (Files.isDirectory(path)) {
   System.err.println(path + " is not a file.");
   return  null;
  }
  
  Reader  fin = null;
  BufferedReader  in = null;
  try {
   fin = Files.newBufferedReader(path, Charset.forName("UTF-8"));
   in = new  BufferedReader(fin);
   String  line;
   
   while((line = in.readLine()) != null) {
    for (String  key : line.split(separator)) {
     if(map.get(key) == null) {
      map.put(key, one);
     } else {
      val = map.get(key) + 1;
      map2.put(key, val);
     }
    }
   }
  } catch (IOException e) {
   e.printStackTrace();
   return  null;
  } finally {
   try {
    if(fin != null) {
     fin.close();
    }
    if(in != null) {
     in.close();
    }
   } catch (IOException e) {
    e.printStackTrace();
   }
  }
  
  return  map;
 }
}
調用如下:
Map<String, Integer>  map = StringValueMemStore.wordCount("./data/words.txt",
" ");
for(String  k : map.keySet()) {
 System.out.println(k + "\t" + map.get(k));
}
加上RMI實現最簡分散式是這樣實現的:
public interface WCService extends Remote {
 Map<String, Integer>  wordCount(String  filePath, String  separator) throws RemoteException;
}

public class WCServiceImpl extends UnicastRemoteObject implements WCService {

 /**
  *
  */
 private static final long serialVersionUID = 4478936029983919271L;

 protected WCServiceImpl() throws RemoteException {
 }

 @Override
 public Map<String, Integer> wordCount(String filePath, String separator)  throws RemoteException {
  Map<String, Integer>  map = new  HashMap<>();
  int  val;
  
  Path  path = Paths.get(filePath);
  
  if (Files.notExists(path)) {
   System.err.println(path + " dose not exist.");
            return  null;
  }
  
  if (Files.isDirectory(path)) {
   System.err.println(path + " is not a file.");
   return  null;
  }
  
  Reader  fin = null;
  BufferedReader  in = null;
  try {
   fin = Files.newBufferedReader(path, Charset.forName("UTF-8"));
   in = new  BufferedReader(fin);
   String  line;
   
   while((line = in.readLine()) != null) {
    for (String  key : line.split(separator)) {
     if(map.get(key) == null) {
      map.put(key, Constants.ONE);
     } else {
      val = map.get(key) + 1;
      map.put(key, val);
     }
    }
   }
  } catch (IOException e) {
   e.printStackTrace();
   return  null;
  } finally {
   try {
    if(fin != null) {
     fin.close();
    }
    if(in != null) {
     in.close();
    }
   } catch (IOException e) {
    e.printStackTrace();
   }
  }
  
  return  map;
 }

}

public class WCServer {

 public static void main(String[] args) throws RemoteException, MalformedURLException {
  // 註冊埠
 LocateRegistry.createRegistry(Constants.PORT);
/*
 Constants.WCCount_RMI = "rmi://某節點(這裡同伺服器節點):" + PORT + "/net.xxx.xxx.wordCount.xxx.WCServiceImpl";
*/
// 將服務對象綁定url
  Naming.rebind(Constants.WCCount_RMI, new  WCServiceImpl());
 }

}

public class WCClient {

 public static void main(String[] args) throws MalformedURLException, RemoteException, NotBoundException {
  // 在註冊的服務中根據url尋找服務
  WCService  wcService = (WCService) Naming.lookup(Constants.WCCount_RMI);
  Map<String, Integer> wordCount = wcService.wordCount("X:/xxx/words.txt", " ");
  for(String  k : wordCount.keySet()) {
   System.out.println(k + "\t" + wordCount.get(k));
  }
 }
}
當然這裡為了簡單起見,我們把代碼寫死了,在實際的大數據處理框架中處理邏輯是由用戶完成的。我們只需要提供介面,而且第一步先進行數據映射,即map階段,第二步才是聚合統計reduce/aggregate,中間還有shuffle,最開始還有split。這裡只是為了說明RMI在Windows中可以輕易、方便地使用。有了RMI,我們一開始的數據存儲和處理邏輯就可以分佈在分散式環境中了;有了RMI,我們的數據和處理邏輯就可以“自由”地在節點間“旅行”了。這構成了大數據處理框架的基礎。千里之行,始於足下。借鑒hadoop和spark,我們應該先搭建RPC環境。RMI使用起來太麻煩,而且功能有限,現實中的大數據框架從未真正使用過RMI,而是使用對它的封裝和改良,比如說Netty。下一節我們介紹Netty,並逐漸用Netty搭建起RPC環境。學識有限,描述錯誤、不周的地方,還望各位技術大佬批評指正。這一節主要論述了在windows環境下處理大數據的可能性。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Linux文件系統原理在所有的操作系統中文件都有文件名與數據,在Linux系統上文件系統分成兩個部分:用戶數據 (user data) 與元數據 (metadata)。用戶數據,即文件數據塊 (data block),數據塊是記錄文件真實內容的地方;而元數據則是文件的附加屬性,如文件大小、創建時間、 ...
  • 對於磁碟等各類存儲設備中所有的數據都以0和1的概念,但對於用戶來說,0和1是沒有任何意義的,這時候就需要一種類似於“翻譯”的機制存在於用戶和磁碟之間,Linux中採用的是文件系統+虛擬文件系統(Virtual File System,VFS)的解決方案 一、文件系統: 就是操作系統用於明確磁碟或分區 ...
  • [TOC] max_connections 允許最大連接數,預設100,最大16384。這個根據性能調節,如果3000連接就會導致mysql的資源不夠,那就給3000.因為再給多了,就會導致其它連接的資源被搶占。 建議: 根據需求來看,一般2核4G機器填寫1000,16核64G填寫5000。 測試運 ...
  • 物理設計:具體任務主要是確定資料庫在存儲設備上的存儲結構及存取方法, 因DBMS的不同還可能包括建立索引和聚集,以及物理塊大小、緩衝區個 數和大小、數據壓縮的選擇等。 ...
  • 一、String1.1 概述1.2 相關命令列表1.3 命令示例二、List2.1 概述:2.2 相關命令列表:2.3 命令示例:2.4 鏈表結構的小技巧:三、HashSet3.1 概述3.2 相關命令列表3.3 命令示例四、Set4.1 概述:4.2 相關命令列表:4.3 命令示例:4.4 應用範... ...
  • MySQL學習——查詢表裡的數據 摘要:本文主要學習了使用DQL語句查詢表裡數據的方法。 數據查詢 語法 說明 查詢全部和指定列 查詢所有成績,通配符“*”查詢所有欄位: 查詢姓名、課程、成績: 去重查詢 查詢所有課程名稱: 使用別名查詢 查詢姓名、課程、成績並顯示表頭為中文,使用別名時,as可省略 ...
  • 1.下載安裝包 鏈接:https://pan.baidu.com/s/1hP3cD9aTv8nvJfNwjXPdrQ 提取碼:xmsu 2.解壓安裝包 選擇.exe 文件然後 安裝 選擇自己要安裝的位置。 3.安裝完成之後 點擊剛纔解壓出來的另一個文件 選擇navicat.exe 打開 4.最後出現 ...
  • -- 今天 SELECT DATE_FORMAT(NOW(),'%Y-%m-%d 00:00:00') AS dayStart;SELECT DATE_FORMAT(NOW(),'%Y-%m-%d 23:59:59') AS dayEnd; -- 昨天SELECT DATE_FORMAT( DATE ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...