tonglin0325的个人主页

给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

全文 >>

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
;

输出:

1
2
3
4
5
+-----------------+
| ConsecutiveNums |
+-----------------+
| 1 |
+-----------------+

3.查询每个部门下最高的值

输入:Employee表和Department表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Employee 表:
+----+-------+--------+--------------+
| id | name | salary | departmentId |
+----+-------+--------+--------------+
| 1 | Joe | 70000 | 1 |
| 2 | Jim | 90000 | 1 |
| 3 | Henry | 80000 | 2 |
| 4 | Sam | 60000 | 2 |
| 5 | Max | 90000 | 1 |
+----+-------+--------+--------------+
Department 表:
+----+-------+
| id | name |
+----+-------+
| 1 | IT |
| 2 | Sales |
+----+-------+

先用group by+max算出每个departmentId下最多的salary,然后用where+in来进行过滤

1
2
3
4
5
6
7
8
9
10
11
12
13
14
select t2.Name as Department,t1.Name as Employee,Salary  from (
(select Name, DepartmentId,Salary from Employee) t1
left join
(select Id,Name from Department) t2
on t1.DepartmentId = t2.Id
)
WHERE
(t2.Id,t1.Salary)
in
(
(select DepartmentId, MAX(Salary) from Employee
group by DepartmentId)
)

4.将分数转换成排名

输入:Scores表

1
2
3
4
5
6
7
8
9
10
+----+-------+
| id | score |
+----+-------+
| 1 | 3.50 |
| 2 | 3.65 |
| 3 | 4.00 |
| 4 | 3.85 |
| 5 | 4.00 |
| 6 | 3.65 |
+----+-------+
1
2
3
4
5
6
# t2表中有多少个大于t1当前score的
select Score,
(select count(distinct(Score)) from Scores t1 where t1.Score > t2.Score ) +1 as `Rank`
from Scores t2
order by Score DESC;

去重后的scores表中,比scores表的每一行大的有多少个

输出:

1
2
3
4
5
6
7
8
9
10
+-------+------+
| score | rank |
+-------+------+
| 4.00 | 1 |
| 4.00 | 1 |
| 3.85 | 2 |
| 3.65 | 3 |
| 3.65 | 3 |
| 3.50 | 4 |
+-------+------+

全文 >>

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点之间处理的事件,以此类推。

全文 >>

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

全文 >>

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