Discuz! Board

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 65|回复: 0

Zebra项目知识介绍共五篇(三)

[复制链接]

1万

主题

1万

帖子

5万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
58026
发表于 2020-10-20 11:42:36 | 显示全部楼层 |阅读模式

                    

                    

                    
                    
                    <p style="text-align: center;"><span style="color: rgb(0, 209, 0);">Zebra项目知识介绍共五篇(三)——</span></p><p style="text-align: center;"><span style="color: rgb(0, 209, 0);">序列化和反序列化、zookeeper介绍_原理 、</span></p><p style="text-align: center;"><span style="color: rgb(0, 209, 0);">&nbsp;zookeeper的安装配置 、 zookeeper操作</span></p><p style="text-align: left;"><span style="color: rgb(0, 209, 0);"></span></p><p style="white-space: normal;">===========================================================</p><p style="white-space: normal;"><strong><span style="color: rgb(255, 79, 121);">一、序列化和反序列化概述</span></strong></p><p style="white-space: normal;"><span class="Apple-tab-span" style="white-space: pre;">        </span>远程方法调用 -- RPC</p><p style="white-space: normal;"><span class="Apple-tab-span" style="white-space: pre;">        </span><strong><span style="color: rgb(0, 82, 255);">1.序列化</span></strong></p><p style="white-space: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;对象本身是存在在内存中的,而对象在内存中存活的状态是无法直接用来保存或传输的,将内存中对象从这种状态转换为可以用字节形式表示便于保存或传输的过程,称为将对象序列化。</p><p style="white-space: normal;"><span class="Apple-tab-span" style="white-space: pre;">        </span><strong><span style="color: rgb(0, 82, 255);">2.反序列化</span></strong></p><p style="white-space: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;将序列化后的对象恢复为内存中的对象的过程叫做反序列化。</p><p style="white-space: normal;"><span class="Apple-tab-span" style="white-space: pre;">        </span><strong><span style="color: rgb(0, 82, 255);">3.持久化</span></strong></p><p style="white-space: normal;"><span class="Apple-tab-span" style="white-space: pre;">        </span>对象存在与内存时,是易失的状态,将对象从这个易失的状态转换为持久化设备中不易丢失的状态的过程叫做持久化。</p><p style="white-space: normal;"><span class="Apple-tab-span" style="white-space: pre;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><strong><span style="color: rgb(0, 82, 255);">4.反持久化</span></strong></p><p style="white-space: normal;"><span class="Apple-tab-span" style="white-space: pre;">        </span>将持久化设备中已经持久化了的对象恢复到内存中的过程称为反持久化。</p><p style="white-space: normal;"><span class="Apple-tab-span" style="white-space: pre;">        </span></p><p style="white-space: normal;"><span class="Apple-tab-span" style="white-space: pre;">        </span><strong>持久化的前提是序列化,但是序列化的目的不一定是持久化。</strong></p><p style="white-space: normal;"><br  /></p><p style="white-space: normal;"><span class="Apple-tab-span" style="white-space: pre;">        </span></p><p style="white-space: normal;"><strong><span style="color: rgb(255, 79, 121);">二、sun提供的序列化和反序列化</span></strong></p><p style="white-space: normal;"><span class="Apple-tab-span" style="white-space: pre;">        </span>sun其实从jdk1.0开始就已经提供了原生的序列化反序列化功能。</p><p style="white-space: normal;"><span class="Apple-tab-span" style="white-space: pre;">        </span>主要是通过ObjectOutputStream ObjectInputStream Serializable来实现的。<span class="Apple-tab-span" style="white-space: pre;">        </span><span class="Apple-tab-span" style="white-space: pre;">        </span></p><p style="white-space: normal;"><span class="Apple-tab-span" style="white-space: pre;">        </span>缺点:</p><p style="white-space: normal;"><span class="Apple-tab-span" style="white-space: pre;">        </span>1.只能支持java语言,无法跨语言。</p><p style="white-space: normal;"><span class="Apple-tab-span" style="white-space: pre;">        </span>2.序列化完成后产生的数据量比较大。</p><p style="white-space: normal;"><span class="Apple-tab-span" style="white-space: pre;">        </span>3.执行序列化反序列化操作的效率比较低。</p><p style="white-space: normal;"><br  /></p><p style="white-space: normal;"><strong><span style="color: rgb(255, 79, 121);">三、第三方序列化反序列化框架</span></strong></p><p style="white-space: normal;"><span class="Apple-tab-span" style="white-space: pre;">        </span>1.Avro -- Apache</p><p style="white-space: normal;"><span class="Apple-tab-span" style="white-space: pre;">        </span>2.Google ProtoBuffer -- Google</p><p style="white-space: normal;"><span class="Apple-tab-span" style="white-space: pre;">        </span>GoogleProtoBuffer的使用:</p><p style="white-space: normal;"><span class="Apple-tab-span" style="white-space: pre;">                </span>①写proto文件</p><p style="white-space: normal;"><span class="Apple-tab-span" style="white-space: pre;">                </span>②编译成类文件</p><p style="white-space: normal;"><span class="Apple-tab-span" style="white-space: pre;">                </span>③导入类文件进行序列化反序列化</p><p style="text-align: left;"><br  /></p><p><strong><span style="color: rgb(255, 79, 121);">四、Zookeeper</span></strong></p><p>        <strong><span style="color: rgb(0, 82, 255);">1.Zookeeper概述</span></strong></p><p>                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Zookeeper是一个工具,可以实现集群中的分布式协调服务。</p><p>                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;所谓的分布式协调服务,就是在集群的节点中进行可靠的消息传递,来协调集群的工作。</p><p>                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Zookeeper之所以能够实现分布式协调服务,靠的就是它能够保证分布式数据一致性。&nbsp;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;所谓的分布式数据一致性,指的就是可以在集群中保证数据传递的一致性。</p><p>                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Zookeeper能够提供的分布式协调服务包括:数据发布订阅、负载均衡、命名服务、分布式协调/通知、集群管理、分布式锁、分布式队列等功能。</p><p><br  /></p><p>        <strong><span style="color: rgb(0, 82, 255);">2.Zookeeper的特点</span></strong></p><p>                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Zookeeper工作在集群中,对集群提供分布式协调服务,它提供的分布式协调服务具有如下的特点:</p><p>                        <strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;①顺序一致性</strong></p><p>                                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;从同一个客户端发起的事务请求,最终将会严格按照其发起顺序被应用到zookeeper中。</p><p>                        <strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;②原子性</strong></p><p>                                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;所有事务请求的处理结果在整个集群中所有机器上的应用情况是一致的,即,要么整个集群中所有机器都成功应用了某一事务,要么都没有应用,一定不会出现集群中部分机器应用了改事务,另外一部分没有应用的情况。</p><p>                        <strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;③单一视图</strong></p><p>                                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;无论客户端连接的是哪个zookeeper服务器,其看到的服务端数据模型都是一致的。</p><p>                        <strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;④可靠性</strong></p><p>                                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;一旦服务端成功的应用了一个事务,并完成对客户端的响应,那么该事务所引起的服务端状态变更将会一直保留下来,除非有另一个事务又对其进行了改变。</p><p>                        <strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;⑤实时性</strong></p><p>                                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;zookeeper并不是一种强一致性,只能保证顺序一致性和最终一致性,只能称为达到了伪实时性。</p><p><br  /></p><p>        <strong><span style="color: rgb(0, 82, 255);">3.zookeeper的数据模型</span></strong></p><p>                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;zookeeper中可以保存数据,正是利用zookeeper可以保存数据这一特点,我们的集群通过在zookeeper里存取数据来进行消息的传递。</p><p>                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;zookeeper中保存数据的结构非常类似于文件系统。都是由节点组成的树形结构。不同的是文件系统是由文件夹和文件来组成的树,而zookeeper中是由ZNODE来组成的树。</p><p>                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;每一个ZNODE里都可以存放一段数据,ZNODE下还可以挂载零个或多个子ZNODE节点,从而组成一个树形结构。</p><p style="white-space: normal;"><strong>节点类型:</strong></p><table width="258" height="77"><colgroup><col width="81"  /><col width="131"  /><col width="132"  /></colgroup><tbody><tr height="19"><td class="et2" height="14" width="60" style="font-size: 11pt;text-align: center;vertical-align: middle;"><br  /></td><td class="et3" x:str="" height="14" width="98" style="font-size: 11pt;text-align: center;vertical-align: middle;background: rgb(197, 217, 241);">顺序节点</td><td class="et3" x:str="" height="14" width="99" style="font-size: 11pt;text-align: center;vertical-align: middle;background: rgb(197, 217, 241);">普通节点</td></tr><tr height="29"><td class="et3" x:str="" height="21" width="60" style="font-size: 11pt;text-align: center;vertical-align: middle;background: rgb(197, 217, 241);"><p>临时</p><p>节点</p></td><td class="et2" x:str="" height="21" width="98" style="font-size: 11pt;text-align: center;vertical-align: middle;"><p>顺序临<span style="font-size: 11pt;">时</span></p><p><span style="font-size: 11pt;">节点</span><span class="font1" style="font-size: 11pt;">&nbsp;</span></p></td><td class="et2" x:str="" height="21" width="99" style="font-size: 11pt;text-align: center;vertical-align: middle;"><p>普通临时</p><p>节点</p></td></tr><tr height="29"><td class="et3" x:str="" height="21" width="60" style="font-size: 11pt;text-align: center;vertical-align: middle;background: rgb(197, 217, 241);"><p>持久</p><p>节点</p></td><td class="et2" x:str="" height="21" width="98" style="font-size: 11pt;text-align: center;vertical-align: middle;"><p>顺序持<span style="font-size: 11pt;">久</span></p><p><span style="font-size: 11pt;">节点</span><span class="font1" style="font-size: 11pt;">&nbsp;</span></p></td><td class="et2" x:str="" height="21" width="99" style="font-size: 11pt;text-align: center;vertical-align: middle;"><p>普通持<span style="font-size: 11pt;">久</span></p><p><span style="font-size: 11pt;">节点</span></p></td></tr></tbody></table><p style="white-space: normal;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: rgb(0, 82, 255);">顺序节点</span>:指定叫什么,除了前缀是指定的名字外,在名字后会会自带一个独一无二自动增长的的编号 。</p><p style="white-space: normal;">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<span style="color: rgb(0, 82, 255);">普通节点</span>:指定叫什么就叫什么。</p><p style="white-space: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(0, 82, 255);">临时节点</span>:一个客户端连接创建的临时节点,会在当客户端会话结束时立即自动删除。&nbsp;</p><p style="white-space: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(0, 82, 255);">持久节点</span>:创建出来后只要不删除就不会消失,无论客户端是否连接。</p><p><br  /></p><p>        <strong><span style="color: rgb(0, 82, 255);">4.zookeeper集群的搭建</span></strong></p><p>                需要先安装jdk,并且配置jdk的环境变量</p><p>①下载zookeeper的安装包</p><p>②上传到linux集群环境下</p><p>&nbsp;③解压安装包:</p><p>&nbsp; &nbsp; &nbsp; tar -zxvf zookeeper-3.4.7.tar.gz</p><p>④进入conf目录,复制zoo-sample.cfg为zoo.cfg,通过修改zoo.cfg来对zookeeper进行配置</p><p>⑤修改1:dataDir 指定zookeeper将数据保存在哪个目录下,如果不修改,默认在/tmp下,这个目录下的数据有可能会在磁盘空间不足或服务器重启时自动被linux清理,所以一定要修改这个地址</p><p>&nbsp;⑥修改2:修改服务器列表:</p><p>                                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;单机模式:在zoo.cfg中只配置一个server.id就是单机模式了。</p><p>                                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;伪集群模式:在zoo.cfg中配置多个server.id,其中ip都是当前机器,而端口各部相同,启动时就是伪集群模式了。</p><p>                                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;集群模式:多台机器各自配置。</p><p>                                        server.1=xxx.xxx.xxx.xxx:2888:3887        </p><p>                                        server.2=xxx.xxx.xxx.xxx:2888:3888        </p><p>                                        server.3=xxx.xxx.xxx.xxx:2888:3889</p><p>⑦ 如果是完全分布模式,还要进行修改3:到之前配置的zookeeper数据文件所在的目录下生成一个文件叫myid,其中写上一个数字表明当前机器是哪一个编号的机器。</p><p>&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</p><p>        <strong><span style="color: rgb(0, 82, 255);">5.zookeeper的shell下操作</span></strong></p><p>&nbsp;&nbsp;&nbsp;&nbsp;                <strong>①首先进入%ZK_HOME%/bin</strong></p><p>&nbsp;&nbsp;&nbsp;&nbsp;                执行zkCli.sh [-server ip:port] #如不指定,则连接本机。</p><p><br  /></p><p>&nbsp;&nbsp;&nbsp;&nbsp;                <strong>②创建:</strong></p><p>&nbsp;&nbsp;&nbsp;&nbsp;                        create [-s] [-e] path data [acl] #创建数据节点</p><p>&nbsp;&nbsp;&nbsp;&nbsp;                                --其中 -s表示顺序节点 -e表示临时节点,两个都不加则是持久节点</p><p>&nbsp;&nbsp;&nbsp;&nbsp;                                --acl 指定权限控制,不赋值则不进行任何权限控制 &nbsp; &nbsp;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;        <strong>练习:</strong></p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;创建/zk-book 其中数据为123</p><p>&nbsp;&nbsp;&nbsp;&nbsp;        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;                        Create /zk-book 123</p><p><br  /></p><p>&nbsp;&nbsp;&nbsp;&nbsp;<strong>③列出:</strong></p><p>                        &nbsp;&nbsp;&nbsp;&nbsp;ls path [watch]        #列出所有数据节点</p><p>                        &nbsp;&nbsp;&nbsp;&nbsp;<strong>练习:</strong></p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;列出根目录下所有数据节点</p><p>&nbsp;&nbsp;&nbsp;&nbsp;        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;                        ls /</p><p><br  /></p><p>&nbsp;&nbsp;&nbsp;&nbsp;                <strong>④获取:</strong></p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;                        get path [watch] &nbsp; &nbsp;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;<strong>练习:</strong></p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;列出 /zk-book中的数据</p><p>&nbsp;&nbsp;&nbsp;&nbsp;        &nbsp;&nbsp;&nbsp;&nbsp;        &nbsp;&nbsp;&nbsp;&nbsp;                get /zk-book</p><p><br  /></p><p>&nbsp;&nbsp;&nbsp;&nbsp;<strong>⑤更新:</strong></p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;                        set path data [version]</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;                                --data 为要更新的内容&nbsp;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; &nbsp;--version指定要基于哪个版本的数据进行更新</p><p><br  /></p><p>&nbsp;&nbsp;&nbsp;&nbsp;<strong>⑥删除:</strong></p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;                        delete path [version]</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;                                --path 为要删除的路径&nbsp;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --version指定要基于哪个版本进行删除</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;                                --注意,要删除的节点下必须没有任何子节点才能删除成功</p><p>                </p><p style="text-align: center;"><span style="color: rgb(0, 209, 0);">=======================================================</span></p><p><strong><span style="color: rgb(0, 82, 255);">6.zookeeper的java API操作</span></strong></p><p><strong>①创建会话:</strong></p><p>                        &nbsp;&nbsp;&nbsp;&nbsp;Zookeeper(String connectString,int sessionTimeout,Watcher watcher)</p><p>                        &nbsp;&nbsp;&nbsp;&nbsp;Zookeeper(String connectString,int sessionTimeout,Watcher watcher,boolean canBeReadOnly)</p><p>                        &nbsp;&nbsp;&nbsp;&nbsp;Zookeeper(String connectString,int sessionTimeout,Watcher watcher,long sessionId,byte[] sessionPasswd)</p><p>                        &nbsp;&nbsp;&nbsp;&nbsp;Zookeeper(String connectString,int sessionTimeout,Watcher watcher,long sessionId,byte[] sessionPasswd,boolean canBeReadOnly)</p><p>                        <strong>参数说明:</strong></p><p>&nbsp; &nbsp; &nbsp; &nbsp; connectString -- host:port[,host:port][basePath] 指定的服务器列表,多个host:port之间用英文逗号分隔。还可以可选择的指定一个基路径,如果指定了一个基路径,则所有后续操作基于这个路径进行。</p><p>&nbsp; &nbsp; &nbsp; &nbsp; sessionTimeOut -- 会话超时时间。以毫秒为单位。客户端和服务器端之间的连接通过心跳包进行维系,如果心跳包超过这个指定时间则认为会话超时失效。</p><p>&nbsp; &nbsp; &nbsp; &nbsp; watcher -- 指定默认观察者。如果为null表示不需要观察者。</p><p>&nbsp; &nbsp; &nbsp; &nbsp; canBeReadOnly -- 是否支持只读服务。只当一个服务器失去过半连接后不能再进行写入操作时,是否继续支持读取操作。</p><p>&nbsp; &nbsp; &nbsp; &nbsp; sessionId、SessionPassword -- 会话编号 会话密码,用来实现会话恢复。</p><p><br  /></p><p><strong>注意</strong><strong>:</strong></p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;整个创建会话的过程是异步的,构造方法会在初始化连接后即返回,并不代表真正建立好了一个会话,此时会话处于"CONNECTING"状态。</p><p>                        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;当会话真正创建起来后,服务器会发送事件通知给客户端,只有客户端获取到这个通知后,会话才真正建立。</p><p style="text-align: center;"><span style="text-align: center;color: rgb(0, 209, 0);">=======================================================</span></p><p><strong>②创建节点:</strong><br  /></p><p>&nbsp;&nbsp;&nbsp;&nbsp;                        String create(final String path,byte data[],List&lt;ACL&gt; acl,CreateMode createMode);//同步方式创建        </p><p>&nbsp;&nbsp;&nbsp;&nbsp;                        void create(final String path,byte data[],List&lt;ACL&gt; acl,CreateMode createMode,StringCallback cb,Object ctx);//异步方式创建</p><p>&nbsp;&nbsp;&nbsp;&nbsp;                        <strong>参数说明:</strong></p><p>&nbsp;&nbsp;&nbsp;&nbsp;                                path 要创建的数据节点的路径;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;                                data [] 节点创建时初始数据内容;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;                                acl 节点acl安全策略;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;                                createMode 创建模式;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;                                        PERSISTENT 持久;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;                                        PERSISTENT_SEQUENTIAL 持久顺序;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;                                        EPHEMERAL 临时;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;                                        EPHEMERAL_SEQUENTIAL 临时顺序;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;                                cb 回调接口;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;                                ctx 传递对象,用来在回调方法中使用 通常是个上下文对象;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;<br  /></p><p><strong>注意:</strong></p><p>&nbsp;&nbsp;&nbsp;&nbsp;不支持递归创建,即不能在无父节点的情况下创建出子节点</p><p>&nbsp; &nbsp; &nbsp;尝试创建已经存在的节点将失败并抛出异常</p><p>&nbsp; &nbsp; &nbsp;在不需要进行任何权限控制时,只需传入Ids.OPEN_ACL_UNSAFE即可</p><p><br  /></p><p style="text-align: center;">                        <span style="text-align: center;color: rgb(0, 209, 0);">=======================================================</span></p><p>&nbsp;<strong>③删除节点:</strong></p><p>&nbsp;&nbsp;&nbsp;&nbsp;                        public void delete(final String path,int version)</p><p>&nbsp;&nbsp;&nbsp;&nbsp;                        public void delete(final String path,int version,VoidCallback cb,Object ctx)</p><p>&nbsp;&nbsp;&nbsp;&nbsp;<br  /></p><p>&nbsp;<strong>注意:</strong></p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;无法删除存在子节点的节点,即如果要删除一个节点,必须要先删除其所有子节点</p><p style="text-align: center;"><span style="text-align: center;color: rgb(0, 209, 0);">=======================================================</span></p><p><strong>④        读取数据:</strong></p><p>&nbsp;&nbsp;&nbsp;&nbsp;                        getChildren</p><p>&nbsp;&nbsp;&nbsp;&nbsp;                                //同步方式</p><p>&nbsp;&nbsp;&nbsp;&nbsp;                                List&lt;String&gt; getChildren(final String path,Watcher watcher)</p><p>&nbsp;&nbsp;&nbsp;&nbsp;                                List&lt;String&gt; getChildren(String path,boolean watch)</p><p>&nbsp;&nbsp;&nbsp;&nbsp;                                List&lt;String&gt; getChildren(final String path,Watcher watcher,Stat stat)</p><p>&nbsp;&nbsp;&nbsp;&nbsp;                                List&lt;String&gt; getChildren(String path,boolean watch,Stat stat)</p><p>&nbsp;&nbsp;&nbsp;&nbsp;                                //异步方式</p><p>&nbsp;&nbsp;&nbsp;&nbsp;                                void getChildred(final String path,Watcher watcher,ChildrenCallback cb,Object ctx)</p><p>&nbsp;&nbsp;&nbsp;&nbsp;                                void getChildred(String path,boolean watch,ChildrednCallback cb,Object ctx)</p><p>&nbsp;&nbsp;&nbsp;&nbsp;                                void getChildred(final String path,Watcher watcher,Children2Callback cb,Object ctx)</p><p>&nbsp;&nbsp;&nbsp;&nbsp;                                void getChildred(String path,boolean watch,Children2Callback cb,Object ctx) &nbsp; &nbsp;</p><p>&nbsp;<strong>参数说明:</strong></p><p>&nbsp;&nbsp;&nbsp;&nbsp;                                        path 要创建的数据节点的路径</p><p>&nbsp;&nbsp;&nbsp;&nbsp;                                        watcher 观察者,一旦在本子节点获取之后,子节点列表发生变更,服务器端向客户端发送消息,触发watcher中的回调。注意,仅仅是通知而已,如果需要新的子节点列表,需要自己再次去获取。允许传入null。</p><p>&nbsp;&nbsp;&nbsp;&nbsp;                                        watch 表明是否需要注册一个Watcher。为true则通知默认到默认watcher,如果为false则不使用</p><p>&nbsp;&nbsp;&nbsp;&nbsp;                                        cb 回掉函数</p><p>&nbsp;&nbsp;&nbsp;&nbsp;                                        ctx 上下文对象</p><p>&nbsp;&nbsp;&nbsp;&nbsp;                                        stat 指定数据节点的状态信息。用法是在接口中传入一个旧的stat变量,该stat变量会在方法执行过程中,被来自服务端响应的新stat对象替换。</p><p style="text-align: center;"><span style="color: rgb(0, 209, 0);"><span style="text-align: center;">=======================================================</span>&nbsp;&nbsp;&nbsp;&nbsp;</span><br  /></p><p><strong>⑤getData</strong></p><p>&nbsp;&nbsp;&nbsp;&nbsp;                                //同步方式</p><p>&nbsp;&nbsp;&nbsp;&nbsp;                                byte [] getData(final String path,Watcher watcher, Stat stat)</p><p>&nbsp;&nbsp;&nbsp;&nbsp;                                byte [] getData(String path,boolean watch, Stat stat)</p><p>&nbsp;&nbsp;&nbsp;&nbsp;                                //异步方式</p><p>&nbsp;&nbsp;&nbsp;&nbsp;                                void getData(final String path,Watcher watcher, DataCallback cb,Object ctx)        </p><p>&nbsp;&nbsp;&nbsp;&nbsp;                                void getData(String path,boolean watch, DataCallback cb,Object ctx)        </p><p>&nbsp;&nbsp;&nbsp;&nbsp;<br  /></p><p>&nbsp; &nbsp; &nbsp;可以通过注册Watcher进行监听,一旦该节点数据被更新会通知客户端</p><p style="text-align: center;"><span style="color: rgb(0, 209, 0);"><span style="text-align: center;">=======================================================</span>&nbsp;&nbsp;&nbsp;&nbsp;</span><br  /></p><p><strong>⑥        更新数据</strong></p><p>&nbsp;&nbsp;&nbsp;&nbsp;                        //同步方式</p><p>&nbsp;&nbsp;&nbsp;&nbsp;                        Stat setData(final String path,byte data[],int version)//version可以传入-1,表明要基于最新版本进行更新操作</p><p>&nbsp;&nbsp;&nbsp;&nbsp;                        //异步方式</p><p>&nbsp;&nbsp;&nbsp;&nbsp;                        void setData(final String path,byte data[],int version,StatCallback cb,Object ctx)</p><p style="text-align: center;"><span style="color: rgb(0, 209, 0);text-align: center;">=======================================================</span><span style="color: rgb(0, 209, 0);text-align: center;">&nbsp; &nbsp;&nbsp;</span>&nbsp;&nbsp;&nbsp;&nbsp;                                        </p><p><strong>⑦        检查节点是否存在</strong></p><p>&nbsp;&nbsp;&nbsp;&nbsp;                        //同步方式</p><p>&nbsp;&nbsp;&nbsp;&nbsp;                        public Stat exists(final String path,Watcher watcher)</p><p>&nbsp;&nbsp;&nbsp;&nbsp;                        public Stat exists(String path,boolean watch)</p><p>&nbsp;&nbsp;&nbsp;&nbsp;                        //异步方式</p><p>&nbsp;&nbsp;&nbsp;&nbsp;                        public Stat exists(final String path,Watcher watcher,StatCallback cb,Object ctx)</p><p>&nbsp;&nbsp;&nbsp;&nbsp;                        public Stat exists(String path,boolean watch,StatCallback cb,Object ctx)</p><p>&nbsp;&nbsp;&nbsp;&nbsp;<br  /></p><p>&nbsp; &nbsp; &nbsp;可以通过注册Watcher进行监听,一旦节点被创建、删除、数据被更新都会通知客户端</p><p style="text-align: center;"><span style="color: rgb(0, 209, 0);"><span style="text-align: center;">=======================================================</span>&nbsp;&nbsp;&nbsp;&nbsp;</span><br  /></p><p><strong>⑧        zookeeper权限控制:</strong></p><p>&nbsp;&nbsp;&nbsp;&nbsp;                        addAuthInfo(String schema,byte [] auth)</p><p><strong>参数说明;</strong></p><p>&nbsp;&nbsp;&nbsp;&nbsp;                                schema 权限模式,可以是world auth digest ip super,我们使用digest</p><p>&nbsp;&nbsp;&nbsp;&nbsp;                                byte[] auth 权限控制标识,由"foo:123".getByte()方式组成,后续操作只有auth值相同才可以进行</p><p>&nbsp;&nbsp;&nbsp;&nbsp;<br  /></p><p><strong>注意:</strong></p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;删除操作,如果在增加节点时指定了权限,则对于删除操作,认为权限加在了子节点上,删除当前结点不需要权限,删除子节点需要权限。</p><p style="text-align: center;"><span style="text-align: center;white-space: pre;color: rgb(0, 209, 0);">=======================================================</span></p><p><strong><span style="color: rgb(0, 82, 255);">7.zookeeper原理</span></strong><br  /></p><p>                        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;zookeeper为了保证可靠性,不能用一台机器,而应该是一个集群。</p><p>                        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;为了保证zookeeper集群数据能够一致,必须有一个拍板说了算的人,这就是leader,其他的是follower。</p><p>                        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;某一时刻集群里只能有且仅有一个leader。</p><p>                        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;leader可以执行增删改和查询操作,而follower只能进行查询操作。</p><p>                        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;所有的更新操作都会被转交给leader来处理,leader批准的任务,再发送给follower去执行来保证和leader的一致性。</p><p>                        由于网络是不稳定的,为了保证执行顺序的一致,所有的任务都会被赋予一个唯一的顺序的编号,一定是按照这个编号来执行任务,保证任务顺序的一致性。</p><p>                        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;那么什么时候leader可以认为一个客户端的请求可以算是处理成功了呢?</p><p>                        如果只有leader或少数机器来认可这个任务,则leader和这些少量机器如果挂掉,则选出来的新的leader并不知道之前批准过的这个任务,最终会违反数据的可靠性。</p><p>                        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;所以要求leader在批准一个任务之前应该保证集群里大部分的机器应该是知道这个提案的,这样即使自己挂掉,根据过半同意选出来的leader肯定是知道这个提案的。</p><p>                        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;而如果leader一定要等到所有follower都同一才执行提案也不好,因为知道有一个机器挂掉,leader就无法工作,也相当于单节点了,无法保证集群可靠性。</p><p>                        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;所以,只要过半同一leader就可以认为一个提案通过。</p><p>                        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;所以,leader在收到客户端提交过来的任务后,会向集群中所有的follower发送提案等待follower的投票,follower们收到这个提议后,会进行投票,同意或者不同意,leader会回收follower的投票,一旦受到过半的投票表示同意,则leader认为这个提案通过,再发送命令要求所有的follower都进行这个提案中的任务。</p><p>                        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;由于需要过半的机器同意才能执行任务,所以一旦集群中过半的机器挂掉,整个集群就无法工作了。</p><p><br  /></p><p>                        <strong>从而可以推导出:</strong></p><p>                                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;zookeeper集群必须保证过半存活才能工作。</p><p>                                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;zookeeper的集群中的机器数量最好应该是奇数个,因为需要过半存活集群才能工作,所以偶数个机器提供的集群可靠性其实和偶数-1个机器提供的集群可靠性是一样的。</p><p><br  /></p><p>                                        </p><p><strong>leader选举的问题:</strong></p><p>                                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;最开始集群启动时,会选择最先启动的机器作为leader。</p><p>                                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;当leader挂掉后,会通过过半投票选出具有最高任务编号的称为新的leader。</p><p><span class="Apple-tab-span" style="white-space:pre;">        </span></p><p><span style="color: rgb(255, 79, 121);">五、zebra中zookeeper的应用</span></p><p><strong>1.监测集群中集群的存活状态</strong></p><p><span class="Apple-tab-span" style="white-space:pre;">        </span>在一级引擎和二级引起启动时 要求去zookeeper中创建临时节点,表明自己已经启动了</p><p>zebra</p><p><span class="Apple-tab-span" style="white-space:pre;">        </span>|-jb</p><p><span class="Apple-tab-span" style="white-space:pre;">                </span>|--jb_000001</p><p><span class="Apple-tab-span" style="white-space:pre;">        </span>|-engin1</p><p><span class="Apple-tab-span" style="white-space:pre;">                </span>|--engin1_0000001 - xxx &nbsp;:xx</p><p><span class="Apple-tab-span" style="white-space:pre;">                </span>|--engin1_0000002</p><p><span class="Apple-tab-span" style="white-space:pre;">        </span>|-engin2</p><p><span class="Apple-tab-span" style="white-space:pre;">                </span>|--egin2_0000001</p><p><br  /></p><p><strong>2.数据的订阅与发布</strong>&nbsp;</p><p>-- 将zebra的配置信息提取到zookeeper中来管理</p><p><br  /></p><p>zebra&nbsp;</p><p>- paths:/root/work/data/zebra/103_20150615143630_00_00_000.csv</p><p><span class="Apple-tab-span" style="white-space:pre;">        </span>|-jb - port:6666</p><p><span class="Apple-tab-span" style="white-space:pre;">                </span>|--jb_00001 - ip:xxxx</p><p><span class="Apple-tab-span" style="white-space:pre;">        </span>|-engin1 - port:9999</p><p><span class="Apple-tab-span" style="white-space:pre;">                </span>|--engin1_000001 - ip:xxxxx,port:9999</p><p><span class="Apple-tab-span" style="white-space:pre;">        </span>|-engin2 - port:8888,</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dirverName=com.mysql.jdbc.Driver,</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jdbcUrl=jdbc:mysql://192.168.242.1:3306/zebra,</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;username=root,password=root</p><p><br  /></p><p><span class="Apple-tab-span" style="white-space:pre;">        </span>engin1, engin2在启动时通过读取zookeeper中的自己的节点来获取配置信息。</p><p><span class="Apple-tab-span" style="white-space:pre;">        </span>engin1 engin2在启动时需要在 对应目录下 创建顺序临时节点表明自己存活,并且要在其中写入自己的ip 和 端口。</p><p><span class="Apple-tab-span" style="white-space:pre;">        engin2</span>在启动时还要获取 zk中/zebra/engin1的所有子节点 从而获知一级引擎有几个,以及每个的ip和端口</p><p><span class="Apple-tab-span" style="white-space: pre;">        </span>engin1 在启动时还需要获取 zk中的/zebra/engin2的所有子节点 从而获知二级引擎有几个,以及每个的ip和端口</p><p><br  /></p><hr style="font-size: 16px;white-space: normal;max-width: 100%;color: rgb(62, 62, 62);background-color: rgb(255, 255, 255);box-sizing: border-box !important;word-wrap: break-word !important;"  /><hr style="font-size: 16px;white-space: normal;max-width: 100%;color: rgb(62, 62, 62);background-color: rgb(255, 255, 255);box-sizing: border-box !important;word-wrap: break-word !important;"  /><hr style="font-size: 16px;white-space: normal;max-width: 100%;color: rgb(62, 62, 62);background-color: rgb(255, 255, 255);box-sizing: border-box !important;word-wrap: break-word !important;"  /><hr style="font-size: 16px;white-space: normal;max-width: 100%;color: rgb(62, 62, 62);background-color: rgb(255, 255, 255);box-sizing: border-box !important;word-wrap: break-word !important;"  /><hr style="font-size: 16px;white-space: normal;max-width: 100%;color: rgb(62, 62, 62);background-color: rgb(255, 255, 255);box-sizing: border-box !important;word-wrap: break-word !important;"  /><hr style="font-size: 16px;white-space: normal;max-width: 100%;color: rgb(62, 62, 62);background-color: rgb(255, 255, 255);box-sizing: border-box !important;word-wrap: break-word !important;"  /><hr style="font-size: 16px;white-space: normal;max-width: 100%;color: rgb(62, 62, 62);background-color: rgb(255, 255, 255);box-sizing: border-box !important;word-wrap: break-word !important;"  /><hr style="font-size: 16px;white-space: normal;max-width: 100%;color: rgb(62, 62, 62);background-color: rgb(255, 255, 255);box-sizing: border-box !important;word-wrap: break-word !important;"  /><hr style="font-size: 16px;white-space: normal;max-width: 100%;color: rgb(62, 62, 62);background-color: rgb(255, 255, 255);box-sizing: border-box !important;word-wrap: break-word !important;"  /><hr style="font-size: 16px;white-space: normal;max-width: 100%;color: rgb(62, 62, 62);background-color: rgb(255, 255, 255);box-sizing: border-box !important;word-wrap: break-word !important;"  /><hr style="font-size: 16px;white-space: normal;max-width: 100%;color: rgb(62, 62, 62);background-color: rgb(255, 255, 255);box-sizing: border-box !important;word-wrap: break-word !important;"  /><hr style="font-size: 16px;white-space: normal;max-width: 100%;color: rgb(62, 62, 62);background-color: rgb(255, 255, 255);box-sizing: border-box !important;word-wrap: break-word !important;"  /><hr style="font-size: 16px;white-space: normal;max-width: 100%;color: rgb(62, 62, 62);background-color: rgb(255, 255, 255);box-sizing: border-box !important;word-wrap: break-word !important;"  /><hr style="font-size: 16px;white-space: normal;max-width: 100%;color: rgb(62, 62, 62);background-color: rgb(255, 255, 255);box-sizing: border-box !important;word-wrap: break-word !important;"  /><hr style="font-size: 16px;white-space: normal;max-width: 100%;color: rgb(62, 62, 62);background-color: rgb(255, 255, 255);box-sizing: border-box !important;word-wrap: break-word !important;"  /><hr style="font-size: 16px;white-space: normal;max-width: 100%;color: rgb(62, 62, 62);background-color: rgb(255, 255, 255);box-sizing: border-box !important;word-wrap: break-word !important;"  /><p style="font-size: 16px;white-space: normal;max-width: 100%;min-height: 1em;color: rgb(62, 62, 62);background-color: rgb(255, 255, 255);box-sizing: border-box !important;word-wrap: break-word !important;"><span style="max-width: 100%;line-height: 25.6px;color: rgb(0, 128, 255);box-sizing: border-box !important;word-wrap: break-word !important;">请扫描下面二维码,关注该微信公众号,获取更多</span><span style="max-width: 100%;line-height: 25.6px;color: rgb(255, 41, 65);box-sizing: border-box !important;word-wrap: break-word !important;"><strong style="max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;">生物医学工程</strong>专业及<strong style="max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;">医工</strong><span style="max-width: 100%;line-height: 25.6px;color: rgb(0, 128, 255);box-sizing: border-box !important;word-wrap: break-word !important;">学习笔记</span>:</span><span style="max-width: 100%;color: rgb(0, 0, 0);box-sizing: border-box !important;word-wrap: break-word !important;"></span></p><p style="font-size: 16px;white-space: normal;max-width: 100%;min-height: 1em;color: rgb(62, 62, 62);line-height: 25.6px;background-color: rgb(255, 255, 255);box-sizing: border-box !important;word-wrap: break-word !important;"><span style="max-width: 100%;line-height: 25.6px;color: rgb(255, 41, 65);box-sizing: border-box !important;word-wrap: break-word !important;"></span></p><p style="font-size: 16px;white-space: normal;max-width: 100%;min-height: 1em;color: rgb(62, 62, 62);line-height: 25.6px;text-align: center;background-color: rgb(255, 255, 255);box-sizing: border-box !important;word-wrap: break-word !important;"><img class="" data-ratio="1" data-s="300,640" src="http://mmbiz.qpic.cn/mmbiz_jpg/LKgI6UN8ElZnh0jXF3PjbBz7BBPnYH7wbDgfc3E2r7REMuN2lQqfuVM38HZO8Zx0rN0OLKywrjoH3P7QqDY44Q/640?wx_fmt=jpeg" data-type="jpeg" data-w="430" width="auto" style="box-sizing: border-box !important;word-wrap: break-word !important;visibility: visible !important;width: auto !important;"  /></p><p><br  /></p>
               
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|Comsenz Inc. ( 浙ICP备17000336号-1 )

GMT+8, 2025-3-11 01:36 , Processed in 0.076440 second(s), 33 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表