Zookeeper分布式环境搭建&分布式锁实现
博客专区 > IamOkay 的博客 > 博客详情
Zookeeper分布式环境搭建&分布式锁实现
IamOkay 发表于1年前
Zookeeper分布式环境搭建&分布式锁实现
  • 发表于 1年前
  • 阅读 57
  • 收藏 1
  • 点赞 0
  • 评论 0

【腾讯云】新注册用户域名抢购1元起>>>   

摘要: Zookeeper分布式环境搭建&分布式锁实现

一.Zookeeper分布式环境搭建

由于机器太慢,懒得搭建虚拟机了,这里我们实现Zookeepe伪分布式集群。

1.试验需要准备的环境:windows系统,jdk环境,zookeeper-3.3.x

2.解压后,进入conf目录,将zoo_sample.cfg复制三份,分别命名为

zoo-d2182.cfg,zoo-d2183.cfg,zoo-d2184.cfg (zoo-d{端口}.cfg)

配置zoo-d2182.cfg

# 心跳时间2000毫秒
tickTime=2000
# The number of ticks that the initial 
# synchronization phase can take
initLimit=10
# The number of ticks that can pass between 
# sending a request and getting an acknowledgement
#就表示fowller与leader的心跳时间是2 tick
syncLimit=5
# the directory where the snapshot is stored.
#配置数据目录
dataDir=D:/Zookeeper/data/d2182
#配置日志目录
dataLogDir=D:/Zookeeper/logs/d2182
# 当前zookeeper使用的端口
clientPort=2182

server.1=127.0.0.1:2888:3888
server.2=127.0.0.1:2889:3889
server.3=127.0.0.1:2890:3890
#在上面的例子中,我把三个zookeeper服务放到同一台机器上。上面的配置中有两个TCP port。后面一个是用于Zookeeper选举用的,而前一个是Leader和Follower或Observer,Watcher交换数据使用的。我们还注意到server.后面的数字。这个就是myid(关于myid是什么下一节会介绍)。

配置zoo-d2183.cfg与zoo-d2184.cfg,只需要复制zoo-d2182.cfg的内容,

然后修改 dataDir,dataLogDir,clientPort三项即可。

3.创建zoo-d2182.cfg,zoo-d2183.cfg,zoo-d2184.cfg中说配置的dataDir与logDir

4.进入 bin目录,复制zkServer.cmd三份,命名为

zkServer-d2182.cmd,zkServer-d2183.cmd,zkServer-d2184.cmd (zkServer-d{端口号}.cmd)

然后在这三个cmd文件中找到如下一行

set ZOOMAIN=org.apache.zookeeper.server.quorum.QuorumPeerMain

然后在该行后面添加对应的配置

#zkServer-d2812.cmd
set ZOOCFG=%ZOOCFGDIR%\zoo-d2182.cfg

#zkServer-d2813.cmd
set ZOOCFG=%ZOOCFGDIR%\zoo-d2183.cfg

#zkServer-d2814.cmd
set ZOOCFG=%ZOOCFGDIR%\zoo-d2184.cfg

如下面的例子

@echo off
REM Licensed to the Apache Software Foundation (ASF) under one or more
REM contributor license agreements.  See the NOTICE file distributed with
REM this work for additional information regarding copyright ownership.
REM The ASF licenses this file to You under the Apache License, Version 2.0
REM (the "License"); you may not use this file except in compliance with
REM the License.  You may obtain a copy of the License at
REM
REM     http://www.apache.org/licenses/LICENSE-2.0
REM
REM Unless required by applicable law or agreed to in writing, software
REM distributed under the License is distributed on an "AS IS" BASIS,
REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
REM See the License for the specific language governing permissions and
REM limitations under the License.

setlocal
call "%~dp0zkEnv.cmd"

set ZOOMAIN=org.apache.zookeeper.server.quorum.QuorumPeerMain
set ZOOCFG=%ZOOCFGDIR%\zoo-d2182.cfg
echo on
java "-Dzookeeper.log.dir=%ZOO_LOG_DIR%" "-Dzookeeper.root.logger=%ZOO_LOG4J_PROP%" -cp "%CLASSPATH%" %ZOOMAIN% "%ZOOCFG%" %*

endlocal

然后我们点击相应的cmd便可以启动

 

