使用aws的mapreduce前,要先了解三个名词:
EC2:主机,所有服务运行在上面;分不同类型,计算能力不一样,收费也不一样
EMR:Aws的mapreduce,可运行hadoop/hive/spark/hue…等大数据框架,优势是几分钟可以搭建好集群,并且节点数可根据实际需要随时调整
S3:分布式存储系统,在EMR中一般替代hdfs来存储大数据,价格相对更低廉
aws计费包括计算(Ec2&EMR)、存储(S3)、流量(导出流量,导入暂时不计费)
 
我处理的数据量还算比较大,每天将近900G的LOG存储于第三方的s3上,需要把每天的LOG借助EMR做ETL后存储到自己的s3
在这过程中踩过不少的坑,这里总结一下:
 
1,s3的授权访问问题
原始LOG都存储在三方的s3上,ETL直接将三方的s3作为输入,需要对方授权访问,问题在与对方开放权限了,通过命令行可以访问(aws s3 ls s3://xxx),但通过external hive table locate到对方s3提示权限问题
后来aws技术支持答复按下面配置解决
为了利用角色访问,请将S3 bucket中的Principal不指定为账号下的特定IAM user,而是用root,如下:
      “Principal”: {
       “AWS”: “arn:aws-cn:iam::025053319564:root”
       }


2,HUE & hadoop jobtracker界面访问

HUE可视化界面Hive查询兼File browser功能 jobtracker用来查看job history及状态的,默认是无法直接通过 http://master-public-dns-name:8888/ 访问HUE的
有两种方法:
1,ssh隧道也就是端口映射 http://docs.aws.amazon.com/zh_cn/ElasticMapReduce/latest/ManagementGuide/emr-ssh-tunnel-local.html
2,直接开放master的端口权限,可限制访问者IP
 

3,spark-shell  pyspark  spark-sql 这几个命令都没法交互,一直在轮训日志
16/05/04 07:11:26 INFO Client: Application report for application_1462242003486_0028 (state: ACCEPTED)
其实这个问题也在个人,一边满负荷的在跑ETL job,一边还想通过spark来做ad-hoc查询,这几条命令都是通过spark-submit来提交job的,由于当前集群资源已经用光,spark无法申请到可用的container,所以只能一直无法提交任务,导致log的轮训,等etl job结束释放资源后就没问题了

4,hive中文乱码
很多场景下都会碰到,首先修改hive-site.xml的mysql jdbc url加上&useUnicode=true&characterEncoding=utf-8,启动hive cli直接报
The reference to entity “useUnicode” must end with the ‘;’ delimiter
尝试多次后无果,只能求助aws技术,反馈给我的是有两种调整方式,其中一种调整jdbcurl,由于&在xml属于特殊字符,需要转码成&
调整后果然成功了,乱码也消失了
aws 技术还提供了另一种创建EMR时初始化Hive配置,注意在host部分不能写localhost,否则会引起mysql权限问题,一定要用://%{fqdn}
[
  {
    “classification”: “hive-site”,
    “properties”: {
        “javax.jdo.option.ConnectionURL”: “jdbc:mysql://%{fqdn}:3306/hive?createDatabaseIfNotExist=true&useUnicode=true&characterEncoding=utf-8″
    }
  }
]


5, s3文件合并
s3出现了大量小文件,处于资源考虑需要做一次合并
一种方式是hadoop fs -getmerge s3://xx  合并在本地然后再上传,由于EC2选的m3.xlarge,严重超出了本地磁盘存储,幸好s3提供了s3-dist-cp 功能其中有一个group-by参数可实现合并,需要注意的是:groupBy需要匹配S3的prefix,如果路径匹配错误,则会报错。
需要把userId-m-01***  userId-m-02***  userId-m-03***各自合并成三个大文件,可以参考使用如下命令再次测试:
s3-dist-cp –src=s3://emr-for-shareitlog/output/shareit/20160410/userId/ –dest=s3://emr-for-shareitlog/mapper/shareit/20160410/userId/ –groupBy=.*userId-m-0([0-9]).*
 http://docs.aws.amazon.com/ElasticMapReduce/latest/DeveloperGuide/UsingEMR_s3distcp.html

6,aws cli安装
平时有从s3导入导出文件的需求,在目标机器上安装aws cli能方便许多
 linux下使用bundled installer
wget https://s3.amazonaws.com/aws-cli/awscli-bundle.zip
unzip awscli-bundle.zip
sudo ./awscli-bundle/install -i /usr/local/aws -b /usr/local/bin/aws
 
安装成功后再运行aws configure 输入access key 、secret key、region等
之后就能直接连到s3上操作文件了

7, S3通配符删除文件
EMR写入S3很容易产生类似file_prefix{folder}之类的文件,在s3提供的api里没有找到支持模糊匹配的通配符  比如aws s3 rm s3://bucket/file_prefix*folder*
但有S3独有的处理方式  include  exclude  比如要删除s3://bucket/file_prefix*folder* 的文件(夹),执行以下命令即可:
aws s3 rm s3://bucket/ –recursive –exclude “*” –include file_prefix*folder*