星期四, 一月 20, 2022

FLINK 选举机制

 flink HA 有两种实现, ZooKeeper 和 Kubernetes, flink 对两者进行了封装, 定义如下

// 选举服务
interface LeaderElectionService {
    // 启动选举
    start(LeaderContender)
    // 停止选举
    stop()
    // 确认主权
    confirmLeadership(..)
}
// 参选者
interface LeaderContender {
    // 获取主权后回调
    grantLeadership(..)
    // 失去主权后回调
    revokeLeadership()
    // 选举异常回调
    handleError(Exception)
}

1. 中间层抽象

LeaderElectionService 默认实现类是 DefaultLeaderElectionService, 通过创建 LeaderElectionDriver 进行选举, 选举成功后回调 LeaderElectionEventHandler, 失败后回调 FatalErrorHandler, 这两个 Handler 内部调用 LeaderContender 的方法

2. ZooKeeper 实现

LeaderElectionDriver 的 ZooKeeper 实现是 ZooKeeperLeaderElectionDriver, 内部使用 Curator 框架提供的 LeaderLatch 和 NodeCache 机制实现选举,

 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
public ZooKeeperLeaderElectionDriver(..) {
    // 选举成功, 回调 isLeader, 否则回调 notLeader
    leaderLatch = new LeaderLatch(client, checkNotNull(latchPath));
    // 监听变化, 回调 nodeChanged
    cache = new NodeCache(client, leaderPath);
    // 选举异常, 回调 unhandledError
    client.getUnhandledErrorListenable().addListener(this);

    leaderLatch.addListener(this);
    leaderLatch.start();

    cache.getListenable().addListener(this);
    cache.start();
}

public void isLeader() {
    leaderElectionEventHandler.onGrantLeadership();
}

public void notLeader() {
    leaderElectionEventHandler.onRevokeLeadership();
}

public void unhandledError(String message, Throwable e) {
    fatalErrorHandler.onFatalError(..);
}

References

Hibernate 一级缓存

一级缓存

hibernate 在应用层维护一个可重复读的持久上下文

  1. 在使用主键加载实体的时候,hibernate 首先在持久上下文中根据主键查询实体,如果存在则返回,不存在则请求数据库

  2. 在使用非主键加载实体的时候,hibernate 请求数据库,首先从结果集中解析出实体的主键,然后在持久上下文中根据主键查询实体,如果存在则返回,不存在则继续解析剩余部分

1. 例子

1.1. findById

1
2
3
4
5
6
7
8
@Test
@Transactional
void l1CacheTest() {
    // query
    employeeRepository.findById(10001); 1
    // no query
    employeeRepository.findById(10001); 2
}
1第一次执行 SQL
2第二次不执行 SQL

1.2. not findById

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
@Override
@Transactional(isolation = Isolation.READ_UNCOMMITTED) 1
public void readUncommitted() {
    Optional<User> firstReadUser = userRepository.findFirstByUsername("admin");
    String firstReadPassword = firstReadUser.map(User::getPassword).get(); 2
    log.info("first read user admin password is {}", firstReadPassword);
    // debug point below
    // entityManager.clear(); 3
    Optional<User> secondReadUser = userRepository.findFirstByUsername("admin"); 2
    String secondReadPassword = secondReadUser.map(User::getPassword).get();
    log.info("second read user admin password is {}", secondReadPassword);
    assertNotEquals(firstReadPassword, secondReadPassword); 4
}
1设置事务隔离级别为可重复读
2两次都执行 SQL
3在第一次查询后开启另一个事务,修改数据
4断言失败

参考文献

星期四, 八月 08, 2019

为什么使用 macOS

Why Mackintosh?

菜单栏统一,所有应用的菜单都在屏幕顶端,并且菜单可搜索
​

​
任意应用可卸载,rm -rf 从来没让我失望过,不会出现文件在使用中无法删除的问题
没有中间弹窗广告、右下角广告,来抢夺用户注意力,打断思路,影响工作效率
实时保存,大部分应用都支持实时保存,还有TimeMachine,可恢复任意文件
不需要频繁重启,windows各种更新动不动就要重启,windows重启后应用就全部关闭了,MacOS
系统重新启动(包括意外关机再开机、重装)后可以还原到原有的工作状态
系统重装只会替换系统文件(抹盘除外),个人资料不会丢失,和重装前一模一样

Why Hackintosh?

优势

硬盘和内存容易扩容,更多的USB接口,更好的散热

My Current

MacBook Pro (15-inch Mid 2015)
Hackintosh(z390-i7-9700k)


星期日, 五月 01, 2016

使用 ffmpeg 合并 bilibili for mac 下载的分段视频

效果

下载的分段视频:
合并后:

原理

使用ffmpeg转换flv到mp4

ffmpeg -i out.flv -vcodec copy -acodec copy out.mp4

使用ffmpeg合并MP4文件

ffmpeg -i "Apache Sqoop Tutorial Part 1.mp4" -c copy -bsf:v h264_mp4toannexb -f mpegts intermediate1.ts
ffmpeg -i "Apache Sqoop Tutorial Part 2.mp4" -c copy -bsf:v h264_mp4toannexb -f mpegts intermediate2.ts
ffmpeg -i "Apache Sqoop Tutorial Part 3.mp4" -c copy -bsf:v h264_mp4toannexb -f mpegts intermediate3.ts
ffmpeg -i "Apache Sqoop Tutorial Part 4.mp4" -c copy -bsf:v h264_mp4toannexb -f mpegts intermediate4.ts
ffmpeg -i "concat:intermediate1.ts|intermediate2.ts|intermediate3.ts|intermediate4.ts" -c copy -bsf:a aac_adtstoasc "Apache Sqoop Tutorial.mp4"
然后写个脚本调用就行了,我是用 Automator 建了个服务

