分类 技术 下的文章

Mac通过Rename命令批量重命名文件

问题背景:

海贼王OnePiece动画连载已近800集,由于之前是从不同渠道(汉化组、动漫论坛等)下载的,文件命名规则自成一套体系。
对于有轻度收集癖和强迫症的我来说,进行分类管理以及命名规则的统一,蓄谋已久。

It's time!

需求列表:

  • 兼容现有的各种命名规则
  • 名称统一转换为:OnePiece-xxx
  • 保留原有的视频格式后缀

实现过程

  1. 通过Homebrew安装rename
  2. 分析文件对象特征,补充知识
  3. 研究成果展示及拆解

Continue Reading...

可视化分析Hue整合Spark&Hive

前言

下图为我近期研究的结果,计划搭建BI分析平台。

系统架构图.png

原本计划使用Kylin,但发现某些场景Kylin支持得不算好(如:多值维度的统计分析);
发现Hive内置函数explode()是支持行转列的,Spark 1.3后的版本也支持,因此还是考虑回归目前的计算框架。
数据层面也需要进行梳理,计划陆续开展,暂且不谈。

所有环境都是在Macbook Pro(OS X 10.11.6)安装的单机版;
默认Hadoop、Hive、Spark均已安装完毕。


安装Hue

参考:
1.http://gethue.com/start-developing-hue-on-a-mac-in-a-few-minutes/
2.https://github.com/cloudera/hue

重要内容:
1、安装Xcode命令行工具

xcode-select --install

我先按照github上的步骤进行操作,遇到一些奇怪的问题,多为库文件头找不到,如:'openssl/e_os2.h' file not found,浪费了不少精力和时间,后来找到官方的指导(参考2)后才一路畅通。

2、到HUE_HOME目录下编译

make apps

3、修改配置参数

vi ./desktop/conf/pseudo-distributed.ini

若其它组件的端口都是按默认配置安装的,Hue的默认设置无需更改,会自动检测并连接。

4、启动服务

./build/env/bin/hue runserver

这时应该能够访问Hue的页面,初次登录需创建管理员用户及密码。


组件配置

一、HDFS

(默认切换至HADOOP_HOME,下同)
1.开启webhdfs

vi ./etc/hadoop/hdfs-site.xml

添加以下参数:

<property>
<name>dfs.webhdfs.enabled</name>
<value>true</value>
</property>

测试命令:
curl -i "http://localhost:50070/webhdfs/v1/?user.name=hadoop&op=LISTSTATUS"

2.允许超级用户模拟其他用户

 vi ./etc/hadoop/core-site.xml

添加以下参数:

<property>
<name>hadoop.proxyuser.hue.hosts</name>
<value>*</value>
<description>Allow the superuser hue to impersonate any members of the group group1 and group2</description>
</property>

<property>
<name>hadoop.proxyuser.hue.groups</name>
<value>*</value>
</property>

允许hue用户模拟其他用户,若有其他超级用户,还需添加类似的配置(比如我都是使用Edward启动各类组件的,此处还需加上Edward的文件)
建议新建OS用户hue并划分至hadoop组内,不过我本地习惯单用户,将错就错了 :P

3.添加HDFS权限
hdfs dfs -chmod 777 -R /tmp

注:777仅限本地或测试用;(另准备研究下Hue如何集成账号权限管理Sentry+Kerberos)
配置修改后,记得重启Hadoop集群。

二、Hive

1.启动hiveserver2

./bin/hive --service hiveserver2

若有Spark,此步可略,后文详述。

三、Spark

我的目的很简单,只是希望能够在web端执行Spark SQL。

在官方查阅了几篇文章,有篇建议通过Spark Job Server,能够上传jar并执行任务:
http://gethue.com/a-new-spark-web-ui-spark-app/

有篇是通过Livy Server提供REST接口:
http://gethue.com/how-to-use-the-livy-spark-rest-job-server-for-interactive-spark-2-2/

最终发现通过启动Spark的thriftServer即可

cd ${SPARK_HOME}/sbin
./start-thriftserver.sh --master local

