Linux
链接
链接文件:一个可以“通向”其他文件的文件。
分为 软链接 和 硬链接。
软链接:类似 Windows 的快捷方式,不是一个实质的文件,当链接的文件被销毁后,也就失去作用了
硬链接:直接和 另一个文件 通向 相同的内存,和链接的文件共享文件内容,这边修改了那边也会跟着变
和 Docker 的 Volume 有点像
命令:ln -s <linked> <link>
s: symbolic 符号,表示创建软链接(符号链接)
如 ln b.txt a.txt:创建 a 对 b 的硬链接。
注意:硬链接不能指向目录,因为目录只是一个层级,不是文件,无法让你修改。
vi编辑器
打开方式:vi <file>
如果文件不存在则会创建新文件。
vim编辑器中分为三种状态
- 命令模式,按下按键不会输入字符,而是执行命令。
- 输入模式,可以插入字符
- 底线命令模式,在界面最低端,输入命令执行相应操作
命令模式常用
- i、a、o,分别是在光标当前、随后、下一行进入输入模式,可以输入字符
- u,复原操作
- dd,删除这一行
:
,切换到底线命令模式
输入模式常用
- ctrl + u,撤回操作
底线命令模式
- q 退出
- q!强制退出,加一个!表示强制的意思
- w 保存
- wq 保存退出
- !暂时离开进入terminal查看信息
- set nu 显示行号
- set nonu 取消显示行号
分布式锁
在集群部署的情况下,保证某个操作只能单线程执行。
实现方式
- MySQL 本身的互斥锁机制(还没学)
- Redis setnx 互斥命令
- zookeeper 唯一有序节点
定义 Lock 接口
boolean tryLock(long timeSec)
尝试获取锁,并设置过期时间,防止服务宕机造成死锁MySQL 断连会自动释放,zookeeper 是临时节点
void unlock()
防止误删
如果某次操作执行非常慢或者被阻塞了,导致他获取的锁被过期释放了,此时其他线程获取到了新的锁,但由于锁的 key 都是一致的,最后这个被阻塞的操作完成后会误删了其他线程的锁。
一、给锁加上标识
为了误删其他线程的锁,需要再释放之前,判断这把锁是否是为当前线程的锁。
利用 UUID + 线程id 生成不同服务器不同的标识
如果只用id的话,由于这个id是顺序生成的,不同服务器之间会冲突。
二、原子性
既然出现了判断,就会有数据不一致的并发问题。
如果因为 JVM 的 GC 垃圾回收等机制造成了阻塞,导致在判断完之后锁又过期的情况下,又会误删其他线程的锁。
因此,需要保证 判断 和 释放 两个操作的原子性。
这里采用脱离 JVM,让 Redis 执行 lua 脚本的方法。
实现步骤:
- 编写 lua 脚本
- 借助 StringRedisTemplate 的 execute 方法执行脚本
Redis 会不会产生数据不一致的问题,在查询到标识之后被其他线程改了?多线程?
Redis 在 5 版本之前都是单线程的,而且事务保证了原子性。