C# servicestack.redis 互通 java jedis
2023-09-14 08:57:46 时间
拥抱变化,如今也走上了.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,核心的就这些了。
相关文章
- Java Magic. Part 4: sun.misc.Unsafe
- java -version 问题 : C:ProgramDataOracleJavajavapath;
- Java实现 LeetCode 725 分隔链表(暴力)
- Java实现 LeetCode 419 甲板上的战舰
- Java实现 LeetCode 204 计数质数
- Java实现 洛谷 P1089 津津的储蓄计划
- java实现第三届蓝桥杯数量周期
- java实现第七届蓝桥杯机器人塔
- java实现第四届蓝桥杯快速排序
- Java实现 蓝桥杯VIP 算法提高 11-2删除重复元素
- Java实现 蓝桥杯 算法提高 摩尔斯电码
- Java 蓝桥杯 算法训练 字符串的展开 (JAVA语言实现)
- 【JAVA】MacBook安装Java环境及eclipse
- java实现redis数据库访问
- Java面向对象编程篇5——枚举
- 转:Java Web应用中调优线程池的重要性
- [Bug]redis问题解决(MISCONF Redis is configured to save RDB snapshots)
- Atitit 函数式常用子操作与组合 目录 1. 集合类的操作1 1.1. Transform、map1 1.2. paip.提升效率---filter map reduce 的java 函
- 华为校招机试 - 单词重量(Java & JS & Python)
- java字符串练习题8、同构字符串
- 当年的java考试:Java景区预约登记管理系统(maven整合servlet)
- Java 是值传递还是引用传递?
- 【java】Java 包(package)
- 深入浅出Redis-redis哨兵集群
- JAVA语言之Java 中不同的并行实现的性能比较