网站开发和ipv6,北京专业网站搭建公司,权重网站建设,织梦可以做大型网站吗最近在读hbase源码关于rpc的一些实现细节#xff0c;想正好趁此机会和大家分享一下我理解到的hbase关于Nonce机制的实现。Nonce机制的来源Nonce这个词由来已久#xff0c;且在各个领域都会有相对应的名词解释。对于HBase来说#xff0c;由于网络环境的复杂性#xff0c;在客…最近在读hbase源码关于rpc的一些实现细节想正好趁此机会和大家分享一下我理解到的hbase关于Nonce机制的实现。Nonce机制的来源Nonce这个词由来已久且在各个领域都会有相对应的名词解释。对于HBase来说由于网络环境的复杂性在客户端调用rpc像服务器发送请求时随时都有丢失该请求的风险。对于客户端发出的一个请求来说客户端只会收到三种结果服务端响应成功、服务端响应失败、请求超时。在一个并不可靠的网络连接下请求超时是经常会发生的对此HBase中有相应的Retry机制保证一个请求可以顺利被发送到服务端然而对于Append、Increment这样的非幂等操作在HBase中被称为Delta操作来说一个被服务端重复接收的请求带来的后果无疑是灾难性的。于是Nonce机制便应运而生。Nonce机制的实现下面进入正题关于Nonce机制如何在HBase中实现我将从提出问题-解决问题的角度简单分析HBase中对于“delta”操作的实现过程。第一步 现在假设我是一个客户端那么对于我来说最重要的事就是要去区分我发送的多个请求所以我要为我发送的每一个请求分配一个id并且保证这些请求的id都是唯一的对于这个要求我们可以简单的使用jdk中的Random类来实现随机生成不重复的long型数字作为请求的id。第二步 现在我们已经实现了用一个id标示一个客户端的不同请求但是对于一个server来说他会收到来自超级多的客户端发送的请求那么就会不可避免的遇到不同客户端发送的请求中会有id重复的问题。所以解决问题的方式也非常简单就是为每一个客户端也生成一个id去标识这样就可以通过一个客户端id和一个请求id来全局唯一的标识一个服务端收到的请求了HBase的服务端中用来标识请求的类被称为NonceKey其中核心的两个成员变量便是客户端id和请求id即nonce值在HBase3的版本中这个唯一的客户端id的生成方式是使用client id的哈希值加一个随机数第三步 有了前面两步我们现在已经知道一个server是如何区分请求的问题了接下来我们关注服务端如何对请求进行nonce处理的问题。服务端有一个核心的管理器叫ServerNonceManager他掌握着一个请求是否被执行的“生杀大权”在这个类的内部有一个核心容器ConcurrentHashMapNonceKey, OperationContext其中NonceKey就是我们在上两步中说的用于标识一个请求的key而OperationContext代表着这个请求进行的操作的具体信息其中有这个操作的执行状态三种执行状态DONT_PROCEED、PROCEED和WAIT这三种执行状态中DONT_PROCEED代表已经执行成功不需要再次执行了PROCEED表示已经被执行但是执行失败了WAIT表示这个请求正在等待其他请求执行结束后再执行。所以对于ServerNonceManager来说他要做的事情就是判断一个请求是否可以被执行。对于这个问题他首先根据NonceKey去map中找是否之前收到过相同NonceKey的请求如果没有则代表这个请求可以被执行因为之前没有被重复提交的请求如果map中有相同NonceKey的请求则说明这个请求由于网络问题被重复发送了这时候manager就要通过map中已有的这个请求的状态来判断了 1. 如果这个已有的请求状态为wait则代表请求还在等待执行于是接着等待而直接丢弃新来的请求 2. 如果这个已有请求的状态为DONT_PROCEED则代表请求已经执行完毕不执行新请求 3. 如果这个已有请求的状态为PROCEED则代表请求已经执行完毕并且执行失败了则将会执行新请求。另外为了防止这个map无限扩张ServerNonceManager将会对其进行定期清理默认半个小时第四步 我们通过前三步已经了解到了一个ServerNonceManager是如何构建起来的以及如何解决问题的。于是问题就简单了当服务端收到一个delta请求时首先会根据ServerNonceManager反馈的结果若不能执行便直接丢弃允许执行才会进行接下来的处理逻辑。以上便是我对于HBase中实现Nonce机制的一些思考。