工具

  • Automator
  • ffmpeg
brew install ffmpeg

新建一个系统服务

使用 Automator 新建一个服务:文件➜新建➜服务,我这里命名为"flv合并为mp4"
添加「过滤 Finder 项目」「给 Finder 项目排序」「运行 Shell 脚本」组件
按图配置就行了,其中 Shell 脚本如下:
注: 脚本中包含 rm 方法,会将视频源文件和临时文件删除
for f in "$@"
do
 concat_file+="${f%.*}.ts"\|
 /usr/local/bin/ffmpeg -i "$f" -vcodec copy -acodec copy -c copy -bsf:v h264_mp4toannexb -f mpegts "${f%.*}.ts"
done

/usr/local/bin/ffmpeg -i "concat:${concat_file%|*}" -c copy -bsf:a aac_adtstoasc "${f%-*}.mp4"

for f in "$@"
do
 rm "${f%.*}.flv"
 rm "${f%.*}.ts"
done

exit 0

使用方法

选中 所有 分段的视频,右键➜服务➜flv合并为mp4

参考

星期四, 十一月 12, 2015

Mac 转发 PS4 twitch 直播流量到第三方直播平台

Mac 设置

I. enable IP Forwarding

1. 开机启用

新建或编辑 /etc/sysctl.conf 文件
加入内容:
net.inet.ip.forwarding=1

2. 现在启用

$ sudo sysctl -w net.inet.ip.forwarding=1  

II. set Traffic Redirection (Port Forwarding)

编辑 pf 配置文件

编辑 /etc/pf.conf 文件[^1]
在 rdr-anchor 下面新增一行
rdr-anchor "ps4"
在 load anchor 下面新增一行
load anchor "ps4" from "/etc/pf.anchors/ps4"
新建 /etc/pf.anchors/ps4 文件[^1]
内容:
rdr pass on en0 inet proto tcp from any to 199.9.0.0/16 port 1935 -> 127.0.0.1 port 1935
[^1] 文件需要以空行结尾

启用 pf 规则

1. 现在启用

# 重新加载 pf 规则
$ sudo pfctl -f /etc/pf.conf

# 启用 pf
$ sudo pfctl -e

2. 开机启用

编辑 /System/Library/LaunchDaemons/com.apple.pfctl.plist 文件
在 pfctl 下面加入一行
<string>-e</string>

III. set nginx rtmp server

安装 nginx

# http://brew.sh/homebrew-nginx/
$ brew tap homebrew/nginx
$ brew install nginx-full --with-rtmp-module

配置 nginx

编辑 /usr/local/etc/nginx/nginx.conf 文件
与 http 同级,加入
rtmp {
    server {
        listen 1935;
        chunk_size 131072;
        max_message 256M;
        application app {
            live on;
            record off;
            meta copy;
            push rtmp://直播地址;
        }
    }
}

开启 nginx

# Start process:
$ sudo nginx

# Reload config:
$ sudo nginx -s reload

# Stop process:
$ sudo nginx -s stop

PS4 设置

网关设为 Mac 的 ip 地址

星期二, 一月 20, 2015

[root]一条命令开启 Google Now & 位置报告

使用 root 权限运行以下命令(重启后失效)
setprop gsm.sim.operator.alpha "AT&T" && 
setprop gsm.sim.operator.iso-country "us" && 
setprop gsm.sim.operator.numeric "310090"
一段时间(几小时)后 Google Now 就能打开了
理论上位置报告也能开启,可能是 sim 卡没插吧
  

星期六, 四月 05, 2014

在 windows 上使用 Dvorak 键盘布局

第一种:修改输入法

1、英文输入法

控制面板 - 更换输入法,添加 美国英语-DVORAK

2、中文输入法

注册表定位到
HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Keyboard Layouts\00000804
修改 Layout File 的值为 KBDDV.DLL,然后注销电脑
说明:00000804 表示 Chinese (Simplified) - US Keyboard

第二种:修改键盘映射

先把下面的文字另存为 qwerty.reg,留着备用。
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout]
"ScanCode Map"=hex:00,00,00,00,00,00,00,00,01,00,00,00,00,00,00,00
把下面的文字另存为 dvorak.reg 文件,双击导入注册表,注销后生效。
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout]
"ScanCode Map"=hex:00,00,00,00,00,00,00,00,22,00,00,00,2d,00,30,00,24,00,2e,00,\
11,00,33,00,33,00,11,00,12,00,20,00,34,00,12,00,1b,00,0d,00,0d,00,1b,00,16,\
00,21,00,17,00,22,00,20,00,23,00,1a,00,0c,00,2e,00,17,00,23,00,24,00,14,00,\
25,00,31,00,26,00,35,00,1a,00,30,00,31,00,13,00,18,00,26,00,19,00,2f,00,34,\
00,28,00,10,00,0c,00,28,00,19,00,13,00,18,00,1f,00,1f,00,27,00,2c,00,35,00,\
15,00,14,00,22,00,16,00,25,00,2f,00,10,00,2d,00,21,00,15,00,27,00,2c,00,00,\
00,00,00