基于murmurhash+list实现一致性hash(代码片段)

author author     2022-12-14     684

关键词:

一致性Hash原理这里不再介绍了,下面是一个简单版的实现方案。

1、MurmurHashUtils

package com.jane.pos.sync.utils;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;

/**
 * 利用murmurHash实现高性能的低碰撞的纯数字hash值
 */
public class MurmurHashUtils 

    private static final String UTF_8 = "UTF-8";

    public static long hash64A(byte[] data, int seed) 
        return hash64A(ByteBuffer.wrap(data), seed);
    

    public static long hash64A(ByteBuffer buf, int seed) 
        ByteOrder byteOrder = buf.order();
        buf.order(ByteOrder.LITTLE_ENDIAN);

        long m = 0xc6a4a7935bd1e995L;
        int r = 47;

        long h = seed ^ (buf.remaining() * m);

        long k;
        while (buf.remaining() >= 8) 
            k = buf.getLong();

            k *= m;
            k ^= k >>> r;
            k *= m;

            h ^= k;
            h *= m;
        

        if (buf.remaining() > 0) 
            ByteBuffer finish = ByteBuffer.allocate(8).order(ByteOrder.LITTLE_ENDIAN);
            // for big-endian version, do this first:
            // finish.position(8-buf.remaining());
            finish.put(buf).rewind();
            h ^= finish.getLong();
            h *= m;
        

        h ^= h >>> r;
        h *= m;
        h ^= h >>> r;

        buf.order(byteOrder);
        return h;
    

    public static long hash(byte[] key) 
        return hash64A(key, 0x1234ABCD);
    

    public static long hash(String key) 
        return hash(encode(key));
    

    /**
     * Long转换成无符号长整型(C中数据类型)
     */
    public static BigDecimal readUnsignedLong(long value) 
        if (value >= 0)
            return new BigDecimal(value);
        long lowValue = value & 0x7fffffffffffffffL;
        return BigDecimal.valueOf(lowValue).add(BigDecimal.valueOf(Long.MAX_VALUE)).add(BigDecimal.valueOf(1));
    

    /**
     * 返回无符号murmur hash值
     */
    public static BigDecimal hashUnsigned(String key) 
        return readUnsignedLong(hash(key));
    

    public static BigDecimal hashUnsigned(byte[] key) 
        return readUnsignedLong(hash(key));
    

    private static byte[] encode(String data) 
        try 
            return data.getBytes(UTF_8);
         catch (UnsupportedEncodingException e) 
            throw new IllegalArgumentException(e);
        
    

2、HashUtils

package com.jane.pos.sync.utils;

import java.math.BigDecimal;
import java.util.*;

public class HashUtils 

    /**
     * 真实节点虚拟化,为了节点分布均衡
     * @param realNodes 真实节点列表
     * @param inventedNum 每个节点虚拟的节点个数
     * @param hashList 用数组模拟hash环
     * @return
     */
    public static Map<BigDecimal, String> inventedNodes(String[] realNodes, int inventedNum, List<BigDecimal> hashList) 
        //虚拟点和真实节点的对应关系
        Map<BigDecimal, String> map = new HashMap<>();
        if(realNodes.length > 0) 
            for (String node : realNodes) 
                for(int i = 1; i <= inventedNum; i++) 
                    BigDecimal hashCode = MurmurHashUtils.hashUnsigned(node + i);
                    map.put(hashCode, node);
                    //组建hash值数组,模拟hash环
                    hashList.add(hashCode);
                
            
        

        return map;
    

    /**
     * 根据key获取固定的一致性节点
     * @param realNodes 真实节点
     * @param inventedNum 虚拟的节点数量
     * @param key hash的key,这个key对应一个固定的唯一的真实节点
     * @return
     */
    public static String getFixedOnlyNode(String[] realNodes, int inventedNum, String key) 
        List<BigDecimal> hashList = new ArrayList<>();
        Map<BigDecimal, String> map = inventedNodes(realNodes, inventedNum, hashList);
        //hash数组排序
        Collections.sort(hashList);
        BigDecimal findHash = MurmurHashUtils.hashUnsigned(key);
        for(BigDecimal item : hashList)
            //第一个大的节点,即为要的节点
            if(item.compareTo(findHash) == 1 ) 
                return map.get(item);
            
        
        //未命中的key,对节点取余当作下标,获取真实节点
        return map.get(findHash.divideAndRemainder(BigDecimal.valueOf(hashList.size()))[1]);
    


