为什么不呢?我们有了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环境下处理大数据的可能性。

Windows环境下大数据处理的构想(一)的更多相关文章

  1. 【大数据系列】windows环境下搭建hadoop开发环境使用api进行基本操作

    前言 搭建完hadoop集群之后在windows环境下搭建java项目进行测试 操作hdfs中的文件 版本一 package com.slp.hadoop274.hdfs; import java.i ...

  2. 【经验之谈】Windows环境下配置WordPress

    前言 wordpress全球著名的开放博客平台,拥有成千上万个各式插件和不计其数的主题模板样式,使用php和mysql搭建,下面说下载windows环境下配置wordpress,经验之谈. 安装 关于 ...

  3. Windows环境下Android Studio v1.0安装教程

    Windows环境下Android Studio v1.0安装教程 准备工具 JDK安装包. 要求:JDK 7以及以上版本. Android Studio安装文件. Windows: exe(包含SD ...

  4. Windows环境下32位汇编语言程序设计(典藏版)

    Windows环境下32位汇编语言程序设计(典藏版)(含CD光盘1张)(年,经典再现!) 罗云彬 著 ISBN 978-7-121-20759-4 2013年7月出版 定价:99.00元 756页 1 ...

  5. Android笔记——Windows环境下Android Studio v1.0安装教程

    本文主要讲解Windows环境下Android Studio的安装教程,Mac的Android Studio安装与此类似不在赘述,另外友情提示Windows下的SDK与Mac的SDK是通用的,可以直接 ...

  6. Android 开发之Windows环境下Android Studio安装和使用教程(图文详细步骤)

    鉴于谷歌最新推出的Android Studio备受开发者的推崇,所以也跟着体验一下. 一.介绍Android Studio  Android Studio 是一个Android开发环境,基于Intel ...

  7. [原]我在Windows环境下的首个Libevent测试实例

    libevent对Windows环境也有很好的支持,不过初次学习和编译libevent简单实例,总是有一些陌生感的,只有成功编译并测试了一个实例,才会有恍然大悟的感觉.下面将要讲到的一个实例是我从网上 ...

  8. 【转】Windows环境下Android Studio v1.0安装教程

    原文网址:http://ask.android-studio.org/?/article/9 http://android-studio.org/index.php/docs/experience/1 ...

  9. PHP.6-PHP环境搭建(Windows环境下)-LAMP

    PHP环境搭建(Windows环境下)-LAMP Windows系统上分别独立安装Apache2.PHP5.MySQL5和phpMyAdmin等几个软件.独立安装的好处是可以自由选择这些组件的具体版本 ...

随机推荐

  1. Laravel 入门常见问题汇总

    一.安装完成后想打开 Laravel 内置的登录页面,报错 解决方法: Laravel 利用 PHP5.4 的新特性 trait 内置了非常完善好用的简单用户登录注册功能,适合一些不需要复杂用户权限管 ...

  2. 随便贴两个漏洞,如 Apache JServ协议服务

    1.Apache JServ协议服务 描述:Apache JServ协议(AJP)是一种二进制协议,可以将来自Web服务器的入站请求代理到 位于Web服务器后面的应用程序服务器.不建议在互联网上公开使 ...

  3. 012-Shell 提示确认(Y / N,YES / NO)

    例1:确认提示(一次) 这个示例代码将为确认提示一次,如果你给输入错误,程序会以状态1退出.这个例子将只接受Y或N或YES或NO(不区分大小写). #!/bin/bash read -r -p &qu ...

  4. WMS常用命令

  5. [LeetCode] 125. Valid Palindrome 验证回文字符串

    Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignori ...

  6. servlet 读取文件

    读取pdf protected void service(HttpServletRequest request, HttpServletResponse response) throws Servle ...

  7. 【转帖】MIPS构架:曾经是英特尔的“眼中钉”

    MIPS构架:曾经是英特尔的“眼中钉” https://www.eefocus.com/mcu-dsp/363953 <处理器史话>之十一 2016-06-17 08:02 作者:付丽华预 ...

  8. 一起来学Spring Cloud | 第七章:分布式配置中心(Spring Cloud Config)

    上一章节,我们讲解了服务网关zuul,本章节我们从git和本地两种存储配置信息的方式来讲解springcloud的分布式配置中心-Spring Cloud Config. 一.Spring Cloud ...

  9. Linux05 文件或目录的权限(ls、lsattr、chattr、chmod、chown、chgrp、file)

    一.查看文件或目录的权限:ls -al  文件名/目录名 keshengtao@LAPTOP-F9AFU4OK:~$ ls -al total drwxr-xr-x keshengtao keshen ...

  10. Qt 5.12 LTS 部署

    1. 拷贝release生成的exe到一个独立的目录deploy 2. windeployqt.exe A_Toolkit.exe 3. 将qt\qt5.12.5\tool\mingw730_64\b ...