tonglin0325的个人主页

Hive学习笔记——函数

1.cast函数

数据类型转换函数

比如date的值为

参考:Hive中CAST()函数用法

2.explode函数

explode() 函数接收一个 array 或 map 作为输入,然后将 array 或 map 里面的元素按照每行的形式输出。其可以配合 LATERAL VIEW 一起使用

参考:Hive应用:explode和lateral view

3.lateral view

lateral view用于和split、explode等UDTF一起使用的,能将一行数据拆分成多行数据,在此基础上可以对拆分的数据进行聚合,lateral view首先为原始表的每行调用UDTF,UDTF会把一行拆分成一行或者多行,lateral view在把结果组合,产生一个支持别名表的虚拟表。

4.json_tuple

参考:一文学会Hive解析Json数组(好文收藏)

5.json UDF

brickhouse的json udf

1.brickhouse.udf.json.ToJsonUDF,将hive表转换成json

1
2
3
4
5
6
7
8
9
10
add jar /path/brickhouse-0.7.0-SNAPSHOT.jar;

CREATE TEMPORARY FUNCTION to_json AS 'brickhouse.udf.json.ToJsonUDF';

select to_json(named_struct( 'name', a.col_1, 'children' , array(named_struct('name', b.col_2, 'logins', b.col_3))))
from table_a a join table_b b on a.col_1 = b.col_1;

{"name":"userLogins","children":[{"name":"Site B","logins":20}]}
{"name":"userLogins","children":[{"name":"Site A","logins":10}]}

全文 >>

Spring MVC学习笔记——给Controller和视图传值

**  一、给Controller传值,值将显示在控制台**

  1.第一种:使用@RequestParam,改HelloController.java

1
2
3
4
5
6
7
8
//RequestMapping表示用哪一个url来对应
@RequestMapping({"/hello","/"})
public String hello(@RequestParam("username") String username){
System.out.println("hello");
System.out.println(username);
return "hello";
}

   然后在浏览器中输入请求

1
2
http://localhost:8080/SpringMVC_hello/hello?username=123

   控制台可以看到传的值

  但是使用了RequestParam,如果在请求中不传值的话,会报400错误,因为默认把参数作为了地址的一部分

**  2.第二种,把RequestParam删除,直接String username**

1
2
3
4
5
6
7
8
//RequestMapping表示用哪一个url来对应
@RequestMapping({"/hello","/"})
public String hello(String username){
System.out.println("hello");
System.out.println(username);
return "hello";
}

   这种可以不传值,不传值时候为null

**  二、再从Controller给视图传值**

**  1.用Map来传值**

**  修改HelloController.java文件,用Map<String,Object> context,不过不太建议用Map**

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package org.common.controller;

import java.util.Map;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class HelloController {

//RequestMapping表示用哪一个url来对应,从Controller给视图传值
@RequestMapping({"/hello","/"})
public String hello(String username,Map<String,Object> context){
context.put("username", username); //从Controller给视图传值
System.out.println(username);
System.out.println("hello");
return "hello";
}

}

全文 >>

给ubuntu的docky添加可以直接打开的图标

在/usr/share/applications和/usr/share/app-install/desktop寻找需要的图标,没有就自己做一个

eclipse的图标

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[Desktop Entry]

Version=1.0

Name=eclipse

Exec=/home/common/software/eclipse/eclipse

Terminal=false

Icon=/home/common/software/eclipse/eclipse.png

Type=Application

Categories=Development

 sublimetext的图标

**为了使得sublime能修改root的文件,安装gksu,然后在Exec前面加上gksu **

1
2
3
4
5
6
7
8
[Desktop Entry]
Name=SublimeText2
Type=Application
Terminal=false
Comment=Edit text files
Exec=/home/common/software/SublimeText2/sublime_text %F
Icon=/home/common/software/SublimeText2/sublime_text.png

 注意末尾不要有空格

 docky添加的图标的目录在

1
2
~/.local/share/applications

 

Hive学习笔记——常用SQL

1.查询第二高的值

输入:Salary表

1
2
3
4
5
6
+-------------+------+
| Column Name | Type |
+-------------+------+
| id | int |
| salary | int |
+-------------+------+

使用limit+offset语法来限制结果数量,其中 limit N,1 等于 limit 1 offset N

1
2
select (select DISTINCT Salary from Employee order by Salary DESC limit 1 offset 1) as SecondHighestSalary

输出:

1
2
3
4
5
+---------------------+
| SecondHighestSalary |
+---------------------+
| 200 |
+---------------------+

2.查询连续出现3次的数字

输入:Logs表

1
2
3
4
5
6
7
8
9
10
11
+----+-----+
| id | num |
+----+-----+
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 4 | 2 |
| 5 | 1 |
| 6 | 2 |
| 7 | 2 |
+----+-----+

查询表3次,然后通过where条件来筛选

1
2
3
4
5
6
7
8
9
SELECT DISTINCT(t1.Num) as ConsecutiveNums
FROM Logs t1, Logs t2, Logs t3
WHERE
t1.Id = t2.Id - 1
AND t2.Id = t3.Id - 1
AND t1.Num = t2.Num
AND t2.Num = t3.Num
;

全文 >>

Flink学习笔记——窗口

Flink窗口(window)可以用于keyed streams和non-keyed streams

参考官方文档:https://nightlies.apache.org/flink/flink-docs-master/zh/docs/dev/datastream/operators/windows/

1.一些概念

1.时间语义

flink支持3种时间语义,分别是Event time,Processing time和Ingestion time。

参考:https://nightlies.apache.org/flink/flink-docs-release-1.17/docs/learn-flink/streaming_analytics/

1.Event time

