技术博客


  • 首页

  • 关于

  • 标签

  • 分类

  • 归档

  • 搜索

shell脚本使用和总结

发表于 2018-02-04 | 分类于 工具 | | 阅读次数:
字数统计: 1.1k | 阅读时长 ≈ 4

shell脚本使用和总结

hello world

  • 新建test1.sh
  • 内容echo Hello world!

如果需要的话,赋予可执行权限chmod +x test1.sh

执行指令

可以在脚本中写入更多的命令,比如:启动app,编译、运行java文件,链接服务器等等;只要你能想到的,基本都可以。在此,我仅以一个简单的例子来说明:通过脚本编译运行一个java文件。

1
2
3
cd /Users/daniel/Documents/tmp
javac Test2.java
java Test2

匹配规则${},##, %% , :- ,:+, ? 的使用(路径处理)

假设我们定义了一个变量为:file=/dir1/dir2/dir3/my.file.txt

  • 1.可以用${ }分别替换得到不同的值:
1
2
3
4
5
6
7
8
${file#*/}:删掉第一个/ 及其左边的字符串:dir1/dir2/dir3/my.file.txt
${file##*/}:删掉最后一个/ 及其左边的字符串:my.file.txt
${file#*.}:删掉第一个. 及其左边的字符串:file.txt
${file##*.}:删掉最后一个. 及其左边的字符串:txt
${file%/*}:删掉最后一个 / 及其右边的字符串:/dir1/dir2/dir3
${file%%/*}:删掉第一个/ 及其右边的字符串:(空值)
${file%.*}:删掉最后一个 . 及其右边的字符串:/dir1/dir2/dir3/my.file
${file%%.*}:删掉第一个 . 及其右边的字符串:/dir1/dir2/dir3/my
  • 2.记忆的方法为:
1
2
3
4
5
6
7
8
# 是 去掉左边(键盘上#在 $ 的左边)
%是去掉右边(键盘上% 在$ 的右边)
单一符号是最小匹配;两个符号是最大匹配
${file:0:5}:提取最左边的5 个字节:/dir1
${file:5:5}:提取第5 个字节右边的连续5个字节:/dir2
也可以对变量值里的字符串作替换:
${file/dir/path}:将第一个dir 替换为path:/path1/dir2/dir3/my.file.txt
${file//dir/path}:将全部dir 替换为path:/path1/path2/path3/my.file.txt
  • 3.利用${ } 还可针对不同的变数状态赋值(沒设定、空值、非空值):
1
2
3
4
5
6
7
8
9
10
11
12
13
${file-my.file.txt} :假如$file 沒有设定,則使用my.file.txt 作传回值。(空值及非空值時不作处理) 
${file:-my.file.txt} :假如$file 沒有設定或為空值,則使用my.file.txt 作傳回值。(非空值時不作处理)
${file+my.file.txt} :假如$file 設為空值或非空值,均使用my.file.txt 作傳回值。(沒設定時不作处理)
${file:+my.file.txt} :若$file 為非空值,則使用my.file.txt 作傳回值。(沒設定及空值時不作处理)
${file=my.file.txt} :若$file 沒設定,則使用my.file.txt 作傳回值,同時將$file 賦值為my.file.txt 。(空值及非空值時不作处理)
${file:=my.file.txt} :若$file 沒設定或為空值,則使用my.file.txt 作傳回值,同時將$file 賦值為my.file.txt 。(非空值時不作处理)
${file?my.file.txt} :若$file 沒設定,則將my.file.txt 輸出至STDERR。(空值及非空值時不作处理)

${file:?my.file.txt} :若$file 没设定或为空值,则将my.file.txt 输出至STDERR。(非空值時不作处理)

${#var} 可计算出变量值的长度:

${#file} 可得到27 ,因为/dir1/dir2/dir3/my.file.txt 是27个字节

分割字符串

比如,要分割test="aaa,bbb,cc cc,dd dd",可以这样:

1
2
3
4
5
6
7
8
9
10
11
# 1.分割
OLD_IFS="$IFS"
IFS="-"
arr=($filename)
IFS="$OLD_IFS"

# 2.获取
for x in $arr; do
echo $x
done
echo ${arr[0]}

实例

取出照片,按照日期创建文件夹,并将文件放到指定文件夹中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
for filePath in /Users/***/DCIM/*.jpg; do
# 1.获取文件名,eg: P70827-165946.jpg
filename=${filePath##*/}
echo ${filename}

# 2.获取日期标识部分P70827:从头开始取6位
dirName="/Users/***/DCIM/"${filename:0:6}
echo $dirName"\n"

# 3.根据日期创建文件夹
mkdir -p ${dirName}

# 4.将文件移入该文件夹
mv ${filePath} ${dirName}
done

注意事项

  • 等号=两边不能有空格:空格对于linux的shell是一种很典型的分隔符,所以给变量赋值的时候中间不能够有空格。

参考文档

  • 求助linux下批量建立文件夹和移动文件
  • Shell 教程
  • shell编程--遍历目录下的文件
  • shell中的${},##和%%的使用
  • linux shell 字符串操作详解 (长度,读取,替换,截取,连接,对比,删除,位置 )

表达式引擎性能比较

发表于 2018-02-03 | 分类于 研发技能 | | 阅读次数:
字数统计: 934 | 阅读时长 ≈ 4

表达式引擎性能比较

表达式引擎选型

选择3种主要的表达式引擎进行性能对比,从而选择最优表达式引擎和最优方案。常用的3中规则引擎:QLExpress、MEVL、JUEL。

性能测试

性能测试维度:

  • 表达式引擎维度:主要采用了3种引擎的5种实现方式,即QLExpress 使用缓存; mvel 不编译; mvel 先编译; mvel 先编译,且指定输入值类型; juel 指定输入值类型。注:QLExpress 不使用缓存的话,性能非常低,就不再进行对比测试。
  • 表达式维度:主要采用了3种类型的表达式,后续的大多数需求,都属于这3种方式。即:
    • 最常见的场景(多个条件进行and操作): a<100 && b>=100 && c<=123,
    • 包含特殊的操作(contains):a<100 && b>=100 && c<=123 && stringList.contains(str)
    • 一个稍微复杂一点的语法树:a>1 && ((b>1 || c<1) || (a>1 && b<1 && c>1))

测试方式

10次循环,每次循环执行这5种方式10万次,即每种方式执行100万次。为了保证一定的差异性,变量赋值的时候,采用变化的值。代码详见附录。

执行结果:

对结果进行可视化,很显然Mvel不编译方式耗时最高。

为了方便查看,将Mvel不编译方式过滤掉,得到下图。得到以下结论:

  • 性能高低顺序为:mvel 先编译,且指定输入值类型 > mvel 先编译 > juel 指定输入值类型 > QLExpress 使用缓存 > mvel 不编译。
  • juel 指定输入值类型性能也可以接受,但是在使用了contains操作后,性能明显降低很多。

结论

mvel 先编译,且指定输入值类型方式性能为最优,采用该方式作为表达式引擎的实现方式。但是,采用自己实现一层缓存:用来缓存预编译的结果,同时,采用2小时无访问,则更新缓存的策略。缓存使用Guava Cache实现。

注: 1. QLExpress自身实现了缓存机制,如果性能要求没那么高的话,也可以采用该方式。 2. 如果规则非常多,比如到了亿级别的规模,并且基本不复用规则的话,就没有必要先编译并缓存了。或者调整缓存策略。

附录

机器配置

1
2
3
4
MacBook Pro (13-inch, 2017, Two Thunderbolt 3 ports)
处理器 2.3 GHz Intel Core i5
内存 8 GB 2133 MHz LPDDR3
图形卡 Intel Iris Plus Graphics 640 1536 MB

表达式引擎版本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<!-- https://mvnrepository.com/artifact/org.mvel/mvel2 -->
<dependency>
<groupId>org.mvel</groupId>
<artifactId>mvel2</artifactId>
<version>2.4.0.Final</version>
</dependency>

<!-- https://mvnrepository.com/artifact/ognl/ognl -->
<dependency>
<groupId>ognl</groupId>
<artifactId>ognl</artifactId>
<version>3.2.4</version>
</dependency>

<!-- https://mvnrepository.com/artifact/de.odysseus.juel/juel-api -->
<dependency>
<groupId>de.odysseus.juel</groupId>
<artifactId>juel-api</artifactId>
<version>2.2.7</version>
</dependency>

<!-- https://mvnrepository.com/artifact/de.odysseus.juel/juel-impl -->
<dependency>
<groupId>de.odysseus.juel</groupId>
<artifactId>juel-impl</artifactId>
<version>2.2.7</version>
</dependency>

Java代码

详见: https://github.com/DanielJyc/expression-language-compare/blob/master/java/src/Test.java

参考文档

  • mvel github
  • QLExpress
  • MVEL 2.0 官方文档
  • Transwiki:MVEL Language Guide
  • Mvel2.0使用指南一 基础
  • mvel2.0语法指南
  • Ognl/MVEL/Aviator/JSEL 四种表达式引擎执行效率对比
  • 在Excel图表中制作三维立体图表的方法
  • juel Quickstart
  • THE ART OF BEING EXPRESSIVE

Storm+kafka

发表于 2018-01-19 | 分类于 大数据 | | 阅读次数:
字数统计: 42 | 阅读时长 ≈ 1

Storm+kafka

Storm+kafka

flume实时收集日志,kafka消息队列源源不断生产数据,然后由storm进行实时消费。

参考

  • Storm+kafka的HelloWorld初体验

Apache Superset

发表于 2018-01-17 | 分类于 大数据 | | 阅读次数:
字数统计: 510 | 阅读时长 ≈ 1

Apache Superset

Superset其实是一个自助式数据分析工具,它的主要目标是简化我们的数据探索分析操作。

相似产品对比

name 描述 实现
grafana grafana的druid插件,比较简陋,github一年不更新了 js
Metabase 支持数据库种类多,启动方便,支持json查询。图形化查询,只能有一个聚合字段,两个维度 Clojure
imply-pivot 基于Plywood,部署方便,能构造复杂的查询。目前已经闭源了,没法二次开发 Js
airbnb/superset 权限管理完善,图形可定制性也比较高,github持续更新,集合了metabase的Dashboard和pivot的查询可定制性优点,部署相对麻烦 python+js

数据库支持

Superset 是基于 Druid.io 设计的,但是又支持横向到像 SQLAlchemy 这样的常见Python ORM框架上面。

Druid 是一个基于分布式的快速列式存储,也是一个为BI设计的开源数据存储查询工具。Druid提供了一种实时数据低延迟的插入、灵活的数据探索和快速数据聚合。现有的Druid已经可以支持扩展到TB级别的事件和PB级的数据了,Druid是BI应用的最佳搭档。

跟类似产品Hive相比,速度快了很多。

架构

整个项目的后端是基于Python的,用到了Flask、Pandas、SqlAlchemy。

后端:

  • Flask AppBuilder(鉴权、CRUD、规则)
  • Pandas(分析)
  • SqlAlchemy(数据库ORM)

前端:

用到了npm、react、webpack,这意味着你可以在手机也可以流畅使用。

  • d3 (数据可视化)
  • nvd3.org(可重用图表)

局限性

  • Superset的可视化,目前只支持每次可视化一张表,对于多表join的情况还无能为力
  • 依赖于数据库的快速响应,如果数据库本身太慢Superset也没什么办法
  • 语义层的封装还需要完善,因为druid原生只支持部分sql。

参考

  • 解密Airbnb 自助BI神器:Superset 颠覆 Tableau
  • superset官网
  • druid.io可视化调研
  • Grafana vs Superset

Apache Ambari

发表于 2018-01-17 | 分类于 大数据 | | 阅读次数:
字数统计: 202 | 阅读时长 ≈ 1

Apache Ambari

用来创建、管理、监视 Hadoop 的集群,但是这里的 Hadoop 是广义,指的是 Hadoop 整个生态圈(例如 Hive,Hbase,Sqoop,Zookeeper 等),而并不仅是特指 Hadoop。用一句话来说,Ambari 就是为了让 Hadoop 以及相关的大数据软件更容易使用的一个工具。

Ambari 自身也是一个分布式架构的软件,主要由两部分组成:Ambari Server 和 Ambari Agent。简单来说,用户通过 Ambari Server 通知 Ambari Agent 安装对应的软件;Agent 会定时地发送各个机器每个软件模块的状态给 Ambari Server,最终这些状态信息会呈现在 Ambari 的 GUI,方便用户了解到集群的各种状态,并进行相应的维护。

参考

  • Ambari——大数据平台的搭建利器
1234…8
DanielJyc

DanielJyc

数据驱动 Java 大数据 算法

40 日志
5 分类
28 标签
RSS
Links
  • Danieljyc blog
© 2014 — 2019 DanielJyc | Site words total count: 53k
由 Hexo 强力驱动
|
主题 — NexT.Muse v5.1.4
京ICP备 - 19007489号