• 一致性hash


    在缓存场景中,一致性hash算法避免了余数法在因为节点失效导致大面积缓存失效的问题。
    直接上代码,使用了Java自带的TreeMap, 参考了dubbo代码中的一致性hash负载
     1 package org.example;
     2 
     3 import java.nio.charset.StandardCharsets;
     4 import java.security.MessageDigest;
     5 import java.security.NoSuchAlgorithmException;
     6 import java.util.*;
     7 
     8 public class ConsistentHash<T> {
     9 
    10     private int VIRTUAL_NODE_NUM = 40;
    11     private final TreeMap<Long, T> circle = new TreeMap<>();
    12 
    13     public ConsistentHash(List<T> nodes, int VIRTUAL_NODE_NUM) {
    14         this.VIRTUAL_NODE_NUM = VIRTUAL_NODE_NUM;
    15         for (T node : nodes) {
    16             for (int i = 0; i < VIRTUAL_NODE_NUM; i++) {
    17                 byte[] digest = md5(node.toString() + i);
    18                 for (int h = 0; h < 4; h++) {
    19                     long m = hash(digest, h);
    20                     circle.put(m, node);
    21                 }
    22             }
    23         }
    24     }
    25 
    26     public T get(Object key) {
    27         if (circle.isEmpty()) {
    28             return null;
    29         }
    30         byte[] digest = md5(key.toString());
    31         long hash = hash(digest, 0);
    32         Map.Entry<Long, T> entry = circle.ceilingEntry(hash);
    33         if (entry == null) {
    34             entry = circle.firstEntry();
    35         }
    36         return entry.getValue();
    37     }
    38 
    39 
    40     private long hash(byte[] digest, int number) {
    41         return (((long) (digest[3 + number * 4] & 0xFF) << 24)
    42                 | ((long) (digest[2 + number * 4] & 0xFF) << 16)
    43                 | ((long) (digest[1 + number * 4] & 0xFF) << 8)
    44                 | (digest[number * 4] & 0xFF))
    45                 & 0xFFFFFFFFL;
    46     }
    47 
    48     private byte[] md5(String value) {
    49         MessageDigest md5;
    50         try {
    51             md5 = MessageDigest.getInstance("MD5");
    52         } catch (NoSuchAlgorithmException e) {
    53             throw new IllegalStateException(e.getMessage(), e);
    54         }
    55         md5.reset();
    56         byte[] bytes = value.getBytes(StandardCharsets.UTF_8);
    57         md5.update(bytes);
    58         return md5.digest();
    59     }
    60 }
  • 相关阅读:
    Angular与PHP之间的不同的请求方式(post/get)导致的传参问题
    项目当中会使用到的---获取主机名
    JavaScript eval() 函数
    PHP 数组排序
    PHP Switch 语句
    PHP strlen()函数和strpos()函数
    Array.prototype.map()和Array.prototypefilter()
    25.参考链接
    24.ArrayBuffer
    23.读懂 ECMAScript 规格
  • 原文地址:https://www.cnblogs.com/beyondbit/p/13222530.html
Copyright © 2020-2023  润新知