C# servicestack.redis 互通 java jedis
拥抱变化,如今也走上了.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 = ; n < ; ++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 = ; foreach(var b in convertedKeyBytes)
value *= b*-; 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 = ; 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的更多相关文章
- 使用Redis的Java客户端Jedis
转载自:http://aofengblog.blog.163.com/blog/static/631702120147298317919/ 前一篇文章<Redis命令指南>讲解了通过命令行 ...
- [转载] 使用Redis的Java客户端Jedis
转载自http://aofengblog.blog.163.com/blog/static/631702120147298317919/ 在实际的项目开发中,各种语言是使用Redis的客户端库来与Re ...
- redis安装 phpredis Jedis 扩展的实现及注意事项,php,java,python相关插件安装实例代码和文档推荐
redis安装 phpredis Jedis 扩展的实现及注意事项,php,java,python相关插件安装实例代码和文档推荐 1.Redis 官方网站下载: http://redis.io/dow ...
- 【转载】Redis的Java客户端Jedis的八种调用方式(事务、管道、分布式…)介绍
转载地址:http://blog.csdn.net/truong/article/details/46711045 关键字:Redis的Java客户端Jedis的八种调用方式(事务.管道.分布式…)介 ...
- Redis与Java的链接Jedis(二)
就像jdbc跟java链接数据库一样 redis跟java链接最好的工具就是Jedis 相关资源下载:https://github.com/xetorthio/jedis 正常建立java项目, 导入 ...
- Redis(九):Redis的Java客户端Jedis
Redis的Java客户端Jedis导航目录: 安装JDK 安装Eclipse Jedis所需要的Jar包 Jedis常用操作 JedisPool 安装JDK tar -zxvf jdk-7u67-l ...
- 9.Redis的Java客户端Jedis
Redis的Java客户端Jedis Jedis所需jar包 commons-pool-1.6.jar jedis-2.1.0.jar 1.Jedis常用操作(jedis中的api 和 我们在 l ...
- redis 与java的连接 和集群环境下Session管理
redis 的安装与设置开机自启(https://www.cnblogs.com/zhulina-917/p/11746993.html) 第一步: a) 搭建环境 引入 jedis jar包 co ...
- 【Redis】:Jedis 使用
Redis 支持很多语言, 例如C#,RUBY,JAVA 等, Jedis是redis的java版本的客户端实现 一个简单的Jedis使用 依赖第三方包jedis-2.7.2.jar commons- ...
随机推荐
- bzoj4826 [Hnoi2017]影魔
Description 影魔,奈文摩尔,据说有着一个诗人的灵魂.事实上,他吞噬的诗人灵魂早已成千上万.千百年来,他收集了各式各样的灵魂,包括诗人.牧师.帝王.乞丐.奴隶.罪人,当然,还有英雄.每一个灵 ...
- SVD之最小二乘【推导与证明】
0.SLAM中SVD进行最小二乘的应用 在SLAM应用中,计算Homography Matrix,Fundamental Matrix,以及做三角化(Triangulation)时,都会用到最小二乘 ...
- HTML5 进阶系列:拖放 API 实现拖放排序
前言 HTML5 中提供了直接拖放的 API,极大的方便我们实现拖放效果,不需要去写一大堆的 js,只需要通过监听元素的拖放事件就能实现各种拖放功能. 想要拖放某个元素,必须设置该元素的 dragga ...
- ASP.NET Core 使用 JWT 搭建分布式无状态身份验证系统
为什么使用 Jwt 最近,移动开发的劲头越来越足,学校搞的各种比赛都需要用手机 APP 来撑场面,所以,作为写后端的,很有必要改进一下以往的基于 Session 的身份认证方式了,理由如下: 移动端经 ...
- Redis学习-SortedSet
Sorted-Sets和Sets类型极为相似,它们都是字符串的集合,都不允许重复的成员出现在一个Set中.它们之间的主要差别是Sorted-Sets中的每一个成员都会有一个分数(score)与之关联, ...
- MyBatis之TypeHandler
在大学写web应用的时候经常会遇到这么个问题,当我要插入一条数据,某个数据是Date类型,数据库中却是VARCHAR类型,这个时候可能会傻乎乎的先把这个数据自己手动转换成String类型再插入到数据库 ...
- jmeter将参数值写入到指定文件
有时在测试过程中需要将测试过程中生成的参数保存下来,jmeter并没有此类功能,此时,可以 通过beanshell编写代码来实现 思路: 每次请求响应返回后,通过正则表达式获取到需要保存的值,通过Be ...
- OpenStack(企业私有云)万里长征第二步——使用Fuel部署
一.前言 最近一直在使用DevStack来安装OpenStack,注意一直二字,部署了一遍又一遍,操作系统怕是安装了不下上百次,有时是为了验证新的方案,有时是安装出错,还有时是运行过程中出错.总之是碰 ...
- 刨根究底字符编码之五——简体汉字编码方案(GB2312、GBK、GB18030、GB13000)以及全角、半角、CJK
简体汉字编码方案(GB2312.GBK.GB18030.GB13000)以及全角.半角.CJK 一.概述 1. 英文字母再加一些其他标点字符之类的也不会超过256个,用一个字节来表示一个字符就足够 ...
- 《一起》Alpha版软件使用说明
1.引言 1.1编写目的 本手册是软件工程概论团队项目<一起>的Alpha版使用说明,面向的对象群体为全校师生. 1.2项目背景 本项目由<软件工程概论>课程需求创建,软件由S ...