rainit2006 / My_AWS-Cloud

0 stars 0 forks source link

EMR / Hive #9

Open rainit2006 opened 7 years ago

rainit2006 commented 7 years ago

image Hive依赖于HDFS存储数据,依赖MR处理数据; Pig可作为Hive的替代工具,是一种数据流语言和运行环境,适合用于在Hadoop平台上查询半结构化数据集,用于与ETL过程的一部分,即将外部数据装载到Hadoop集群中,转换为用户需要的数据格式; HBase是一个面向列的、分布式可伸缩的数据库,可提供数据的实时访问功能,而Hive只能处理静态数据,主要是BI报表数据,Hive的初衷是为减少复杂MR应用程序的编写工作,HBase则是为了实现对数据的实时访问。

image 上图是企业中一种常见的大数据分析平台部署框架 ,在这种部署架构中:


image Hive主要由以下三个模块组成: ・用户接口模块,含CLI、HWI、JDBC、Thrift Server等,用来实现对Hive的访问。CLI是Hive自带的命令行界面;HWI是Hive的一个简单网页界面;JDBC、ODBC以及Thrift Server可向用户提供进行编程的接口,其中Thrift Server是基于Thrift软件框架开发的,提供Hive的RPC通信接口。 ・驱动模块(Driver),含编译器、优化器、执行器等,负责把HiveQL语句转换成一系列MR作业,所有命令和查询都会进入驱动模块,通过该模块的解析变异,对计算过程进行优化,然后按照指定的步骤执行。 ・元数据存储模块(Metastore),是一个独立的关系型数据库,通常与MySQL数据库连接后创建的一个MySQL实例,也可以是Hive自带的Derby数据库实例。此模块主要保存表模式和其他系统元数据,如表的名称、表的列及其属性、表的分区及其属性、表的属性、表中数据所在位置信息等。

rainit2006 commented 6 years ago

Hive Apache Hive 是一种数据仓库应用程序,可以让您使用类似 SQL 的语言来查询 Amazon EMR 集群数据。

使用 Hive 查询 Apache 日志文件数据。Hive 会将您的查询转换为 Hadoop MapReduce 作业并在 Amazon EMR 集群上运行该作业。当 Hadoop 作业运行时,将显示状态消息。

例 1:统计 Apache Web 服务器日志文件中的行数 select count(1) from [TableName]; 例 2:返回一行日志文件数据中的所有字段 select * from serde_regex limit 1; 例 3:统计来自 IP 地址为 192.168.1.198 的主机的请求数 select count(1) from serde_regex where host="192.168.1.198";

教程

HiveQL(DDL): SQLに似ています。


HiveServer2, Hive metastore server, Hive metastore databaseの違い ■HiveServer2 リモート・クライアントがHiveに対してクエリを実行し、結果を取得するためのインタフェースを提供するサーバ。JDBC/ODBCといったオープンなAPIで接続が可能。

単なるインタフェースにとどまらず、並列接続性やセキュリティをHiveユーザに提供する役割も担う。セキュリティについては、認証および認可の両方を提供する。

■Hive metastore Hiveは内部で扱うメタデータを「metastore」というデータで保持しています。テーブルやパーティションなどの情報、またレコードが実際に保持されてある場所などのメタデータは全部このmetastoreにまとまっています。

■Hive metastore server metastore databaseへのアクセス・インタフェース。Thrift APIを通じてHiveのMetadataを作成/参照/更新/削除出来る。

metastore serverにはLocal/Embedded ModeとRemote Modeがある。Local/Embedded Modeの場合、Hive CLIやHiveServer2と同じプロセスで稼働する。つまりサーバというよりは、Hive CLIやHiveServer2がmetastore databaseにアクセスするためのライブラリのような働きをする。Remote Modeの場合、Hive CLIやHiveServer2は別プロセスまたは別サーバで稼働するmetastore serverを参照する。

Local/EmbeddedかRemoteかは、hive-site.xmlで設定する。具体的には「hive.metastore.uris」にリモートサーバのURIを書くと、Remote Mode、なにも書かないとLocal/Embdded Modeになる。

■Hive metastore database HiveのMetadataを格納しているDBのこと。Metadataとはテーブル名/カラム名やらIndex定義やらパーティション定義やら。 metastore databaseにもLocal/Embedded ModeとRemote Modeがある。データはRDBMSに格納され、Local/Embedded Modeの場合Derbyが、Remote Modeの場合MySQLなどが利用出来る。 Local/EmbeddedかRemoteかは、hive-site.xmlの「javax.jdo.option.ConnectionURL」にDerbyへの接続文字列を書くか、他RDBMSへの接続文字列を書くかで決まる。

rainit2006 commented 6 years ago

Run HiveQL from Java https://stackoverflow.com/questions/37896023/how-to-run-hive-ql-file-from-java-and-store-the-result-in-arraylist https://www.iteblog.com/archives/846.html

Hive提供了jdbc驱动,使得我们可以用Java代码来连接Hive并进行一些类关系型数据库的sql语句查询等操作。同关系型数据库一样,我们也需要将Hive的服务打开;

