查看“Zookeeper:分布式命名服务”的源代码
←
Zookeeper:分布式命名服务
跳到导航
跳到搜索
因为以下原因,您没有权限编辑本页:
您请求的操作仅限属于该用户组的用户执行:
用户
您可以查看和复制此页面的源代码。
[[category:Zookeeper]] __TOC__ == 关于“分布式命名服务” == <pre> “命名服务”是为系统中的资源提供标识能力。 </pre> ZooKeeper的命名服务主要是利用 '''ZooKeeper节点的树形分层结构和子节点的顺序'''维护能力,来为分布式系统中的资源命名。 === 应用场景 === '''分布式API目录''':为分布式系统中各种API接口服务的名称、链接地址,提供类似 JNDI(Java命名和目录接口)中的文件系统的功能。 : 借助于 ZooKeeper 的树形分层结构就能提供分布式的API调用功能。 * 著名的 Dubbo 分布式框架就是应用了 ZooKeeper 的分布式的 JNDI 功能,大致的思路为: *# 服务提供者(Service Provider)在启动的时候,向 ZooKeeper 上的指定节点“/dubbo/${serviceName}/providers”写入自己的API地址,这个操作就相当于服务的公开。 *# 服务消费者(Consumer)启动的时候,订阅节点“/dubbo/{serviceName}/providers”下的服务提供者的 URL 地址,获得所有服务提供者的API。 '''分布式的ID生成器''':在分布式系统中,为每一个数据资源提供唯一性的ID标识功能。 : 在单体服务环境下,通常来说,可以利用数据库的主键自增功能,唯一标识一个数据资源。但是,在大量服务器集群的场景下,依赖单体服务的数据库主键自增生成唯一ID的方式,则没有办法满足高并发和高负载的需求。这时,就需要分布式的ID生成器,保障分布式场景下的ID唯一性。 : 在分布式系统中,分布式ID生成器的使用场景非常之多: :* 大量的数据记录,需要分布式ID。 :* 大量的系统消息,需要分布式ID。 :* 大量的请求日志,如RESTful的操作记录,需要唯一标识,以便进行后续的用户行为分析和调用链路分析。 :* 分布式节点的命名服务,往往也需要分布式ID。 '''分布式节点的命名''':一个分布式系统通常会由很多的节点组成,节点的数量不是固定的,而是不断动态变化的。 : 比如说,当业务不断膨胀和流量洪峰到来时,大量的节点可能会动态加入到集群中。而一旦流量洪峰过去了,就需要下线大量的节点。再比如说,由于机器或者网络的原因,一些节点会主动离开集群。 : 如何为大量的动态节点命名呢?一种简单的办法是可以通过配置文件,手动为每一个节点命名。但是,如果节点数据量太大,或者说变动频繁,手动命名则是不现实的,这就需要用到分布式节点的命名服务。 === ID生成器 === 在分布式系统环境中,唯一ID系统需要满足以下需求: # 全局唯一:不能出现重复ID。 # 高可用:ID生成系统是基础系统,被许多关键系统调用,一旦宕机,就会造成严重影响。 很明显,传统的数据库自增主键或者单体的自增主键,已经不能满足需求。 可能的分布式ID生成器方案: # Java的UUID。 # 分布式缓存Redis生成ID:利用 Redis 的原子操作 '''INCR''' 和 '''INCRBY''',生成全局唯一的ID。 # Twitter 的 '''SnowFlake''' 算法。 # ZooKeeper 生成ID:利用'''ZooKeeper的顺序节点''',生成全局唯一的ID。 # MongoDb 的 ObjectId:【???】 #: MongoDB是一个分布式的非结构化 NoSQL 数据库,每插入一条记录会自动生成全局唯一的一个“_id”字段值,它是一个 12 字节的字符串,可以作为分布式系统中全局唯一的ID。 P.S. 关于“UUID”: <pre> UUID 是“Universally Unique Identifier”的缩写,它是在一定的范围内(从特定的名字空间到全球)唯一的机器生成的标识符,所以,UUID 在其他语言中也叫“GUID”。 在Java中,生成UUID的代码: String uuid = UUID.randomUUID().toString() UUID是经由一定的算法机器生成的,为了保证UUID的唯一性,规范定义了包括网卡MAC地址、时间戳、名字空间(Namespace)、随机或伪随机数、时序等元素,以及从这些元素生成UUID的算法。【UUID只能由计算机生成】 优点:UUID的优点是本地生成ID,不需要进行远程调用,时延低,性能高。 缺点: 1、UUID过长,16字节共128位,通常以36字节长的字符串来表示,在很多应用场景不适用。 2、UUID没有排序,无法保证趋势递增。 </pre> == Zookeeper:分布式命名服务 == ZooKeeper 实现分布式命名服务(分布式ID、分布式节点命名),主要是利用其'''顺序节点'''的特性: <pre> ZooKeeper 的每一个节点都会为它的第一级子节点维护一份顺序编号(自动为创建后的节点路径在末尾加上一个数字),用于记录每个子节点创建的先后顺序,这个顺序编号是分布式同步的,也是全局唯一的。 例如,在创建节点的时候只需要传入节点“/test_”,ZooKeeper自动会在“test_”后面补充数字顺序,例如“/test_0000000010”。 note:这个顺序值的最大上限就是整型的最大值。 </pre> 在 ZooKeeper 节点的四种类型中,有两种自动编号的节点: # '''PERSISTENT_SEQUENTIAL''':持久化顺序节点,节点持久有效,可用于实现“分布式ID”。 # '''EPHEMERAL_SEQUENTIAL''':临时顺序节点,节点随会话失效而删除,可用于实现“分布式节点命名”。 === 分布式ID === 通过创建ZooKeeper的持久化顺序节点的方法,生成全局唯一的ID。 实现: <syntaxhighlight lang="Java" highlight=""> package com.crazymakercircle.zk.NameService; import com.crazymakercircle.zk.ClientFactory; import org.apache.curator.framework.CuratorFramework; import org.apache.ZooKeeper.CreateMode; /** *生成分布式ID **/ public class IDMaker { //...省略其他的方法 /** * 创建持久化顺序节点 * @param pathPefix节点路径 * @return 创建后的完整路径名称 */ private String createSeqNode(String pathPefix) { try { // 创建一个ZNode顺序节点 String destPath = client.create() .creatingParentsIfNeeded() .withMode(CreateMode.PERSISTENT_SEQUENTIAL) .forPath(pathPefix); return destPath; } catch (Exception e) { e.printStackTrace(); } return null; } // 生成ID public String makeId(String nodeName) { // 创建新的zookeeper节点 String str = createSeqNode(nodeName); if (null == str) { return null; } // 截取新节点的末尾序号作为新ID int index = str.lastIndexOf(nodeName); if (index >= 0) { index += nodeName.length(); return index <= str.length() ? str.substring(index) : ""; } return str; } } </syntaxhighlight> 测试: <syntaxhighlight lang="Java" highlight=""> @Slf4j public class IDMakerTester { @Test public void testMakeId() { IDMaker idMaker = new IDMaker(); String nodeName = "/test/IDMaker/ID-"; for (int i = 0; i< 10; i++) { String id = idMaker.makeId(nodeName); log.info("第"+ i + "个创建的id为:" + id); } } } </syntaxhighlight> 结果: <syntaxhighlight lang="bash" highlight=""> 第0个创建的id为:0000000010 第1个创建的id为:0000000011 //…..省略其他的输出 </syntaxhighlight> === 分布式节点命名 === === SnowFlakeID 算法实现(分布式ID算法)===
返回至“
Zookeeper:分布式命名服务
”。
导航菜单
个人工具
登录
命名空间
页面
讨论
大陆简体
已展开
已折叠
查看
阅读
查看源代码
查看历史
更多
已展开
已折叠
搜索
导航
首页
最近更改
随机页面
MediaWiki帮助
笔记
服务器
数据库
后端
前端
工具
《To do list》
日常
阅读
电影
摄影
其他
Software
Windows
WIKIOE
所有分类
所有页面
侧边栏
站点日志
工具
链入页面
相关更改
特殊页面
页面信息