如果再有人问你分布式锁,这篇文章扔给他

关于mos管的压降问题(项目遇到问题总结) 在研发过程中没有出现问题的板子,到了小批时竟出现雷达一直在触发???找了大几天,没有头绪。心中疑惑颇多,加上老板催促,自考等原因,真是压力山大。4月份自考,只有差不多一个月时间了吧,没有什么大的收获,反而在查找硬件问题的过程中,发现了一个自己忽视的一个问题,就是关于Mos管的压降问题。 备考的过程崎岖不平,工作又问题多多,孰轻孰重,如何取舍?从心理来说,不想取舍什么,只是有所得就可以,过不了就过不了呗,已经毕业十五年了,没这个本科文凭不也过来了吗?只是代表了自己在这一段时间的思考,自己兴趣吧,没什么大不了 阅读详情

1.背景

对于锁大家肯定不会陌生,在Java中synchronized关键字和ReentrantLock可重入锁在我们的代码中是经常见的,一般我们用其在多线程环境中控制对资源的并发访问,但是随着分布式的快速发展,本地的加锁往往不能满足我们的需要,在我们的分布式环境中上面加锁的方法就会失去作用。于是人们为了在分布式环境中也能实现本地锁的效果,也是纷纷各出其招,今天让我们来聊一聊一般分布式锁实现的套路。

2.分布式锁

2.1为何需要分布式锁

Martin Kleppmann是英国剑桥大学的分布式系统的研究员,之前和Redis之父Antirez进行过关于RedLock(红锁,后续有讲到)是否安全的激烈讨论。Martin认为一般我们使用分布式锁有两个场景:

效率:使用分布式锁可以避免不同节点重复相同的工作,这些工作会浪费资源。比如用户付了钱之后有可能不同节点会发出多封短信。

正确性:加分布式锁同样可以避免破坏正确性的发生,如果两个节点在同一条数据上面操作,比如多个节点机器对同一个订单操作不同的流程有可能会导致该笔订单最后状态出现错误,造成损失。

2.2分布式锁的一些特点

当我们确定了在不同节点上需要分布式锁,那么我们需要了解分布式锁到底应该有哪些特点:

互斥性:和我们本地锁一样互斥性是最基本,但是分布式锁需要保证在不同节点的不同线程的互斥。

可重入性:同一个节点上的同一个线程如果获取了锁之后那么也可以再次获取这个锁。

锁超时:和本地锁一样支持锁超时,防止死锁。

高效,高可用:加锁和解锁需要高效,同时也需要保证高可用防止分布式锁失效,可以增加降级。

支持阻塞和非阻塞:和ReentrantLock一样支持lock和trylock以及tryLock(long timeOut)。

支持公平锁和非公平锁(可选):公平锁的意思是按照请求加锁的顺序获得锁,非公平锁就相反是无序的。这个一般来说实现的比较少。

2.3常见的分布式锁

我们了解了一些特点之后,我们一般实现分布式锁有以下几个方式:

MySql
Zk
Redis

自研分布式锁:如谷歌的Chubby。

下面分开介绍一下这些分布式锁的实现原理。

3Mysql分布式锁

首先来说一下Mysql分布式锁的实现原理,相对来说这个比较容易理解,毕竟数据库和我们开发人员在平时的开发中息息相关。对于分布式锁我们可以创建一个锁表:

前面我们所说的lock(),trylock(long timeout),trylock()这几个方法可以用下面的伪代码实现。

3.1 lock()

lock一般是阻塞式的获取锁,意思就是不获取到锁誓不罢休,那么我们可以写一个死循环来执行其操作: 在这里插入图片描述
mysqlLock.lcok内部是一个sql,为了达到可重入锁的效果那么我们应该先进行查询,如果有值,那么需要比较node_info是否一致,这里的node_info可以用机器IP和线程名字来表示,如果一致那么就加可重入锁count的值,如果不一致那么就返回false。如果没有值那么直接插入一条数据。伪代码如下: 在这里插入图片描述
需要注意的是这一段代码需要加事务,必须要保证这一系列操作的原子性。

3.2tryLock()和tryLock(long timeout)

tryLock()是非阻塞获取锁,如果获取不到那么就会马上返回,代码可以如下:
在这里插入图片描述
tryLock(long timeout)实现如下: 在这里插入图片描述
mysqlLock.lock和上面一样,但是要注意的是select … for update这个是阻塞的获取行锁,如果同一个资源并发量较大还是有可能会退化成阻塞的获取锁。

3.3 unlock()

unlock的话如果这里的count为1那么可以删除,如果大于1那么需要减去1。在这里插入图片描述
3.4 锁超时

我们有可能会遇到我们的机器节点挂了,那么这个锁就不会得到释放,我们可以启动一个定时任务,通过计算一般我们处理任务的一般的时间,比如是5ms,那么我们可以稍微扩大一点,当这个锁超过20ms没有被释放我们就可以认定是节点挂了然后将其直接释放。

3.5 Mysql小结

适用场景: Mysql分布式锁一般适用于资源不存在数据库,如果数据库存在比如订单,那么可以直接对这条数据加行锁,不需要我们上面多的繁琐的步骤,比如一个订单,那么我们可以用select * from order_table where id = ‘xxx’ for update进行加行锁,那么其他的事务就不能对其进行修改。

优点:理解起来简单,不需要维护额外的第三方中间件(比如Redis,Zk)。

缺点:虽然容易理解但是实现起来较为繁琐,需要自己考虑锁超时,加事务等等。性能局限于数据库,一般对比缓存来说性能较低。对于高并发的场景并不是很适合。

3.6 乐观锁

前面我们介绍的都是悲观锁,这里想额外提一下乐观锁,在我们实际项目中也是经常实现乐观锁,因为我们加行锁的性能消耗比较大,通常我们会对于一些竞争不是那么激烈,但是其又需要保证我们并发的顺序执行使用乐观锁进行处理,我们可以对我们的表加一个版本号字段,那么我们查询出来一个版本号之后,update或者delete的时候需要依赖我们查询出来的版本号,判断当前数据库和查询出来的版本号是否相等,如果相等那么就可以执行,如果不等那么就不能执行。这样的一个策略很像我们的CAS(Compare And Swap),比较并交换是一个原子操作。这样我们就能避免加select * for update行锁的开销。

4. ZooKeeper

ZooKeeper也是我们常见的实现分布式锁方法,相比于数据库如果没了解过ZooKeeper可能上手比较难一些。ZooKeeper是以Paxos算法为基础分布式应用程序协调服务。Zk的数据节点和文件目录类似,所以我们可以用此特性实现分布式锁。我们以某个资源为目录,然后这个目录下面的节点就是我们需要获取锁的客户端,未获取到锁的客户端注册需要注册Watcher到上一个客户端,可以用下图表示。在这里插入图片描述
/lock是我们用于加锁的目录,/resource_name是我们锁定的资源,其下面的节点按照我们加锁的顺序排列。

4.1Curator
Curator封装了Zookeeper底层的Api,使我们更加容易方便的对Zookeeper进行操作,并且它封装了分布式锁的功能,这样我们就不需要再自己实现了。

Curator实现了可重入锁(InterProcessMutex),也实现了不可重入锁(InterProcessSemaphoreMutex)。在可重入锁中还实现了读写锁。

4.2InterProcessMutex
InterProcessMutex是Curator实现的可重入锁,我们可以通过下面的一段代码实现我们的可重入锁:在这里插入图片描述
我们利用acuire进行加锁,release进行解锁。

加锁的流程具体如下:

1,首先进行可重入的判定:这里的可重入锁记录在ConcurrentMap<Thread, LockData> threadData这个Map里面,如果threadData.get(currentThread)是有值的那么就证明是可重入锁,然后记录就会加1。我们之前的Mysql其实也可以通过这种方法去优化,可以不需要count字段的值,将这个维护在本地可以提高性能。

2,然后在我们的资源目录下创建一个节点:比如这里创建一个/0000000002这个节点,这个节点需要设置为EPHEMERAL_SEQUENTIAL也就是临时节点并且有序。

3,获取当前目录下所有子节点,判断自己的节点是否位于子节点第一个。

4,如果是第一个,则获取到锁,那么可以返回。