Query Editors页面选择Hive即可。

注: thriftServer是用来替代hiveserver2,根据性能测试结果,建议使用Spark的thriftServer 。

AWS CLI多用户配置文件切换

前言

之前研究AWS S3时AWS S3&IAM 权限控制研究,主要是通过本地(MAC)安装命令行工具(CLI,Command Line Interface)进行基础操作。
由于当时只有一个账户的访问需求,所以配置和证书文件中都只有默认的 default 配置档案;
今天我需要访问他人的AWS资源,而又希望能够保持历史配置信息,因此稍作研究,得出了本地环境下在多个配置文件之间切换的方案。

参考文档:
配置 AWS Command Line Interface


AWS本地配置文件

首先引用下 AWS CLI 环境变量列表:

AWS CLI 支持以下变量:

AWS_ACCESS_KEY_ID – AWS 访问密钥。

AWS_SECRET_ACCESS_KEY – AWS 私有密钥。访问和私有密钥变量会覆盖证书和 config 文件中存储的证书。

AWS_SESSION_TOKEN – 会话令牌。只有在使用临时安全证书时才需要会话令牌。

AWS_DEFAULT_REGION – AWS 区域。如果设置,此变量会覆盖正在使用的配置文件的默认区域。

AWS_DEFAULT_PROFILE – 要使用的 CLI 配置文件的名称。可以是存储在证书或 config
文件中的配置文件的名称,也可以是 default,后者使用默认配置文件。

AWS_CONFIG_FILE – CLI config 文件的路径。

AWS本地配置文件,其实就是对上述环境变量进行维护的文件,此为前提;
尤其需重点关注以下常用配置项:

  • AWS_DEFAULT_PROFILE
  • AWS_ACCESS_KEY_ID
  • AWS_SECRET_ACCESS_KEY
  • AWS_DEFAULT_REGION

AWS本地配置文件共有两个,分别是:

//配置文件,存储region、output配置项
~/.aws/config
//证书文件,存储aws_access_key_id、aws_secret_access_key配置项。
~/.aws/credentials 

credentials的多配置文件格式示例如下:

vi ~/.aws/credentials
##默认配置
[default]
aws_access_key_id = ACCESS_KEY_ID
aws_secret_access_key = SECRET_ACCESS_KEY

##新增配置,命名为 "PROFILE_NAME"
[dsptest]
aws_access_key_id = ACCESS_KEY_ID
aws_secret_access_key = SECRET_ACCESS_KEY

config的多配置文件格式示例如下:

vi ~/.aws/config
##默认配置
[default]
region = ap-southeast-1

##与credentials中的配置项保持一致,命名为 "profile $PROFILE_NAME"
[profile dsptest]
region = cn-north-1
output = json

后期若有新的账号需要添加,分别在config和credentials中添加相应内容即可。


AWS多用户配置文件切换

最初,我以为配置文件切换的命令是:

aws configure --profile $PROFILE_NAME

测试数次后仍无法访问S3资源。
后来在其它电脑上测试通过,其AWS配置文件中只有default区域,证明ID\KEY无误,遂判断本地的问题根源是没能读取到最新的配置内容。
查阅官方指南后,发现:
aws configure 命令其实是修改配置文件的,更改会保存到config和credentials文件中;

切换/设定所有aws命令的执行环境是:
export AWS_DEFAULT_PROFILE= $PROFILE_NAME ,即修改AWS CLI 环境变量。


AWS S3常用命令

##递归地复制目录下的子文件
aws s3 cp newfolder s3://S3BUCKET --recursive

##列出指定目录下的文件
aws s3 ls s3://S3BUCKET

##递归地复制目录下的部分子文件
aws s3 cp newfolder s3://S3BUCKET --recursive --exclude "*" --include "task1*"

Lua入门学习

闲暇时间,了解机器学习(Machine Learning),看到知乎上的一个回答,引起了我的兴趣,因此准备捣鼓下玩玩。

趁着安装Torch依赖环境的等待时间,看了一部分Learn Lua in 15 Minutes(之前对Lua脚本有过接触,比如魔兽世界的脚本/宏),其中有一段光看文字没怎么理解。
摘录如下:

