范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

我想进大厂之分布式锁夺命连环9问大理版人在囧途

  开个头,这是篇技术文章,但是昨天一天太恶心了,忍不住还是简单说下昨天的事情。
  昨天早上11点飞大理,结果9点钟要出门的时候发现密码锁坏了,不用密码都能打开,一边司机师傅在催着走,一边连忙打电话给房东和客服找人维修,这是第一。
  然后飞机晚点,11点20飞到4点钟才要落地,下降的过程那叫一个颠簸,我以为都要没了,这也是第一次晕飞机,简直快吐了,这是第二。
  然后快4点了,飞机总算快要降落了,轮子都快着地了,结果愣是拔起来又起飞了,最后知道是大理8级大风,机长不敢落地…这是第三。
  最后通知起飞不知道什么时候,要等大理那边通知,没有办法,我们只好下飞机转高铁,急急忙忙的一路转,总算赶上了最后7点前的高铁,否则就要等到9点以后了,最后一路周转,9点多总算到了酒店,好在酒店还算行,没有让我太过于失望。
  这一天搞下来,整个一人在囧途,太累了。好吧,废话就这么多,文章开始。 说说分布式锁吧?
  对于一个单机的系统,我们可以通过synchronized或者ReentrantLock等这些常规的加锁方式来实现,然而对于一个分布式集群的系统而言,单纯的本地锁已经无法解决问题,所以就需要用到分布式锁了,通常我们都会引入三方组件或者服务来解决这个问题,比如数据库、Redis、Zookeeper等。
  通常来说,分布式锁要保证互斥性、不死锁、可重入等特点。
  互斥性指的是对于同一个资源,任意时刻,都只有一个客户端能持有锁。
  不死锁指的是必须要有锁超时这种机制,保证在出现问题的时候释放锁,不会出现死锁的问题。
  可重入指的是对于同一个线程,可以多次重复加锁。 那你分别说说使用数据库、Redis和Zookeeper的实现原理?
  数据库的话可以使用乐观锁或者悲观锁的实现方式。
  乐观锁通常就是数据库中我们会有一个版本号,更新数据的时候通过版本号来更新,这样的话效率会比较高,悲观锁则是通过for update 的方式,但是会带来很多问题,因为他是一个行级锁,高并发的情况下可能会导致死锁、客户端连接超时等问题,一般不推荐使用这种方式。
  Redis是通过set 命令来实现,在2.6.2 版本之前,实现方式可能是这样:
  setNX 命令代表当key 不存在时返回成功,否则返回失败。
  但是这种实现方式把加锁和设置过期时间的步骤分成两步,他们并不是原子操作,如果加锁成功之后程序崩溃、服务宕机等异常情况,导致没有设置过期时间,那么就会导致死锁的问题,其他线程永远都无法获取这个锁。
  之后的版本中,Redis提供了原生的set 命令,相当于两命令合二为一,不存在原子性的问题,当然也可以通过lua脚本来解决。
  set 命令如下格式:
  key 为分布式锁的key
  value 为分布式锁的值,一般为不同的客户端设置不同的值
  NX 代表如果要设置的key存在返回成功,否则返回失败
  EX 代表过期时间为秒,PX则为毫秒,比如上面示例中为10秒过期
  Zookeeper是通过创建临时顺序节点的方式来实现。
  当需要对资源进行加锁时,实际上就是在父节点之下创建一个临时顺序节点。客户端A来对资源加锁,首先判断当前创建的节点是否为最小节点,如果是,那么加锁成功,后续加锁线程阻塞等待此时,客户端B也来尝试加锁,由于客户端A已经加锁成功,所以客户端B发现自己的节点并不是最小节点,就会去取到上一个节点,并且对上一节点注册监听当客户端A操作完成,释放锁的操作就是删除这个节点,这样就可以触发监听事件,客户端B就会得到通知,同样,客户端B判断自己是否为最小节点,如果是,那么则加锁成功你说改为set命令之后就解决了问题?那么还会不会有其他的问题呢?
  虽然set 解决了原子性的问题,但是还是会存在两个问题。
  锁超时问题
  比如客户端A加锁同时设置超时时间是3秒,结果3s之后程序逻辑还没有执行完成,锁已经释放。客户端B此时也来尝试加锁,那么客户端B也会加锁成功。
  这样的话,就导致了并发的问题,如果代码幂等性没有处理好,就会导致问题产生。
  锁误删除
  还是类似的问题,客户端A加锁同时设置超时时间3秒,结果3s之后程序逻辑还没有执行完成,锁已经释放。客户端B此时也来尝试加锁,这时客户端A代码执行完成,执行释放锁,结果释放了客户端B的锁。
  那上面两个问题你有什么好的解决方案吗?
  锁超时
  这个有两个解决方案。 针对锁超时的问题,我们可以根据平时业务执行时间做大致的评估,然后根据评估的时间设置一个较为合理的超时时间,这样能一大部分程度上避免问题。自动续租,通过其他的线程为将要过期的锁延长持有时间
  锁误删除
  每个客户端的锁只能自己解锁,一般我们可以在使用set 命令的时候生成随机的value,解锁使用lua脚本判断当前锁是否自己持有的,是自己的锁才能释放。 #加锁 SET key random_value NX EX 10 #解锁 if redis.call("get",KEYS[1]) == ARGV[1] then     return redis.call("del",KEYS[1]) else     return 0 end 了解RedLock算法吗?
  因为在Redis的主从架构下,主从同步是异步的,如果在Master节点加锁成功后,指令还没有同步到Slave节点,此时Master挂掉,Slave被提升为Master,新的Master上并没有锁的数据,其他的客户端仍然可以加锁成功。
  对于这种问题,Redis作者提出了RedLock红锁的概念。
  RedLock的理念下需要至少2个Master节点,多个Master节点之间完全互相独立,彼此之间不存在主从同步和数据复制。
  主要步骤如下: 获取当前Unix时间按照顺序依次尝试从多个节点锁,如果获取锁的时间小于超时时间,并且超过半数的节点获取成功,那么加锁成功。这样做的目的就是为了避免某些节点已经宕机的情况下,客户端还在一直等待响应结果。举个例子,假设现在有5个节点,过期时间=100ms,第一个节点获取锁花费10ms,第二个节点花费20ms,第三个节点花费30ms,那么最后锁的过期时间就是100-(10+20+30),这样就是加锁成功,反之如果最后时间<0,那么加锁失败如果加锁失败,那么要释放所有节点上的锁那么RedLock有什么问题吗?
  其实RedLock存在不少问题,所以现在其实一般不推荐使用这种方式,而是推荐使用Redission的方案,他的问题主要如下几点。
  性能、资源
  因为需要对多个节点分别加锁和解锁,而一般分布式锁的应用场景都是在高并发的情况下,所以耗时较长,对性能有一定的影响。此外因为需要多个节点,使用的资源也比较多,简单来说就是费钱。
  节点崩溃重启
  比如有1~5号五个节点,并且没有开启持久化,客户端A在1,2,3号节点加锁成功,此时3号节点崩溃宕机后发生重启,就丢失了加锁信息,客户端B在3,4,5号节点加锁成功。
  那么,两个客户端AB同时获取到了同一个锁,问题产生了,怎么解决? Redis作者建议的方式就是延时重启,比如3号节点宕机之后不要立刻重启,而是等待一段时间后再重启,这个时间必须大于锁的有效时间,也就是锁失效后再重启,这种人为干预的措施真正实施起来就比较困难了第二个方案那么就是开启持久化,但是这样对性能又造成了影响。比如如果开启AOF默认每秒一次刷盘,那么最多丢失一秒的数据,如果想完全不丢失的话就对性能造成较大的影响。
  GC、网络延迟
  对于RedLock,Martin Kleppmann提出了很多质疑,我就只举这样一个GC或者网络导致的例子。(这个问题比较多,我就不一一举例了,心里有一个概念就行了,文章地址:https://martin.kleppmann.com/2016/02/08/how-to-do-distributed-locking.html )
  从图中我们可以看出,client1线获取到锁,然后发生GC停顿,超过了锁的有效时间导致锁被释放,然后锁被client2拿到,然后两个客户端同时拿到锁在写数据,问题产生。
  图片来自Martin Kleppmann
  时钟跳跃
  同样的例子,假设发生网络分区,4、5号节点变为一个独立的子网,3号节点发生始终跳跃(不管人为操作还是同步导致)导致锁过期,这时候另外的客户端就可以从3、4、5号节点加锁成功,问题又发生了。 那你说说有什么好的解决方案吗?
  上面也提到了,其实比较好的方式是使用Redission ,它是一个开源的Java版本的Redis客户端,无论单机、哨兵、集群环境都能支持,另外还很好地解决了锁超时、公平非公平锁、可重入等问题,也实现了RedLock ,同时也是官方推荐的客户端版本。 那么Redission实现原理呢?
  加锁、可重入
  首先,加锁和解锁都是通过lua脚本去实现的,这样做的好处是为了兼容老版本的redis同时保证原子性。
  KEYS[1] 为锁的key,ARGV[2] 为锁的value,格式为uuid+线程ID,ARGV[1] 为过期时间。
  主要的加锁逻辑也比较容易看懂,如果key 不存在,通过hash的方式保存,同时设置过期时间,反之如果存在就是+1。
  对应的就是hincrby", KEYS[1], ARGV[2], 1 这段命令,对hash结构的锁重入次数+1。
  解锁 如果key都不存在了,那么就直接返回如果key、field不匹配,那么说明不是自己的锁,不能释放,返回空释放锁,重入次数-1,如果还大于0那么久刷新过期时间,反之那么久删除锁
  watchdog
  也叫做看门狗,也就是解决了锁超时导致的问题,实际上就是一个后台线程,默认每隔10秒自动延长锁的过期时间。
  默认的时间就是internalLockLeaseTime / 3 ,internalLockLeaseTime 默认为30秒。
  最后,实际生产中对于不同的场景该如何选择?
  首先,如果对于并发不高并且比较简单的场景,通过数据库乐观锁或者唯一主键的形式就能解决大部分的问题。
  然后,对于Redis实现的分布式锁来说性能高,自己去实现的话比较麻烦,要解决锁续租、lua脚本、可重入等一系列复杂的问题。
  对于单机模式而言,存在单点问题。
  对于主从架构或者哨兵模式,故障转移会发生锁丢失的问题,因此产生了红锁,但是红锁的问题也比较多,并不推荐使用,推荐的使用方式是用Redission。
  但是,不管选择哪种方式,本身对于Redis来说不是强一致性的,某些极端场景下还是可能会存在问题。
  对于Zookeeper的实现方式而言,本身就是保证数据一致性的,可靠性更高,所以不存在Redis的各种故障转移带来的问题,自己实现也比较简单,但是性能相比Redis稍差。
  不过,实际中我们当然是有啥用啥,老板说用什么就用什么,我才不管那么多。
  后台回复【pdf】获取百本计算机电子书和大厂面试精华,文章每周持续更新。我是艾小仙,阿里巴巴技术专家,我们下期见!
  面经PDF整理

每当人生落魄的时候,听完这些歌曲,会让你重新找回自己人生顺风顺水时,做什么事情都顺心人生没落失败时,做什么事情都不顺心。但是人生不能自暴自弃,属于你的终归会来的,也许只是时间问题。遇到烦心事,不如坐下来听听这些歌曲,也许会有意想不到天天传黄晓明baby离婚,夫妻低调行事不受影响,baby新剧依旧火爆娱乐圈有一种假新闻,百传不厌,那就是明星离婚。老人都说了宁拆十座庙,不拆一桩婚,如果天天有人说你离婚,你会怎么想呢?不过难能可贵的是,不管网络怎么说,夫妻双方依旧不离不弃。下面就请海外华人司机接到华人,唱起我的中国心,游子在外思乡苦中国人这个词,包含了两种意思。一种是拥有中国国籍的人,另一种是拥有中华血统的人。今天我们要聊的是拥有中华血统的中国人,他们大多都是海外华人,常年居住在海外。平时和其他人没有什么区别黄晓明杨颖离婚坐实?已有迹象表明?娱乐圈婚姻最后都是名存实亡黄晓明和杨颖baby从当初的世纪婚礼开始,就屡次被传有二人突发婚变的消息,很多坊间传闻二人早已在青岛办理离婚,只是有一些利益捆绑并未公布。正当媒体唱衰两人的婚姻时,黄教主却又暗暗发娱乐圈的高情商明星,黄渤新片海报发布,灼心境地直击人心娱乐圈里最不缺的就是俊男美女,要想在娱乐圈生存下去,有实力有颜值那还远远不够,还需要面对的突发情况太多,所以更要有高情商。谈到高情商的明星,就不得不提到青岛贵妇黄渤。说起黄渤,大家新天龙八部吐槽不断,乔峰段誉更是让人无法接受?年年都有翻拍剧,新倚天屠龙记刚刚播完,就迎来了新天龙八部,大家是不是满满的期待呢?新倚天屠龙记不管是演员还是造型都获得了不错的好评,反而新天龙八部被网友称为史上最丑,这是什么原因呢林夕一生写了千首歌,经典数不胜数,这首称得上经典中的经典娱乐圈从来不缺乏歌手,缺的是能写出一首好词,弹出一首好曲。今天我们要说的就是华语音乐圈词神林夕。林夕可谓是神一般的存在,一生写了4000多首词,其中更是有很多经典之作。接下来就请大网红唱歌真的不如职业歌手吗?如果你不信,请听完这些歌曲不知从何时起,网红这个词走进了大众视野,同时也诞生了很多网络直播歌手。其中也有一些才华横溢的网络直播歌手,甚至不输一些职业歌手。有句话说得好,没有对比就没有伤害,下面来对比一下网红求婚有多甜蜜,现在就有多冷漠,赖弘国发文控诉阿娇对感情不认真在普通人眼中,明星总是光鲜亮丽地出现在镜头之中,他们在获得知名度和利益的同时,也将自己生活完全暴露在聚光灯之下。在公众视野的注视下,无论是恋爱结婚工作,离婚,都会随时成为大家关注讨快乐家族集体收礼口碑崩塌?湖南卫视调查,揭幕饭圈经济何炅收礼一事,越搞越大,先有人民网点名批评,后有湖南卫视出来公开表态调查,大有愈演愈烈之势。距离2020年结束已经没几天了,深谙娱乐大瓜规律的人都知道,越到最后瓜越大,娱乐圈也不断孟晚舟罕见和老公同框,黑色娃娃裙十分减龄,霸总变身粘人小女人作为中国通讯巨头之一华为老总任正非的掌上明珠,从小受到良好教育的孟晚舟,在金融经济方面表现出过人的天赋。作为现任华为副董事长首席财务官,她主要负责处理华为公司的财务运营及管理问题,
她是包衣出身,却因为生下一个奇皇子,死后连抬两旗还被迁入帝陵一说起包衣出身,可能很多人都会想起八阿哥的生母良妃,谁叫康熙当初为了贬低八阿哥,说了一句乃是辛者库贱妇所生呢?一下子贬低了良妃,又打压了八阿哥。而曾经和康熙有过恩爱时光的良妃,当时康熙的哥哥福全,放弃皇位辅佐康熙,没想到却因一件事被康熙怪罪顺治临死之前,把皇位传给了年仅8岁的皇三子玄烨,也就是后来的康熙皇帝。而事实上,在玄烨前面,还另有年长的哥哥福全,而为什么皇位传给了皇三子玄烨,却没有传给福全,这里也是另有一番玄机康熙让雍亲王做皇位继承人,还加一附加条件,却导致一严重后果康熙六十一年,康熙帝病危,在他死前,康熙帝留下遗诏,让四阿哥胤禛继承皇位,算是为纷扰的九龙夺嫡,暂时划上了一个句点。剧照之所以说是暂时,我们大家都知道,一切并没有因为雍正的登基而彻清朝唯一随母葬的皇子,就是因为他,康熙废了太子在康熙的景陵妃园寝里,葬着一个特殊的人物。他就是十八阿哥胤阶。景陵妃园寝,顾名思义,原本该是妃子们的埋骨之所,然后胤阶作为皇子,却能随母入葬,葬在他的母亲密妃旁边,也算是一段传奇了同样是自己的亲兄弟,为何康熙对福全十分厚待,对常宁却挺冷漠?大家有没有一种感觉,提到康熙,你会想起他的妃子后宫,你会想起九龙夺嫡,也会想到顺治董鄂妃,当然也会想到孝庄苏麻拉姑,然而,对于康熙的兄弟们,却鲜少有人提及。甚至会给人一种错觉,好像康熙皇子里很清流的一位阿哥,别人都在争储,他却只想做清闲王爷都知道康熙儿子多,有才干的儿子也多,这才有了后来的九龙夺嫡,即便是睿智如康熙,也没有办法阻止这件事的发生。剧照当然也有一些皇子没有加入夺嫡的,比如十七阿哥胤礼这种,当然也有很大一个她是康熙最早的妃子,本有机会成为皇后却被父亲连累,后登上后位提起康熙的皇后,很多人应该都会想到赫舍里皇后,赫舍里皇后是康熙的第一任皇后,她在青春少年的时候,就嫁给了康熙。他们的婚姻,很有政治意味,因为当时康熙年少,皇位未稳,还有辅政大臣鳌拜要不是太监忘记一件事,窦漪房还不一定能成为皇后呢,真该感谢他提起窦漪房,大家都应该很熟悉了,窦漪房是汉文帝的皇后,儿子景帝登基以后,她又成为了太后,她见证了文景之治,也是文景之治的重要参与者。而她留下的故事,也成了传奇。在大家的印象里,能够同样是儿子,德妃为何偏爱十四却讨厌雍正?都因为清宫一惯例雍正和生母德妃的关系一直不太好。从他还是个皇子的时候,他就很明显的感觉到德妃对自己和胞弟十四阿哥的不同,一个是爱如生命的儿子,一个却是可有可无的儿子,不过那时候,因为没有什么直接利宜妃死后四年才下葬,不是不得宠,只因儿子站错队提起宜妃,很多人估计第一个想到的都是康熙微服私访记里邓婕饰演的宜妃。英姿飒爽又不失女儿柔情,在康熙一路的出巡上,二人吵吵闹闹,不像是皇帝与嫔妃,倒像是一对寻常的夫妇。而宜妃红颜薄命小系列凭啥这么火?小舍得比前两部更好看,只有一个原因4月份热播的影视剧中,一部家庭教育剧堪称黑马,上映没几天就成功占据观众视线,就算是顶流明星出演的古装剧都无法与其媲美。这部作品自然就是宋佳蒋欣合作的小系列第三部小舍得。最近该剧引起