5,如果不是第一个,则证明前面已经有人获取到锁了,那么需要获取自己节点的前一个节点。/0000000002的前一个节点是/0000000001,我们获取到这个节点之后,再上面注册Watcher(这里的watcher其实调用的是object.notifyAll(),用来解除阻塞)。

6,object.wait(timeout)或object.wait():进行阻塞等待这里和我们第5步的watcher相对应。

解锁的具体流程:

1,首先进行可重入锁的判定:如果有可重入锁只需要次数减1即可,减1之后加锁次数为0的话继续下面步骤,不为0直接返回。

2,删除当前节点。

3,删除threadDataMap里面的可重入锁的数据。

4.3读写锁

Curator提供了读写锁,其实现类是InterProcessReadWriteLock,这里的每个节点都会加上前缀:

private static final String READ_LOCK_NAME  = "__READ__";
private static final String WRITE_LOCK_NAME = "__WRIT__";

根据不同的前缀区分是读锁还是写锁,对于读锁,如果发现前面有写锁,那么需要将watcher注册到和自己最近的写锁。写锁的逻辑和我们之前4.2分析的依然保持不变。

4.4锁超时

Zookeeper不需要配置锁超时,由于我们设置节点是临时节点,我们的每个机器维护着一个ZK的session,通过这个session,ZK可以判断机器是否宕机。如果我们的机器挂掉的话,那么这个临时节点对应的就会被删除,所以我们不需要关心锁超时。

4.5 ZK小结

优点:ZK可以不需要关心锁超时时间,实现起来有现成的第三方包,比较方便,并且支持读写锁,ZK获取锁会按照加锁的顺序,所以其是公平锁。对于高可用利用ZK集群进行保证。

缺点:ZK需要额外维护,增加维护成本,性能和Mysql相差不大,依然比较差。并且需要开发人员了解ZK是什么。

5.Redis

大家在网上搜索分布式锁,恐怕最多的实现就是Redis了,Redis因为其性能好,实现起来简单所以让很多人都对其十分青睐。

5.1Redis分布式锁简单实现

熟悉Redis的同学那么肯定对setNx(set if not exist)方法不陌生,如果不存在则更新,其可以很好的用来实现我们的分布式锁。对于某个资源加锁我们只需要

setNx resourceName value

这里有个问题,加锁了之后如果机器宕机那么这个锁就不会得到释放所以会加入过期时间,加入过期时间需要和setNx同一个原子操作,在Redis2.8之前我们需要使用Lua脚本达到我们的目的,但是redis2.8之后redis支持nx和ex操作是同一原子操作。

set resourceName value ex 5 nx

5.2Redission

Javaer都知道Jedis,Jedis是Redis的Java实现的客户端,其API提供了比较全面的Redis命令的支持。Redission也是Redis的客户端,相比于Jedis功能简单。Jedis简单使用阻塞的I/O和redis交互,Redission通过Netty支持非阻塞I/O。Jedis最新版本2.9.0是2016年的快3年了没有更新,而Redission最新版本是2018.10月更新。

Redission封装了锁的实现,其继承了java.util.concurrent.locks.Lock的接口,让我们像操作我们的本地Lock一样去操作Redission的Lock,下面介绍一下其如何实现分布式锁。在这里插入图片描述
Redission不仅提供了Java自带的一些方法(lock,tryLock),还提供了异步加锁,对于异步编程更加方便。 由于内部源码较多,就不贴源码了,这里用文字叙述来分析他是如何加锁的,这里分析一下tryLock方法:

1,尝试加锁:首先会尝试进行加锁,由于保证操作是原子性,那么就只能使用lua脚本,相关的lua脚本如下: 可以看见他并没有使用我们的sexNx来进行操作,而是使用的hash结构,我们的每一个需要锁定的资源都可以看做是一个HashMap,锁定资源的节点信息是Key,锁定次数是value。通过这种方式可以很好的实现可重入的效果,只需要对value进行加1操作,就能进行可重入锁。当然这里也可以用之前我们说的本地计数进行优化。

2,如果尝试加锁失败,判断是否超时,如果超时则返回false。