import java.sql.SQLException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.DriverManager;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class HiveQLWhere {
   private static String driverName = "org.apache.hadoop.hive.jdbc.HiveDriver";

   public static void main(String[] args) throws Exception {

      Map<String,List<String>> map = new HashMap<String,List<String>>();
   List<String> queryList = new ArrayList<String>();
   queryList.add("select colA , colB from table_name;");
   queryList.add("select colA , colB from table_name2;");
   queryList.add("select colA , colB from table_name3;");
   queryList.add("select colA , colB from table_name4:");

      // Register driver and create driver instance
      Class.forName(driverName);

      // get connection
      Connection con = DriverManager.getConnection("jdbc:hive://localhost:10000/userdb", "", "");

      // create statement
      Statement stmt = con.createStatement();

      for(String query : queryList){
      // execute statement
      ResultSet res = stmt.executeQuery(query);
      List<String> list = new ArrayList<String>();

      while (res.next()) {
         System.out.println(res.getString(1) + " " + res.getString(2));
         list.add(res.getString(1));
         list.add(res.getString(2));
         map.put(query.substring(query.lastIndexOf("from")+5,query.length()-1),list);
      }
   }
      con.close();
   }
}

如果你是用Maven,加入以下依赖

<dependency>
        <groupId>org.apache.hive</groupId>
        <artifactId>hive-jdbc</artifactId>
        <version>0.11.0</version>
</dependency>

<dependency>
        <groupId>org.apache.hadoop</groupId>
        <artifactId>hadoop-common</artifactId>
        <version>2.2.0</version>
</dependency>
rainit2006 commented 6 years ago

教程 http://gihyo.jp/dev/serial/01/emr

EMR起動方法:Web ConsoleとAPIの違い Webコンソールは,1回の操作でJobを1つしか実行できません。 一方APIを使用すると,1回の起動で複数のJobを実行できます。 EMRで使用できるAPIは言語ごとにいくつか用意されています: C#, Java、PHPなど。

Web Consoleでデバッグモードを使用するには: Web Consoleでは,Jobを作成する際にデバッグモードを使用するように設定しておく必要があります。 Java SDKでデバッグするには: RunJobFlowRequestに渡すパラメータとして,デバッグ用のステップコンフィグを定義します。

bootstrap Amazon Elastic Mapreduce(EMR)では,起動時にHadoopのオプションなどを設定できるbootstrapというものが用意されています。うまく利用すれば,細かくHadoopのチューニングをしたり,Jobが起動する前に前処理を行ったりすることができます。

Amazon Elastic MapReduceのパフォーマンスを引き出すためのHadoopの基礎知識

  1. Hadoopを使用する際は,サイズが小さいファイルを複数用意するよりも,大きいファイル(GB以上)を扱う方が効率的です
  2. Map: splitという単位で分散され,ユーザが特に意識することはない Reduce: 実際にReduceさせる数をユーザが指定する。デフォルト値は1(1つしかReduceが起動されない)

Map数はsplitという単位で分散されると前述しましたが,splitの単位はユーザが設定することができます。具体的には以下の2つの方法があります。 ①mapred-site.xmlに下記のように記述する

mapred.min.split.size:最小splitサイズ
mapred.max.split.size:最大splitサイズ

②コード中で指定する(以下はJavaの場合)

FileInputFormat.setMinInputSplitSize(job, minSize);
FileInputFormat.setMaxInputSplitSize(job, minSize);

何も指定しないのであれば,デフォルトは「HDFSブロックサイズ=splitサイズ」となります。 デフォルトでは「HDFSのブロックサイズ=split数」です。EMRの場合はHDFSではなくS3を使用するので,「⁠S3のファイル数=split数」となってしまいます。

EMRでMap数を増やすには以下のようにすることをお勧めします。

  1. mapred-site.xmlに適切なsplit値を設定し,bootstrapでEMRを設定する。Javaなどのコードであれば,InputFormatで適切なsplit値を設定する
  2. 大きいファイルであれば,S3に上げるときに,HDFSと同様,ブロックとしてファイルを細かく分ける.

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

AWS CLI -- Create EMR Cluster http://docs.aws.amazon.com/cli/latest/reference/emr/create-cluster.html

rainit2006 commented 6 years ago

EMRとHadoop https://dev.classmethod.jp/hadoop/emr-hive-metastore-rds/ EMRを利用するときには、必要になったらクラスタを起動して、使い終わったら終了させるという使い方をされる方が多いかと思います。 その際、HDFSのデータは消えてしまいますが、S3などに保存しておけば失われることはありません。 これによって、データを保存するストレージとジョブの実行を行うコンピューティングリソースの分離が実現できます。

Hiveではテーブル定義などをHadoop本体とは別にRDB(最近ではHBaseも選択可)に保持するメタストアがあります。 EMRではデフォルトでマスタノードにこのメタストアが設置されることになります。

EMRはクラスタを終了させるとマスタノードも含めて全てのインスタンスが削除されるため、この時にメタストアにあるテーブル定義情報も一緒に失われてしまうことになります。 クラスタを起動するたびに毎回テーブルやパーティションの作成を行っていると非常に効率が悪いですね。 そこで、EMRとは別にRDSを立てておき、メタストアはそちらを使うということができます。 image

Hadoopの環境構築を行ったことがある場合ご存知の方もいるかと思いますが、 環境によっては

rainit2006 commented 6 years ago

当数据量很大的时候,通常采用“分页查询”的方式。 比如MySQL有limit start,end那样的写法来实现分页查询。 但是Hive不支持分页查询。想实现的话需要Google搜索查找有没有办法了。