java .net 互通redis_C# servicestack.redis 互通 java jedis

本文是基于jedis的一致性环哈希来修改的,.net选的是servicestack.redis组件来修改

无奈两个组件都有各自的一致性环哈希算法,不兼容,那就选一个作为标准,修改另一个咯。本文选择jedis的一致性环哈希作为标准,进而修改.net来适应jedis

jedis的逻辑是给每个redis节点构造160个虚拟节点,放入一颗二叉树中(key/value:key是一个long值,根据哈希算法算出来的一个long、value是节点id,是个string)。

OK,逻辑清楚了,那就简单了,给c#端写个一模一样的一致性环哈希算法。

copycode.gifpublic class Sharded

{        private object nodes_lock = new object();        private RedBlackTreeMap nodes = new RedBlackTreeMap();        private IHash hashAlgo = new MD5_LongSUM_Multiply_Hash();

public void AddTarget(int index, string shard)

{            lock (nodes_lock)

{                for (int n = 0; n 

{                    var hashKey = "SHARD-" + index + "-NODE-" + n;                    long hashValue = this.hashAlgo.Hash(hashKey);

nodes.SetOrAddValue(hashValue, shard);

}

}

}        public string GetShardInfo(string key)

{            long searchHashKey = this.hashAlgo.Hash(key);            long nearestKey;            string shard;            lock (nodes_lock)

{                if (this.nodes.NearestGreater(searchHashKey, out nearestKey))

{

shard = this.nodes.GetValue(nearestKey);                    return shard;

}                if (this.nodes.Least(out searchHashKey, out shard))                    return shard;

}            throw new Exception("GetShardInfo exception");

}

}

copycode.gif

其中RedBlackTreeMap这个是TreeLib中的组件,需要在nuget上引用。

68230-20170618222212696-555825592.pngMD5_LongSUM_Multiply_Hash,这是个MD5算法,输入为string,输出为long。

此处由于考虑到输出不是string,因此自己又改了改,让他输出long

copycode.gifpublic class MD5_LongSUM_Multiply_Hash : IHash

{        public long Hash(string key)

{            var md5= Md5Hash(key);            if (string.IsNullOrEmpty(md5))

Log.GetLog().Info("Hash, md5 is null or empty");            var convertedKeyBytes = Encoding.UTF8.GetBytes(md5);

long value = 1;            foreach(var b in convertedKeyBytes)

value *= b*-1;            return value;

}        private string Md5Hash(string input)

{

MD5CryptoServiceProvider md5Hasher = new MD5CryptoServiceProvider();            if (string.IsNullOrEmpty(input))

Log.GetLog().Info("Md5Hash, input is null or empty");            byte[] data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(input));

StringBuilder sBuilder = new StringBuilder();            for (int i = 0; i 

{

sBuilder.Append(data[i].ToString("x2"));

}            return sBuilder.ToString();

}

}

copycode.gif

剩下的就是java端的这个输入string,输出long的算法,需要和.net的输入输出一致了。

那就也写一个哈希算法,让他输入string,输出long,和.net的一致,这里只要java/.net用同一种md5算法,后续的md5变成long就很容易了。

copycode.gifimport org.springframework.security.authentication.encoding.MessageDigestPasswordEncoder;import redis.clients.util.Hashing;import redis.clients.util.SafeEncoder;import java.io.UnsupportedEncodingException;/**

* Created by z on 2017/4/12. */public class MD5_SUM_Hash implements Hashing {

MessageDigestPasswordEncoder encoder=new MessageDigestPasswordEncoder("MD5");    public long hash(String key) {        return this.hash(SafeEncoder.encode(key));

}    public long hash(byte[] bytes) {

String converted_str= null;        try {

converted_str = new String(bytes, "UTF8");

} catch (UnsupportedEncodingException e) {

e.printStackTrace();

}

String result=encoder.encodePassword(converted_str, null);        try {

bytes=result.getBytes("UTF8");

} catch (UnsupportedEncodingException e) {

e.printStackTrace();

}        long value = 1;        for(byte b : bytes)

value *= b*-1;        return value;

}

}

copycode.gif

org.springframework.security

spring-security-core

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值