3,如果加锁失败之后,没有超时,那么需要在名字为redisson_lock__channel+lockName的channel上进行订阅,用于订阅解锁消息,然后一直阻塞直到超时,或者有解锁消息。

4,重试步骤1,2,3,直到最后获取到锁,或者某一步获取锁超时。

对于我们的unlock方法比较简单也是通过lua脚本进行解锁,如果是可重入锁,只是减1。如果是非加锁线程解锁,那么解锁失败。

Redission还有公平锁的实现,对于公平锁其利用了list结构和hashset结构分别用来保存我们排队的节点,和我们节点的过期时间,用这两个数据结构帮助我们实现公平锁,这里就不展开介绍了,有兴趣可以参考源码。

5.3RedLock

我们想象一个这样的场景当机器A申请到一把锁之后,如果Redis主宕机了,这个时候从机并没有同步到这一把锁,那么机器B再次申请的时候就会再次申请到这把锁,为了解决这个问题Redis作者提出了RedLock红锁的算法,在Redission中也对RedLock进行了实现。

通过上面的代码,我们需要实现多个Redis集群,然后进行红锁的加锁,解锁。具体的步骤如下:

1,首先生成多个Redis集群的Rlock,并将其构造成RedLock。
2,依次循环对三个集群进行加锁,加锁的过程和5.2里面一致。
3,如果循环加锁的过程中加锁失败,那么需要判断加锁失败的次数是否超出了最大值,这里的最大值是根据集群的个数,比如三个那么只允许失败一个,五个的话只允许失败两个,要保证多数成功。
4,加锁的过程中需要判断是否加锁超时,有可能我们设置加锁只能用3ms,第一个集群加锁已经消耗了3ms了。那么也算加锁失败。
5,3,4步里面加锁失败的话,那么就会进行解锁操作,解锁会对所有的集群在请求一次解锁。
可以看见RedLock基本原理是利用多个Redis集群,用多数的集群加锁成功,减少Redis某个集群出故障,造成分布式锁出现问题的概率。

5.4 Redis小结

优点:对于Redis实现简单,性能对比ZK和Mysql较好。如果不需要特别复杂的要求,那么自己就可以利用setNx进行实现,如果自己需要复杂的需求的话那么可以利用或者借鉴Redission。对于一些要求比较严格的场景来说的话可以使用RedLock。
缺点:需要维护Redis集群,如果要实现RedLock那么需要维护更多的集群。

6.分布式锁的安全问题

上面我们介绍过红锁,但是Martin Kleppmann认为其依然不安全。有关于Martin反驳的几点,我认为其实不仅仅局限于RedLock,前面说的算法基本都有这个问题,下面我们来讨论一下这些问题:

长时间的GC pause:熟悉Java的同学肯定对GC不陌生,在GC的时候会发生STW(stop-the-world),例如CMS垃圾回收器,他会有两个阶段进行STW防止引用继续进行变化。那么有可能会出现下面图(引用至Martin反驳Redlock的文章)中这个情况: client1获取了锁并且设置了锁的超时时间,但是client1之后出现了STW,这个STW时间比较长,导致分布式锁进行了释放,client2获取到了锁,这个时候client1恢复了锁,那么就会出现client1,2同时获取到锁,这个时候分布式锁不安全问题就出现了。这个其实不仅仅局限于RedLock,对于我们的ZK,Mysql一样的有同样的问题。

时钟发生跳跃:对于Redis服务器如果其时间发生了向跳跃,那么肯定会影响我们锁的过期时间,那么我们的锁过期时间就不是我们预期的了,也会出现client1和client2获取到同一把锁,那么也会出现不安全,这个对于Mysql也会出现。但是ZK由于没有设置过期时间,那么发生跳跃也不会受影响。

长时间的网络I/O:这个问题和我们的GC的STW很像,也就是我们这个获取了锁之后我们进行网络调用,其调用时间由可能比我们锁的过期时间都还长,那么也会出现不安全的问题,这个Mysql也会有,ZK也不会出现这个问题。

对于这三个问题,在网上包括Redis作者在内发起了很多讨论。

6.1 GC的STW

对于这个问题可以看见基本所有的都会出现问题,Martin给出了一个解法,对于ZK这种他会生成一个自增的序列,那么我们真正进行对资源操作的时候,需要判断当前序列是否是最新,有点类似于我们乐观锁。当然这个解法Redis作者进行了反驳,你既然都能生成一个自增的序列了那么你完全不需要加锁了,也就是可以按照类似于Mysql乐观锁的解法去做。

我自己认为这种解法增加了复杂性,当我们对资源操作的时候需要增加判断序列号是否是最新,无论用什么判断方法都会增加复杂度,后面会介绍谷歌的Chubby提出了一个更好的方案。

6.2 时钟发生跳跃

Martin觉得RedLock不安全很大的原因也是因为时钟的跳跃,因为锁过期强依赖于时间,但是ZK不需要依赖时间,依赖每个节点的Session。Redis作者也给出了解答:对于时间跳跃分为人为调整和NTP自动调整。

人为调整:人为调整影响的那么完全可以人为不调整,这个是处于可控的。
NTP自动调整:这个可以通过一定的优化,把跳跃时间控制的可控范围内,虽然会跳跃,但是是完全可以接受的。

6.3长时间的网络I/O

这一块不是他们讨论的重点,我自己觉得,对于这个问题的优化可以控制网络调用的超时时间,把所有网络调用的超时时间相加,那么我们锁过期时间其实应该大于这个时间,当然也可以通过优化网络调用比如串行改成并行,异步化等。可以参考我的两个文章: 并行化-你的高并发大杀器,异步化-你的高并发大杀器

7.Chubby的一些优化

大家搜索ZK的时候,会发现他们都写了ZK是Chubby的开源实现,Chubby内部工作原理和ZK类似。但是Chubby的定位是分布式锁和ZK有点不同。Chubby也是使用上面自增序列的方案用来解决分布式不安全的问题,但是他提供了多种校验方法:

CheckSequencer():调用Chubby的API检查此时这个序列号是否有效。
访问资源服务器检查,判断当前资源服务器最新的序列号和我们的序列号的大小。
lock-delay:为了防止我们校验的逻辑入侵我们的资源服务器,其提供了一种方法当客户端失联的时候,并不会立即释放锁,而是在一定的时间内(默认1min)阻止其他客户端拿去这个锁,那么也就是给予了一定的buffer等待STW恢复,而我们的GC的STW时间如果比1min还长那么你应该检查你的程序,而不是怀疑你的分布式锁了。

8.小结

本文主要讲了多种分布式锁的实现方法,以及他们的一些优缺点。最后也说了一下有关于分布式锁的安全的问题,对于不同的业务需要的安全程度完全不同,我们需要根据自己的业务场景,通过不同的维度分析,选取最适合自己的方案。

lammps蒙特卡洛MC模拟案例 在lammps中,和MC相关的模拟命令有三个:fix gcmc、fix atom/swap、fix sgcmc。在一个lammps模拟中,mc和md可同时存在,间隔运行,所以设置fix sgcmc命令的同时,可以同时设置系综(nve、nvt或者npt)。lammps官网自带案例中也有一个fix sgcmc的案例,主要模拟FeCu合金的MC建模。sgcmc命令可应用到合金的模拟中,如短程有序模拟。MC运行间隔为100步,最终的浓度比例为0.02,也就是2%的Fe原子交换为Cu原子。大家好,我是小马老师。 阅读详情

相关推荐

告别Windows!Oculus Quest 2在Mac M1上的串流实战(scrcpy+SideQuest避坑指南)

本文为Mac M1用户提供了Oculus Quest 2在macOS上实现高清低延迟串流的实战指南。通过使用开源工具scrcpy和SideQuest,绕开官方限制,详细讲解了从环境准备、无线调试到画质与延迟优化的完整步骤,重点解决了Apple Silicon芯片Mac的连接与性能问题,助你告别Windows依赖。

weixin_29224309的博客 308

分布式锁(MySQL、redis、zookeeper)

为什么需要分布式锁,分布式锁如何实现?分布式锁原理,zookeeper、redis、mysql三者实现分布式锁的区别

qq_44896374的博客 506

SAP LSMW数据批导操作手册及跨客户端传输方法(涉及默认值配置,及多余字段如何删除)