二.分布式锁的实现

2.1实现原理

1 设置锁超时时间

redis、数据库等实现的分布式锁,需要设置锁超时时间的原因在于:其他客户端无法得知已经获取锁的客户端的状态 是挂了呢,还是正在执行。所以只能傻傻的设置一个超时,认为超时之后就简单的判定获取锁的客户端挂了。

一旦锁设定了超时时间,可能获取锁的客户端因各种原因执行业务操作的时候耗时较长,超出了锁的超时时间,这时其他客户端就可以再次获取锁了,所以就会带来并发问题。

2 消除锁超时时间

为了消除这个锁超时,就需要由服务器来作为代理来通知,

如ZooKeeper,一旦客户端挂了,就会删除对应的临时节点,然后通知watch该节点的其他客户端。所以客户端不需要设置锁超时,就等待通知即可。

从这点来说ZooKeeper是更可靠的,降低了因锁超时带来的并发问题。

3 方案的高可用问题

redis、数据库等方案要想实现高可用,则必须有对应的高可用方案。如最简单的主从架构,又引入了一致性的问题,又会有很多的坑。

ZooKeeper方案本身可以做到高可用、一致性,所以ZooKeeper方案也更简单一些。

4 连接的单点问题

这个单点不是说redis或zookeeper的单点问题,而是客户端和服务器端的这个连接的单点问题。先来举个例子:

如ZooKeeper还是会出现并发问题的,如客户端获取到锁了之后,和ZooKeeper连接出现了session超时, 就会导致ZooKeeper集群删除对应的临时节点,其他客户端也就能获取到锁了,此时就存在并发问题。

这种问题的根由就是:客户端和ZooKeeper集群之间的连接是单连接,即只连接其中的一台机器。一旦该连接出现网络抖动, 这种分布式锁方案也会出现并发问题。

减少并发的措施:增大session的超时时间,尽量减少网络抖动,但是这也会降低服务器端对客户端的状态检测的灵敏度,这个灵敏度在分布式锁的场景下也不是特别重要,所以无所谓了。

5 消除连接的单点问题

要消除单点,必然是建立多连接来防止网络的抖动,即客户端连接多个服务器端,向每个服务器都执行获取锁的操作。

如redis的Redlock实现的分布式锁。

有N个独立的master服务器,客户端会向所有的服务器发送获取锁的操作。过半的服务器都获取到锁了则认为获取到锁了,这种也有很多细节。这种方式就解决了上述所说的ZooKeeper单连接可能造成的并发问题。

然而redis由于上述1所说的redis自身设计的问题,Redlock实现的分布式锁也会有锁超时问题,即也会存在并发。

所以理想中更好的方案就是:解决了上述2个问题,从而来进一步减少并发的可能性

redis如果能像ZooKeeper一样,实现了和客户端绑定的临时key,一旦redis客户端挂了,临时key删除,通知watch该key的其他客户端(感觉这个是一个不错的需求,不知redis未来是否要实现),就可以消除锁超时,再使用Redlock实现的分布式锁,这时候可靠性就更高了。

本文侧重总结在可靠性方面的问题,性能嘛,单机的redis当然是最快的了,其次zookeeper,最后数据库。而上述第五点,Redlock方案牺牲了一些性能来换取了可靠性。

6 概览分布式锁

其实要解决2个高可用的问题:

  • 数据存储的高可用(解决基本使用)

    如使用redis、数据库、ZooKeeper,他们承载着分布式锁需要的数据,不能是单点的,要集群高可用

  • 连接的高可用(降低并发的概率)

    那就需要建立多连接,如向N个redis master建立连接,向每一个都获取锁。

所以应该理想的布局是:

和N个独立的服务器(如ZooKeeper)都建立连接,向每台服务器都请求获取锁的操作,过半成功才表示获取到锁

这N个独立的服务器既有数据的保障,又有多连接的保障。所以简单来说,应该和3个独立的ZooKeeper机器都建立连接,而不是这3台构成一个ZooKeeper集群。

 

2.2代码实现

参考 zookeeper分布式锁实现

jedisLock—redis分布式锁实现

 

 

 

 

  • 打赏
  • 点赞
  • 收藏
  • 分享
共有 人打赏支持
粉丝 184
博文 448
码字总数 365195
×
IamOkay
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: