C# servicestack.redis 互連 java jedis

來源:互聯網
上載者:User

標籤:node   frame   ima   sage   dig   result   ted   nuget   size   

擁抱變化,如今也走上了.net/java通吃的時代,下面就講講如何讓.net/java都能正常訪問分區的redis吧。

有幾個關鍵點:一致性環雜湊、雜湊演算法、序列化、還原序列化

後兩個都比較直接,只要選擇一種跨語言的序列化方式就行了,如:json, protobuf, ace等,本文全略了

 

本文是基於jedis的一致性環雜湊來修改的,.net選的是servicestack.redis組件來修改

無奈兩個組件都有各自的一致性環雜湊演算法,不相容,那就選一個作為標準,修改另一個咯。本文選擇jedis的一致性環雜湊作為標準,進而修改.net來適應jedis

jedis的邏輯是給每個redis節點構造160個虛擬節點,放入一顆二叉樹中(key/value:key是一個long值,根據雜湊演算法算出來的一個long、value是節點id,是個string)。

OK,邏輯清楚了,那就簡單了,給c#端寫個一模一樣的一致性環雜湊演算法。

public class Sharded    {        private object nodes_lock = new object();        private RedBlackTreeMap<long, string> nodes = new RedBlackTreeMap<long, string>();        private IHash hashAlgo = new MD5_LongSUM_Multiply_Hash();                public void AddTarget(int index, string shard)        {            lock (nodes_lock)            {                for (int n = 0; n < 160; ++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");        }    }

 

其中RedBlackTreeMap這個是TreeLib中的組件,需要在nuget上引用。

MD5_LongSUM_Multiply_Hash,這是個MD5演算法,輸入為string,輸出為long。
此處由於考慮到輸出不是string,因此自己又改了改,讓他輸出long
public 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 < data.Length; i++)            {                sBuilder.Append(data[i].ToString("x2"));            }            return sBuilder.ToString();        }    }

 

剩下的就是java端的這個輸入string,輸出long的演算法,需要和.net的輸入輸出一致了。

那就也寫一個雜湊演算法,讓他輸入string,輸出long,和.net的一致,這裡只要java/.net用同一種md5演算法,後續的md5變成long就很容易了。

import 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;    }}

 

<dependency>            <groupId>org.springframework.security</groupId>            <artifactId>spring-security-core</artifactId>        </dependency>

 

OK,核心的就這些了。

 

C# servicestack.redis 互連 java jedis

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.