SAP LSMW数据批导操作手册及跨客户端传输方法

我好像病了的博客 6087

MySQL、Redis 和 Zookeeper 实现分布式锁方法及优缺点

MySQL、Redis 和 Zookeeper 都可以用来实现分布式锁,每种技术都有其特定的实现方法以及各自的优缺点。

weixin_73922932的博客 1975

Codex入门19-数据库操作(解放双手:用自然语言写SQL、建表和数据迁移)

写 SQL 是后端开发的日常,但复杂的 JOIN、子查询、窗口函数总让人头疼。本文教你用 Codex CLI 实现:自然语言直接生成 CREATE TABLE、复杂 SQL 查询、数据库迁移脚本(Prisma/Knex/Alembic)、ORM 模型代码(SQLAlchemy/TypeORM)、甚至自动生成数据库文档。重点强调安全红线——永远不要让 AI 直接连接生产数据库。从需求描述到完整数据库层代码,一篇搞定。

yueyeguzhuo的专栏 234

uniapp - 解决 uni.chooseImage 在苹果 IOS 真机上点击没反应的问题,苹果手机点击 uni.chooseImage方法不生效,也不报任何错误(解决苹果ios系统点击无效问题)

uniapp小程序h5网页苹果ios系统点击uni.chooseImage不执行点击无效,uniapp使用uni.chooseImage方法点击没反应怎么办,uniappuni.chooseImage在ios苹果手机运行点击不触发,uniappuni.chooseImage苹果ios系统点击无效,uniapp项目ios端云打包之后uni.chooseImage不生效了,uniapp打包之后uni.chooseImage()无法打开相机,uniapp苹果手机无法打开相机和相册,uniapp网页h5微信支

🏆 前端领域优质创作者 1万+

mysql事务的优点和缺点_分布式锁优缺点 mysql zk redis