Event time的时间戳是每个单独事件在其产生设备上发生的时间。Event time通常在record进入Flink之前就嵌入到record中,这样就可以从每条record中提取事件时间戳。在Event time中,时间的进程取决于数据,而不是任何时钟。Event time程序必须指定如何生成Event time watermarks,这是一种以事件时间表示进度的机制。

在理想情况下,Event time处理将产生完全一致和确定的结果,而不管事件何时到达或它们的顺序如何。然而,除非事件是按顺序到达的(按时间戳),否则事件时间处理在等待乱序事件时会产生一些延迟。因为只能等待一段有限的时间,这就限制了Event time应用程序的确定性。

2.Processing time

Processing time是指执行相应operator的机器的系统时间。

当流处理程序在Porcessing time上运行时,所有基于时间的操作(如时间窗口)将使用运行相应操作的机器的系统时钟。每小时的处理时间窗口将包括在系统时钟显示整个小时的时间之间到达特定操作员的所有记录。例如,如果应用程序在上午9点15分开始运行,第一个小时处理时间窗口将包括上午9点15分到10点之间处理的事件,下一个窗口将包括上午10点到11点之间处理的事件,以此类推。 

Processing time是最简单的时间概念,不需要流和机器之间的协调。它提供了最好的性能和最低的延迟。然而,在分布式和异步环境中,处理时间不提供确定性,因为它容易受到记录到达系统中的速度(例如从消息队列)、记录在系统内部操作符之间流动的速度以及中断(计划或其他)的影响。

3.Ingestion time

Flink在采集事件时记录的时间戳

全文 >>

Flink学习笔记——checkpoint

1.开启checkpoint

默认情况下checkpoint是禁用的,需要手动进行开启,如下

1
2
3
4
5
6
7
8
9
10
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
StreamTableEnvironment tableEnv = StreamTableEnvironment.create(env);
env.getCheckpointConfig().setCheckpointTimeout(3600000); // checkpoint1小时超时
env.enableCheckpointing(180000, CheckpointingMode.EXACTLY_ONCE); // 3分钟做一次checkpoint
env.getCheckpointConfig().setMaxConcurrentCheckpoints(1); // 同一时间只允许一个 checkpoint 进行
env.getCheckpointConfig().setTolerableCheckpointFailureNumber(2); // 允许两个连续的 checkpoint 错误
env.setStateBackend(new EmbeddedRocksDBStateBackend(true)); // 使用rocksdb state backend
env.getCheckpointConfig().setCheckpointStorage("s3://xxxx/xxxx/test_checkpoint"); // 指定gcheckpoint路径
env.getCheckpointConfig().setExternalizedCheckpointCleanup(CheckpointConfig.ExternalizedCheckpointCleanup.RETAIN_ON_CANCELLATION); // 使用 externalized checkpoints,这样 checkpoint 在作业取消后仍就会被保留

其他配置参考官方文档

1
https://nightlies.apache.org/flink/flink-docs-release-1.16/zh/docs/dev/datastream/fault-tolerance/checkpointing/

2.从保留的 checkpoint 中恢复状态

1
2
bin/flink run -s checkpoint_path

参考:https://nightlies.apache.org/flink/flink-docs-master/zh/docs/ops/state/checkpoints/

3.checkpoint相关问题

做checkpoint很慢问题排查,参考:2022年最新版 | Flink经典线上问题小盘点

增量checkpoint,参考:Flink 管理大型状态之增量 Checkpoint

大状态与 Checkpoint 调优,参考:大状态与 Checkpoint 调优

 

全文 >>

Spring MVC学习笔记——Welcome

1.SpringMVC概念

2.整个springmvc运行的流程

  请求–><1>Dispatcher servlet(controller控制器)–><2>HandlerMapping(这个在配置文件中写,可以通过这个找到url该给哪个具体的controller来处理)

                       –><3>controller(具体的控制器)–><4>Model and logical viewname(具体的控制器再将值传给dispatcher servlet)

                       –><5>view resolver(通过这来找到对应的视图)

                       –><6>view

 

3.创建SpringMVC项目

在eclipse下建立一个动态web项目springmvc_hello,记得勾选web.xml的生成按钮

在生成的项目的WEB-INF的lib文件夹下面导jar包

**  要开发一个Welcome项目需要导两个包:**

**  一个是springmvc的包,另一个是Apache的commonslogging的包**

  两个包的官方下载地址分别是

  http://maven.springframework.org/release/org/springframework/spring/3.2.0.RELEASE/

  和http://commons.apache.org/ (bin的那个包,不是源代码包)

全文 >>

Flink学习笔记——统一的source服务

为了方便使用Flink对流式数据进行统一的读写,需要开发统一的source服务

  1. kafka source

需要可配置的参数,参考flume的kafka source配置参数

1
2
https://flume.apache.org/FlumeUserGuide.html#kafka-source

定义KafkaSourceConstants,参考:

1
2
https://github.com/apache/flume/blob/trunk/flume-ng-sources/flume-kafka-source/src/main/java/org/apache/flume/source/kafka/KafkaSourceConstants.java

比如对于kafka source相关的配置,统一的前缀为 kafka.source.,比如

1
2
3
4
5
# kafka source
kafka.source.bootstrap.servers=localhost:9092
kafka.source.topics=thrift_log_test
kafka.source.group.id=test

参考文章:Flink学习笔记——配置,对kafka source前缀的配置进行读取

 

全文 >>

Java多线程——延迟队列DelayQueue

DelayQueue是一个基于优先队列(PriorityQueue)实现的阻塞队列(BlockingQueue),队列中的消息的优先级是根据消息的TTL来决定的。

参考:Java延迟队列DelayQueue

使用延迟队列实现定时任务调度器

参考:https://soulmachine.gitbooks.io/system-design/content/cn/task-scheduler.html