3、启动文件

public static void main(String[] args) throws InterruptedException 

        String storeNo = "store";
        String[] nodes = "tag01","tag02","tag03","tag04","tag05";
        for (int i = 0; i <= 10; i++)
            String key = storeNo + i;
            for (int j = 0; j <= 10; j++) 
                String node = HashUtils.getFixedOnlyNode(nodes, 10, key);
                System.out.println(key + "----" + node);
            
        
    

4、结果

store0----tag01
store0----tag01
store0----tag01
store0----tag01
store0----tag01
store0----tag01
store0----tag01
store0----tag01
store0----tag01
store0----tag01
store0----tag01
store1----tag03
store1----tag03
store1----tag03
store1----tag03
store1----tag03
store1----tag03
store1----tag03
store1----tag03
store1----tag03
store1----tag03
store1----tag03
store2----tag01
store2----tag01
store2----tag01
store2----tag01
store2----tag01
store2----tag01
store2----tag01
store2----tag01
store2----tag01
store2----tag01
store2----tag01
store3----tag01
store3----tag01
store3----tag01
store3----tag01
store3----tag01
store3----tag01
store3----tag01
store3----tag01
store3----tag01
store3----tag01
store3----tag01
store4----tag02
store4----tag02
store4----tag02
store4----tag02
store4----tag02
store4----tag02
store4----tag02
store4----tag02
store4----tag02
store4----tag02
store4----tag02
store5----tag05
store5----tag05
store5----tag05
store5----tag05
store5----tag05
store5----tag05
store5----tag05
store5----tag05
store5----tag05
store5----tag05
store5----tag05
store6----tag01
store6----tag01
store6----tag01
store6----tag01
store6----tag01
store6----tag01
store6----tag01
store6----tag01
store6----tag01
store6----tag01
store6----tag01
store7----tag05
store7----tag05
store7----tag05
store7----tag05
store7----tag05
store7----tag05
store7----tag05
store7----tag05
store7----tag05
store7----tag05
store7----tag05
store8----tag05
store8----tag05
store8----tag05
store8----tag05
store8----tag05
store8----tag05
store8----tag05
store8----tag05
store8----tag05
store8----tag05
store8----tag05
store9----tag02
store9----tag02
store9----tag02
store9----tag02
store9----tag02
store9----tag02
store9----tag02
store9----tag02
store9----tag02
store9----tag02
store9----tag02
store10----tag03
store10----tag03
store10----tag03
store10----tag03
store10----tag03
store10----tag03
store10----tag03
store10----tag03
store10----tag03
store10----tag03
store10----tag03

julia实现基于双序列比对(pairwisesequencealignment)计算蛋白序列间一致性(identity)

待补充 查看详情

简陋版一致性hash算法实现

