各省住房和城乡建设厅网站,xp花生壳做自己的网站,企业门户网站开发要多少钱,wordpress the_content()一、背景 在分布式系统中,一个应用部署在多台机器中,在某些场景下,为了保证数据的一致性,要求在同一时刻,同一任务只在一个节点上运行,即保证某个行为在同一时刻只能被一个线程执行。在单机单进程多线程环境下,通过锁很容易做到,比如 mutex、spinlock、信号量 等。在多…一、背景
在分布式系统中,一个应用部署在多台机器中,在某些场景下,为了保证数据的一致性,要求在同一时刻,同一任务只在一个节点上运行,即保证某个行为在同一时刻只能被一个线程执行。在单机单进程多线程环境下,通过锁很容易做到,比如 mutex、spinlock、信号量 等。在多机多进程环境下,就需要使用 分布式锁 来解决了。 分布式场景:我们的应用由多个节点构成,这些节点可能分布在不同的机器中,也有可能分布在不同的网络环境中,通常这些进程之间通过 socket 进行通信。 二、分布式锁
是什么类型的锁 ? 在分布式场景中实现互斥类型的锁。 互斥类型:同一时刻只允许一个执行体进入临界资源。 解决了什么问题 ? 在分布式场景中,同时只允许一个节点执行某类任务。 锁 = 资源 + 行为: 资源: 要记录进程的全局唯一 ID。放在 数据库、zookeeper 或 etcd 中,可以让所有的执行体访问。 行为:加锁、解锁。(以网络通信的方式) 加锁:把当前进程的唯一标识打到当前数据库的某一个字段中,作为一个标记,说明当前进程持有锁。 加锁的方式:原来没有标记,现在打上标记了。 解锁:谁加的锁,谁释放锁,也就是加锁对象和解锁对象必须是同一个对象,除了因为网络异常而造成的锁超时情况。 解锁的方式:持锁方去清除标记,比如置为 0,这样其他的进程才能去加锁。 三、分布式锁特性
互斥性。 锁打上标记:加锁。锁取消标记:解锁。标记:执行体的唯一标识,可以通过雪花算法生成。 锁超时。 在分布式场景中,允许一个进程退出,并希望其他的进程能够继续工作。当持有锁的进程想要解锁的时候,由于某些原因,比如进程宕机、网络异常,导致无法清除数据库中的标记,也就是持锁的进程没有能力去释放锁了,那么我们应该提供一种机制,让数据库自动地去释放锁 → 时间一到,数据库自动地释放锁。 可用性。 合理时间内得到合理的回复。实现: 计算型:开多个备份点。存储型: 多个备份点。主从切换。 容错性。 一致性来解决(半数以上)。 raft 一致性算法。redlock。 高可用 = 可用性 + 容错性。 四、分布式锁类型
重入锁和非重入锁。 重入锁: 允许同一个线程多次获取同一把锁,而不会导致死锁。当一个线程持有锁时,它可以再次获取相同的锁而不被阻塞。std::recursive_mutex。 非重入锁: 不允许同一个线程在持有锁的情况下再次获取相同的锁,会导致死锁。std::mutex。 公平锁和非公平锁。 公平锁:排队,对应互斥锁。非公平锁:轮询,对应自旋锁。 五、实现分布式锁
基于中间件来实现 → 所有的节点都能访问到。资源存储在中间件中。加锁、解锁行为基于中间件的特性来实现。MySQL 实现分布式锁
锁的存储:表。获取锁和释放锁:字段。互斥语义: 唯一性约束:unique key、primary key。利用 innodb 中的 S 锁和 X 锁互斥。select * from lock where ... lock in share mode;
update lock set ... where ...锁超时: 表增加一个字段:加锁时间戳。另起进程(超进程),定时检测是否超时。 其他进程怎么获取锁:主动探寻,实现定时器 → MySQL 只能实现非公平锁。递归锁:表中增加一个字段 count。创建表。DROP TABLE IF EXISTS `dislock`;
CREATE TABLE