-- Literal notation for any (non-nil) value as key:
u = {['@!#'] = 'qbert', [{}] = 1729, [6.28] = 'tau'}
print(u[6.28])  -- prints "tau"

-- Key matching is basically by value for numbers
-- and strings, but by identity for tables.
a = u['@!#']  -- Now a = 'qbert'.
b = u[{}]     -- We might expect 1729, but it's nil:
-- b = nil since the lookup fails. It fails
-- because the key we used is not the same object
-- as the one used to store the original value. So
-- strings & numbers are more portable keys.

KEY 可以是任何非空值,u[{}] 我乍一看以为值对应的是 1729,英文描述没太理解:

从table中查找KEY为"{}"的值失败,原因在于:用做查找的KEY与存储原始数据的KEY两者不一致。

Torch安装完毕后,亲自写代码操作一番,才发现问题的根源:
u[{}] 是指把 空table 做为KEY,实际存储结构如下:

th> u = {['!!!'] = 'test',[{}] = 1111,[6.33] = 'tab' }

th> print(u)
{
  !!! : "test"
  table: 0x00dd6d68 : 1111
  6.33 : "tab"
}

th> print(u[{}])
nil

一目了然。
(英文中也有提到: but by identity for tables ,需要通过table的ID作为查找的KEY,只是看的时候没有关联起来理解)。

ElasticSearch安装及初步研究

环境部署

ElasticSearch安装很简单,解压后直接运行脚本,就能得到一个可访问的测试环境了。
基础环境:

  • JDK 1.7/1.8(数据导入需要)
  • ElasticSearch 2.3.3
  • Marvel 2.3.3
  • Kibana 4.5.1
  • Sense 2.0.0-beta5

插件(Plugin)安装步骤:


初步研究

测试场景
1.数据结构:id + 多列属性;
2.通过多个属性的组合条件,查询对应的id数量。

数据准备
1.通过Python生成逗号分隔的原始文件,共计100万条;

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import random

strLine = 'id,sex,age,marriage,income,house,car,cardlevel,index,readeri,sporteri' +'\n'

listSex = [1,2]
list3 = [1,2,3]
list5 = [1,2,3,4,5]

def str_format(*appendStr):
    tmp = ''
    length = len(appendStr)
    i = 0
    while i < length - 1 :
        tmp += appendStr[i] + ',' 
        i = i + 1
    return tmp + appendStr[length - 1 ]

for id in range(1000000):
    sex = str(random.choice(listSex))
    age = str(random.choice(listSex))
    marriage = str(random.choice(list3))
    income = str(random.choice(listSex))
    house = str(random.choice(listSex))
    car = str(random.choice(listSex))
    cardlevel = str(random.choice(list3))
    index = str(random.choice(list3))
    readeri = str(random.choice(list5))
    sporteri = str(random.choice(list5))

    strLine += str_format(str(id),sex,age,marriage,income,house,car,cardlevel,index,readeri,sporteri)
    strLine += '\n'
# print(strLine)
with open('/Users/Edward/Dev/python/test.txt', 'w') as f:
    f.write(strLine)

2.数据导入至MySQL;
3.数据导入至ElasticSearch。

PS:照理来说,应该可以跳过第2步,直接导入到ElasticSearch中,只是懒得研究,力图早点出结果,后面再慢慢学习。

测试结果

kylin   hive    MySQL   ElasticSearch   语句
0.17    18.361  0.402   0.011           select count(*) from id_tag where sex = 2 and index = 2;
0.23    18.354  0.433   0.023           select count(*) from id_tag where sex = 2 and index = 2 and income =1 and car =1 and readeri = 3;
0.14    18.166  0.47    0.011           select count(*) from id_tag where sex = 2 and index = 2 and income =1 and car =1 and readeri = 3 and sporteri=5 and marriage=1;

由此可见,在类似场景中,ElasticSearch的查询能力非常强悍;
而ElasticSearch的能力不仅限于此,结合其它插件,可以做简单的OLAP分析。