1publicfunctionhashAction(){2$server_list=range(14,114);3$server_slot=$this->hashAri($server_list);4$key_list=range(1,100000);5$key_slot=$this->hashAri($key_list);67//分配位子8$result=$this->hash 查看详情

js实现存储对象的数据结构hashtable和list

...找,同时key是区分大小写;value用于存储对应于key的值。实现该数据结构的几个方法:函数名说明返回值set(key,value)添加项无del(key)根据key删除一项无has(key)是否 查看详情

分布式锁与实现——基于redis实现

...大型网站及应用都是分布式部署的,分布式场景中的数据一致性问题一直是一个比较重要的话题。分布式的CAP理论告诉我们“任何一个分布式系统都无法同时满足一致性(Consistency)、可用性(Availability)和分区容错性(Partitiont... 查看详情

使用springcache实现广告缓存并基于rabbitmq实现双写一致

使用SpringCache实现广告缓存并基于RabbitMQ实现双写一致一、SpringCache简介1.SpringCache介绍​SpringCache是Spring-context-xxx.jar中提供的功能,可以结合EHCache,Redis等缓存工具使用。给用户提供非常方便的缓存处理,缓存基本判断等操作,可... 查看详情

MurmurHash - 它是啥?

】MurmurHash-它是啥?【英文标题】:MurmurHash-whatisit?MurmurHash-它是什么?【发布时间】:2012-08-0715:14:09【问题描述】:我一直试图对MurmurHash的作用有一个更高层次的理解。我已阅读基本说明,但尚未找到关于何时使用它以及为什... 查看详情

使用springcache实现广告缓存并基于rabbitmq实现双写一致

使用SpringCache实现广告缓存并基于RabbitMQ实现双写一致一、SpringCache简介1.SpringCache介绍​SpringCache是Spring-context-xxx.jar中提供的功能,可以结合EHCache,Redis等缓存工具使用。给用户提供非常方便的缓存处理,缓存基本判断等操作,可... 查看详情

使用springcache实现广告缓存并基于rabbitmq实现双写一致

使用SpringCache实现广告缓存并基于RabbitMQ实现双写一致一、SpringCache简介1.SpringCache介绍​SpringCache是Spring-context-xxx.jar中提供的功能,可以结合EHCache,Redis等缓存工具使用。给用户提供非常方便的缓存处理,缓存基本判断等操作,可... 查看详情

97基于binlog实现mysql与redis数据一致性问题

参考技术Amysql与Redis数据一致性问题直接将Redis清空中间件canal框架基于docker环境构建canal框架原理:<u>https://gitee.com/mirrors/canal?utm_source=alading&utm_campaign=repo</u>canal框架原理1,canal伪装成mysql从节点订阅mysql主节点的binlog文... 查看详情

分布式锁-三种实现方式简述

...大型网站及应用都是分布式部署的,分布式场景中的数据一致性问题一直是一个比较重要的话题。分布式的CAP理论告诉我们“任何一个分布式系统都无法同时满足一致性(Consistency)、可用性(Avai 查看详情

分布式锁-三种实现方式简述

...网站及应用都是分布式部署的,分布式场景中的数据一致性问题一直是一个比较重要的话题。分布式的CAP理论告诉我们“任何一个分布式系统都无法同时满足一致性& 查看详情

有关如何使用has_many:through关系正确设置验证的指导?(代码片段)

...t_id,uniqueness:scope::user_idend正如您所看到的,我希望列表项基于其标题是唯一的。换句话说,如果用户Adam添加了标题为“黑暗骑士”的列表,那 查看详情

如何选择分布式事务形态(tcc,saga,2pc,基于消息最终一致性等等)(代码片段)

分布式事务有多种主流形态,包括:基于消息实现的分布式事务基于补偿实现的分布式事务基于TCC实现的分布式事务基于SAGA实现的分布式事务基于2PC实现的分布式事务这些形态的原理已经在很多文章中进行了剖析,用“分布式... 查看详情

它说 AttributeError: 'list' object has no attribute 'sample'

】它说AttributeError:\\\'list\\\'objecthasnoattribute\\\'sample\\\'【英文标题】:ItsaysAttributeError:\'list\'objecthasnoattribute\'sample\'它说AttributeError:\'list\'objecthasnoattribute\'sample\'【发布时间】:2022-01-1000:58:40【问题描述】:我正在 查看详情

使用高效的 `has` 操作实现堆栈

】使用高效的`has`操作实现堆栈【英文标题】:Implementastackwithaefficient`has`operation【发布时间】:2021-09-1522:37:42【问题描述】:我需要一个具有3个操作的数据结构:1.push,2.pop3.has。它就像一个具有类似集合元素查找的堆栈。如果... 查看详情

基于spring+mybatis+atomikos+jta实现分布式事务

...pper绑定在不同的数据源上,通过atomikos可实现分布式事务一致性。版本:spring-3.2.9.RELEASE、mybatis-3.4.4、atomikos-4.0.5、jdk1.81,maven配置文件pom.xml如下:<!--test-- 查看详情

分布式锁与实现——基于zookeeper实现

...,是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。ZooKeeper的架构通过冗余服务实现高可用性。因此,如果第一次无应答,客户端就可以... 查看详情

.netcorewith微服务-使用agiledt快速实现基于可靠消息的分布式事务

前面对于分布式事务也讲了好几篇了(可靠消息最终一致性分布式事务-TCC分布式事务-2PC、3PChttps://github.com/kklldog/AgileDT开源不易,大家多多✨✨✨回顾前面一篇文章(可靠消息最终一致性)我们详细介绍了基于可靠消息的分... 查看详情