Mysql小结适用场景: Mysql分布式锁一般适用于资源不存在数据库,如果数据库存在比如订单,那么可以直接对这条数据加行锁,不需要我们上面多的繁琐的步骤,比如一个订单,那么我们可以用select * from order_table where id = 'xxx' for update进行加行锁,那么其他的事务就不能对其进行修改。优点:理解起来简单,不需要维护额外的第三方中间件(比如Redis...

weixin_28687251的博客 1093

知识图谱-构建:知识图谱构建流程【本体构建、知识抽取(实体抽取、 关系抽取、属性抽取)、知识表示、知识融合、知识存储】

旅游领域的类是用来描述旅游的抽象化概念术语,是对众多旅游个体共性的概念化描述。术语是划分类的基础,根据构建领域本体的目标和具体需要,可以确定哪些术语能作为领域本体的类。在以上抽取的众多旅游领域术语中,有些是能直接作为类的,如旅游、人物、交通方式、景区等等,而有些则不能作为类,如票价、景区门票、联系方式等等,它们只是属性。“旅游”很明显是最顶层的类,是父类。然后,要确定旅游的子类,根据大众标签里体现的共性和《中国分类主题词表》确定了旅游领域的11个核心概念,即本体层次结构图数据属性(固有属性)...

u013250861的博客 4万+

分布式锁原理及实现

目录前言概念什么是锁?什么是分布式?分布式与单机场景什么是分布式锁?场景为什么要使用分布式锁分布式锁应该具备的条件基于数据库的实现方式基于数据库表唯一约束基于表字段版本号做分布式锁基于数据库排他锁做分布式锁基于redis的实现方式基于ZooKeeper的实现方式总结 前言 分布式锁,是控制分布式系统之间同步访问共享资源的一种方式 在分布式系统中,常常需要协调他们的动作。如果不同的系统或是同一个系统的不同主机之间共享了一个或一组资源,那么访问这些资源的时候,往往需要互斥来防止彼此干扰来保证一致性,在这种情况下

7me 1万+

【2026年华为暑期实习(AI)-4月29日-第一题- 选择题】(题目+思路+Java&C++&Python解析+在线测试)

本文摘要涵盖了机器学习和深度学习中的多个核心概念与技术,包括非负矩阵分解、条件数、MobileNet创新点、LDA降维、大模型评测指标、半精度训练、多任务学习、GPU存储层次、正则化、张量并行等。通过12道单选题和8道多选题的形式,系统性地考察了相关理论原理、应用场景及工程实践要点。题目设计注重概念准确性(如LDA目标函数)、技术细节(如Megatron-LM的并行策略)与实际应用(如FP16训练动机),并包含概率统计(二项分布)和数值计算(微分误差分析)等数学基础内容,全面检验读者对AI领域关键知识的掌握

m0_73659489的博客 143

第1课:开篇扫盲——OpenClaw是什么?能帮你解决什么问题?(入门必看)

核心目标:学会安装、卸载、管理OpenClaw技能,自定义AI代理的性格与权限,让AI贴合自己的使用习惯。核心内容技能市场详解:ClawHub市场核心技能分类(办公、学习、开发、生活),热门技能推荐(web-search、文件处理、邮件管理)[superscript:3][superscript:4]。技能安装与卸载:终端命令实操(openclaw skill install/uninstall),技能更新与版本管理[superscript:3]。

从零开始,掌握网络安全。提供全面的网络安全教程、攻防演练技巧和行业动态。 1758

基于mysql实现简单的分布式锁

​ 我们知道mysql支持多种索引,其中有一个(Unique Index),它的特点是索引列中的值必须是唯一的。这样可以防止数据列中出现重复值,同时可以加速查询。那么基于这一特点,我们可以使用mysql实现简单的分布式锁。​ 当我们想获取锁时,可以在表中添加一行数据,对于相同的名的锁来说,如果添加成功,则获取到了这个锁,如果添加失败,则获取锁失败。

weixin_46056406的博客 1495

华为OD机试双机位C卷-FLASH坏块监测系统(Py/Java/C/C++/Js/Go)

华为OD机试(机考)双机位C卷 【FLASH坏块监测系统】,提供Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及在线OJ模拟做题。华为OD机试 - FLASH坏块监测系统。

qq_45776114的博客 1928

再有人问你分布式锁,这篇文章扔给他

1.背景 对于锁大家肯定不会陌生,在Java中synchronized关键字和ReentrantLock可重入锁在我们的代码中是经常见的,一般我们用其在多线程环境中控制对资源的并发访问,但是随着分布式的快速发展,本地的加锁往往不能满足我们的需要,在我们的分布式环境中上面加锁的方法就会失去作用。于是人们为了在分布式环境中也能实现本地锁的效果,也是纷纷各出其招,今天让我们来聊一聊一般分布式锁实现的套...

南哥的博客 704

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

再有人面试问你 Redis 分布式锁的实现,把这篇文章甩给他

目录一、写在前面二、Redisson实现Redis分布式锁的底层原理(1)加锁机制(2)锁互斥机制(3)watch dog...

Hadoop技术博文 1555

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

请列举你了解的分布式锁_再有人问你分布式锁是什么,就把这篇文章发给他

现在面试,一般都会聊聊分布式系统这块的东西。通常面试官都会从服务框架(Spring Cloud、Dubbo)聊起,一路聊到分布式事务、分布式锁、ZooKeeper 等知识。所以咱们就来聊聊分布式锁这块的知识,先具体的来看看 Redis 分布式锁的实现原理。说实话,如果在公司里落地生产环境用分布式锁的时候,一定是会用开源类库的,比如 Redis 分布式锁,一般就是用 Redisson 框架就好了...

weixin_39778668的博客 143

什么是分布式锁?几种分布式锁分别是怎么实现的?

一、什么是分布式锁: 1、什么是分布式锁: 分布式锁,即分布式系统中的锁。在单体应用中我们通过锁解决的是控制共享资源访问的问题,而分布式锁,就是解决了分布式系统中控制共享资源访问的问题。与单体应用不同的是,分布式系统中竞争共享资源的最小粒度从线程升级成了进程。 2、分布式锁应该具备哪些条件: 在分布式系统环境下,一个方法在同一时间只能被一个机器的一个线程执行 高可用的获取锁与释放锁 高性能的获取锁与释放锁 具备可重入特性(可理解为重新进入,由多于一个任务并发使用,而不必担心数据错误) ...

m0_67645544的博客 6万+

Redis的分布式锁详解

1、什么是分布式锁: 为了防止分布式系统中的多个进程之间相互干扰,我们需要一种分布式协调技术来对这些进程进行调度。而这个分布式协调技术的核心就是来实现这个分布式锁。 2、分布式锁应该具备哪些条件 在分布式系统环境下,一个方法在同一时间只能被一个机器的一个线程执行 高可用的获取锁与释放锁 高性能的获取锁与释放锁 具备可重入特性(可理解为重新进入,由多于一个任务并发使用,而不必担心数据错误) 具备锁失效机制,防止死锁 具备非阻塞锁特性,即没有获取到锁将直接返回获取锁失败 分布式锁的实.

张维鹏的博客 9万+

为什么你不会redis分布式锁?因为你没看到这篇文章

一 前言 redis在分布式应用十分广泛,本篇文章也是互联网面试的重点内容,读者至少需要知道为什么需要分布式锁,分布式锁的实现原理,分布式锁的应用场景,在使用分布式锁时遇到哪些问题?你是如何解决的,如果读者能掌握以上问题,那么关于这道面试题,你也就基本过关了; 二 分布式锁的产生背景 分布式锁对应的是多个应用,每个应用中都可能会处理相同的数据,如果多个应用对用一个操作进行了重复操作,就会出现数据不...

知识追寻者(Inheriting the spirit of open source, Spreading technology knowledge;) 1440

关于分布式锁的面试题都在这里了|Reids分布式锁|ZooKeeper分布式锁

我今天班儿都没上,就为了赶紧把这篇文章分布式锁早点写完。我真的不能再贴心了。 边喝茶边构思,你们可不要白嫖了! 三连来一遍? 引言 为什么要学习分布式锁? 最简单的理由就是作为一个社招程序员,面试的时候一定被面啦,你看怎么多公众号都翻来覆去的发分布式锁的主题,可见它很重要啦,在高考里这就是送分题,不要怪可惜的。 那应届生也会问吗?这就不一定了,但是,如果你会,面试官肯定会多给你那点分(钱) 第三...

6022

搞懂“分布式锁”,看这篇文章就对了

对于锁大家肯定不会陌生,在 Java 中 synchronized 关键字和 ReentrantLock 可重入锁在我们的代码中是经常见的,一般我们用其在多线程环境中控制对资源的并发访问。 但是随着分布式的快速发展,本地的加锁往往不能满足我们的需要,在我们的分布式环境中上面加锁的方法就会失去作用。 于是人们为了在分布式环境中也能实现本地锁的效果,也是纷纷各出其招,今天让我们来聊一聊一般分布式锁实现的套路。 为何需要分布式锁 Martin Kleppmann 是英国剑桥大学的分布式系统的研究...

Tom_sensen的博客 385

mysql 分布式锁_搞懂“分布式锁”,看这篇文章就对了

原标题:搞懂“分布式锁”,看这篇文章就对了“对于锁大家肯定不会陌生,在 Java 中 synchronized 关键字和 ReentrantLock 可重入锁在我们的代码中是经常见的,一般我们用其在多线程环境中控制对资源的并发访问。 但是随着分布式的快速发展,本地的加锁往往不能满足我们的需要,在我们的分布式环境中上面加锁的方法就会失去作用。于是人们为了在分布式环境中也能实现本地锁的效果,也是纷纷各...

weixin_35599378的博客 799

面试再被问到分布式锁,把这篇文章甩给他

作者:javajiagoushiziyuanfenxiang 链接:http://www.lofter.com/lpost/205eca09_1c63205b8 来源:LOFTER 一、常规锁会造成什么情况? 二、分布式锁怎么去处理? 三、分布式锁的实现有哪些? 四、在Zookeeper中如何加锁? 首先,分布式锁和我们平常讲到的锁原理基本一样,目的就是确保在多个线程并发时,只有一个...

sincegc的博客 169
上一篇: 如果再有人问你分布式ID,这篇文章扔给他
下一篇: 如何保证消息的顺序性?
令狐义卓
博客等级 码龄6年 4粉丝 18原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值