// 选举服务
interface LeaderElectionService {
// 启动选举
start(LeaderContender)
// 停止选举
stop()
// 确认主权
confirmLeadership(..)
}
// 参选者
interface LeaderContender {
// 获取主权后回调
grantLeadership(..)
// 失去主权后回调
revokeLeadership()
// 选举异常回调
handleError(Exception)
}星期四, 一月 20, 2022
FLINK 选举机制
flink HA 有两种实现, ZooKeeper 和 Kubernetes, flink 对两者进行了封装, 定义如下
1. 中间层抽象
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
[Flink之主从选举] https://www.modb.pro/db/107324
Hibernate 一级缓存
- 一级缓存
hibernate 在应用层维护一个可重复读的持久上下文
在使用主键加载实体的时候,hibernate 首先在持久上下文中根据主键查询实体,如果存在则返回,不存在则请求数据库
在使用非主键加载实体的时候,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 断言失败 参考文献
[spring-boot-isolation-level-read-uncommitted-not-working] https://stackoverflow.com/questions/67443569/spring-boot-isolation-level-read-uncommitted-not-working
[use-of-hibernate-first-level-cache] https://stackoverflow.com/questions/39482861/use-of-hibernate-first-level-cache
[Hibernate_User_Guide] https://docs.jboss.org/hibernate/orm/5.4/userguide/html_single/Hibernate_User_Guide.html#architecture-overview
星期四, 八月 08, 2019
为什么使用 macOS
Why Mackintosh?
Why Hackintosh?
优势
My Current
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
- ffmpeg
brew install ffmpeg
新建一个系统服务
注: 脚本中包含 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
使用方法
参考
星期四, 十一月 12, 2015
Mac 转发 PS4 twitch 直播流量到第三方直播平台
Mac 设置
I. enable IP Forwarding
1. 开机启用
新建或编辑 /etc/sysctl.conf 文件
加入内容:
net.inet.ip.forwarding=1
加入内容:
net.inet.ip.forwarding=1
2. 现在启用
$ sudo sysctl -w net.inet.ip.forwarding=1
$ 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] 文件需要以空行结尾
在 rdr-anchor 下面新增一行
rdr-anchor "ps4"
load anchor "ps4" from "/etc/pf.anchors/ps4"
内容:
rdr pass on en0 inet proto tcp from any to 199.9.0.0/16 port 1935 -> 127.0.0.1 port 1935
启用 pf 规则
1. 现在启用
# 重新加载 pf 规则
$ sudo pfctl -f /etc/pf.conf
# 启用 pf
$ sudo pfctl -e
# 重新加载 pf 规则
$ sudo pfctl -f /etc/pf.conf
# 启用 pf
$ sudo pfctl -e
2. 开机启用
编辑 /System/Library/LaunchDaemons/com.apple.pfctl.plist 文件
在 pfctl 下面加入一行
<string>-e</string>
在 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
# 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://直播地址;
}
}
}
与 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
# Start process:
$ sudo nginx
# Reload config:
$ sudo nginx -s reload
# Stop process:
$ sudo nginx -s stop
PS4 设置
网关设为 Mac 的 ip 地址
星期二, 一月 20, 2015
[root]一条命令开启 Google Now & 位置报告
星期六, 四月 05, 2014
在 windows 上使用 Dvorak 键盘布局
第一种:修改输入法
1、英文输入法
美国英语-DVORAK2、中文输入法
KBDDV.DLL,然后注销电脑第二种:修改键盘映射
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





