`
m635674608
  • 浏览: 4928749 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

Jedis之ShardedJedis虚拟节点一致性哈希分析

 
阅读更多

Jedis之ShardedJedis一致性哈希分析

 

ShardedJedis通过一致性哈希实现的的分布式缓存。主要思路:

  • redis服务器节点划分:将每台服务器节点采用hash算法划分为160个虚拟节点(可以配置划分权重)

  • 将划分虚拟节点采用TreeMap存储

  • 对每个redis服务器的物理连接采用LinkedHashMap存储

  • 对Key or KeyTag 采用同样的hash算法,然后从TreeMap获取大于等于键hash值得节点,取最邻近节点存储;当key的hash值大于虚拟节点hash值得最大值时,存入第一个虚拟节点

  • sharded采用的hash算法:MD5 和 MurmurHash两种;默认采用64位的MurmurHash算法;

 

源码:

1
2
3
4
5
6
7
8
9
public class Sharded<R, S extends ShardInfo<R>> {
 
  public static final int DEFAULT_WEIGHT = 1;
  private TreeMap<Long, S> nodes;
  private final Hashing algo;
  private final Map<ShardInfo<R>, R> resources = new LinkedHashMap<ShardInfo<R>, R>();
  ........................
  ........................
}

这个类维护了一致性哈希后的物理机器和虚拟节点的映射关系,看一张图你会秒懂,

 

TreeMap<Long, S> nodes,存储的是虚拟节点和key的映射关系。有了虚拟节点,还要找到真正的存储位置。

Map<ShardInfo<R>, R> resources维护了虚拟节点和真正的存储位置的映射关系。

也是说,hash(key) -> virtual node -> real node;  

 

jedis划分虚拟节点的逻辑代码,在Sharded类中,方法是initialize。这是在实例化对象池ShardedJedisPool过程中执行的划分虚拟节点。 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private void initialize(List<S> shards) {
    nodes = new TreeMap<Long, S>();
 
    for (int i = 0; i != shards.size(); ++i) {
        final S shardInfo = shards.get(i);
        if (shardInfo.getName() == null) {
            for (int n = 0; n < 160 * shardInfo.getWeight(); n++) {
                nodes.put(this.algo.hash("SHARD-" + i + "-NODE-" + n), shardInfo);
            }
        else {
            for (int n = 0; n < 160 * shardInfo.getWeight(); n++) {
                nodes.put(this.algo.hash(shardInfo.getName() + "*" + shardInfo.getWeight() + n), shardInfo);
            }
        }
        resources.put(shardInfo, shardInfo.createResource());
    }
}

以上代码就是划分虚拟节点的逻辑。

 

那么ShardedJedis客户端是如何执行set key value呢?

通过这里可以看出还是通过Jedis客户端执行的set key value。

1
2
3
4
public String set(String key, String value) {
  Jedis j = getShard(key);
  return j.set(key, value);
}

看一下代码中大体的逻辑,首先通过key得到ShardInfo,然后通过ShardInfo得到泛型Jedis客户端。

Sharded.java

1
2
3
public R getShard(byte[] key) {
  return resources.get(getShardInfo(key));
}
1
2
3
4
5
6
7
public S getShardInfo(byte[] key) {
  SortedMap<Long, S> tail = nodes.tailMap(algo.hash(key));
  if (tail.isEmpty()) {
    return nodes.get(nodes.firstKey());
  }
  return tail.get(tail.firstKey());
}

来看一下ShardedJedis的继承关系吧,

还有ShardInfo和JedisShardInfo继承关系,

参考:http://yychao.iteye.com/blog/1751583

 

http://my.oschina.net/xinxingegeya/blog/391713

分享到:
评论

相关推荐

    征服 Redis + Jedis + Spring (二)—— 哈希表操作(HMGET HMSET)

    NULL 博文链接:https://snowolf.iteye.com/blog/1667104

    jedis-双节点可用性自动检测

    NULL 博文链接:https://laintoday.iteye.com/blog/1484520

    Jedis源码分析及配置说明.pdf

    分析了redis的: 1)java客户端实现源码 2)分析了连接channel,包括命令时客户端和服务端的socket连接;...3)分析了JedisPool连接池配置 4) 分析了命令get set hmset 等逻辑 5)分析了subscribe实现源码

    jedis jedis.jar

    jedis jar包; 版本:2.0 2.1

    jedis-2.9.0.jar

    jedis-2.9.0.jar jedis-2.9.0 jar 包,不包含源码,源码下载地址: http://download.csdn.net/download/tan3739/9993938 测试代码: 导入依赖包: commons-lang-2.5.jar commons-pool2-2.4.2.jar jedis-2.9.0 jar ...

    jedis依赖jar包

    jedis依赖jar包, jedis-2.7.0.jar

    jedis相关jar包

    jedis相关jar包:commons-pool2-2.3.jar、jedis-2.7.0.jar

    jedis-jedis-2.7.2

    jedis-jedis-2.7.2缓存技术应用

    jedis-2.5.1.jar

    Jedis 是 Redis 官方首选的 Java 客户端开发包。 实例方法: ? 1 import redis.clients.jedis.* ? 1 2 3 Jedis jedis = new Jedis("localhost"); jedis.set("foo", "bar"); String value = jedis.get("foo"); 支持...

    jedis-2.6.2.zip

    此资源为Java连接redis的工具jar,Jedis 版本为2.62; 有两个地方需要注意下;jedis 3.0新版本废弃了旧回收资源方法; 废弃方法为:JedisPool.returnResource(Jedis);回收资源 Jedis 3.0版本新回收资源: Jedis.close();...

    jedis 2.8.1

    jedis jedis

    jedis源码 (学习jedis)

    jedis源码 (学习jedis必备,附带测试用例)

    jedis-2.9.0-API文档-中文版.zip

    赠送jar包:jedis-2.9.0.jar; 赠送原API文档:jedis-2.9.0-javadoc.jar; 赠送源代码:jedis-2.9.0-sources.jar; 包含翻译后的API文档:jedis-2.9.0-javadoc-API文档-中文(简体)版.zip 对应Maven信息:groupId...

    jedis-test.7z jedis 简单测试 项目工程

    jedis-test.7z jedis 简单测试 项目工程 lib 目录包含了依赖包: commons-lang-2.5.jar commons-pool2-2.4.2.jar jedis-2.9.0.jar 另: * Jedis 的源码工程(导入 eclipse 可直接运行): ...

    jedis-2.8.0-API文档-中文版.zip

    赠送jar包:jedis-2.8.0.jar; 赠送原API文档:jedis-2.8.0-javadoc.jar; 赠送源代码:jedis-2.8.0-sources.jar; 赠送Maven依赖信息文件:jedis-2.8.0.pom; 包含翻译后的API文档:jedis-2.8.0-javadoc-API文档-...

    Spring-4.1.7、jedis-2.8.0、spring-data-redis-1.6.2

    而且发现Jedis和ShardedJedis的方法非常多,覆盖了Redis几乎所有操作,但是没有注释,也没有异常处理,也没有资源回收,所以我就对这两个类进行了再次封装,对照着Redis官网的中文API加上了中文注释,并对接口方法...

    使用redisson替代jedis

    使用redisson替代jedis中的的对应方法,以及对应的redis的命令在这三方中对应查询及操作,

    jedis分片选择库,jedis动态过滤无效服务器

    1 jedis分片支持数据库 2 动态的将有故障的服务器过滤掉 使用实例 static ShardedJedisPool shareJedisPool; static List&lt;JedisShardInfo&gt; jdsInfoList =new ArrayList(); static{ JedisPoolConfig config =new ...

    jedis安装包

    jedis安装包

    jedis-4.3.1

    要开始使用 Jedis,首先将其作为依赖项添加到您的 Java 项目中。如果使用 Maven: &lt;groupId&gt;redis.clients &lt;artifactId&gt;jedis &lt;version&gt;4.3.0 对于许多应用程序,最好使用连接池。实例化 Jedis 连接池: Jedis...

Global site tag (gtag.js) - Google Analytics