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

Jedis分片连接池(分布式)

 
阅读更多

一下内容来自网络,但是很多细节没有写出来,所以我经过自己琢磨,终于找到原因了。

Redis-2.4.15目前没有提供集群的功能,Redis作者在博客中说将在3.0中实现集群机制。目前Redis实现集群的方法主要是采用一致性哈稀分片(Shard),将不同的key分配到不同的redis server上,达到横向扩展的目的。下面来介绍一种比较常用的分布式场景:

在读写操作比较均匀且实时性要求较高,可以用下图的分布式模式:

在读操作远远多于写操作时,可以用下图的分布式模式:

 

       对于一致性哈稀分片的算法,Jedis-2.0.0已经提供了,下面是使用示例代码(以ShardedJedisPool为例):

())+"_"+(index++);
 

从运行结果中可以看到,不同的key被分配到不同的Redis-Server上去了。

 总结: 客户端jedis的一致性哈稀进行分片原理:初始化ShardedJedisPool的时候,会将上面程序中的jdsInfoList数据进行一个算法技术,主要计算依据为list中的index位置来计算,我大概看了一下其源码如下:

package jedis;

import java.util.ArrayList;
import java.util.List;

import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisShardInfo;
import redis.clients.jedis.ShardedJedis;
import redis.clients.jedis.ShardedJedisPool;
import redis.clients.util.Hashing;
import redis.clients.util.Sharded;

public class RedisShardPoolTest {

	static ShardedJedisPool pool;

	static {

		JedisPoolConfig config = new JedisPoolConfig();// Jedis池配置
		config.setTestOnBorrow(true);

		String hostA = "192.168.1.55";

		int portA = 6379;

		String hostB = "192.168.1.63";

		int portB = 6379;

		List<JedisShardInfo> jdsInfoList = new ArrayList<JedisShardInfo>(2);

		JedisShardInfo infoA = new JedisShardInfo(hostA, portA);

		//infoA.setPassword("redis.360buy");

		JedisShardInfo infoB = new JedisShardInfo(hostB, portB);

		//infoB.setPassword("redis.360buy");

		jdsInfoList.add(infoA);

		jdsInfoList.add(infoB);

		pool = new ShardedJedisPool(config, jdsInfoList, Hashing.MURMUR_HASH,

		Sharded.DEFAULT_KEY_TAG_PATTERN);

	}

	/**
	 * 
	 * @param args
	 */

	public static void main(String[] args) {

		for (int i = 0; i < 100; i++) {

			String key = generateKey();

			// key += "{aaa}";

			ShardedJedis jds = null;

			try {

				jds = pool.getResource();

				System.out.println(key + ":"
						+ jds.getShard(key).getClient().getHost());

				System.out.println(jds.setex(key,100,
						"1111111111111111111111111111111"));

			} catch (Exception e) {

				e.printStackTrace();

			}

			finally {

				pool.returnResource(jds);

			}

		}

	}

	private static int index = 1;

	public static String generateKey() {

		return String.valueOf(Thread.currentThread().getId()) + "_" + (index++);

	}
}
 

(如果亲还是不信的话,可以将上面程序中的 jdsInfoList在add的时候,先add第二个,在add第一个,绝对取不出数据,原因很简单,第一次set值的时候,是按list下标来hash计算出一个服务器的,所以取值的时候,list顺序不能变动)

实际上,上面的集群模式还存在两个问题:

1.       扩容问题:

因为使用了一致性哈稀进行分片,那么不同的key分布到不同的Redis-Server上,当我们需要扩容时,需要增加机器到分片列表中,这时候会使得同样的key算出来落到跟原来不同的机器上,这样如果要取某一个值,会出现取不到的情况,对于这种情况,Redis的作者提出了一种名为Pre-Sharding的方式:

Pre-Sharding方法是将每一个台物理机上,运行多个不同断口的Redis实例,假如有三个物理机,每个物理机运行三个Redis实际,那么我们的分片列表中实际有9Redis实例,当我们需要扩容时,增加一台物理机,步骤如下:

A.     在新的物理机上运行Redis-Server

B.      该Redis-Server从属于(slaveof)分片列表中的某一Redis-Server(假设叫RedisA);

C.      等主从复制(Replication)完成后,将客户端分片列表中RedisAIP和端口改为新物理机上Redis-ServerIP和端口;

D.     停止RedisA

这样相当于将某一Redis-Server转移到了一台新机器上。Prd-Sharding实际上是一种在线扩容的办法,但还是很依赖Redis本身的复制功能的,如果主库快照数据文件过大,这个复制的过程也会很久,同时会给主库带来压力。所以做这个拆分的过程最好选择为业务访问低峰时段进行。

 再 总结一下这里的扩容:其实这里的扩容很简单的思想:就是前期我们可能只用到两三个服务器,但是但是担心后期要扩容,所以前期就现在每一个机器上面再装两个 redis,这样就有9个redis嘛,后面如果确实服务器不够,需要扩容,就重新找一台新机来代替9个中的一个redis,有人说,这样不还是9个么, 是的,但是以前服务器上面有三个redis,压力很大的,这样做,相当于单独分离出来并且将数据一起copy给新的服务器。值得注意的是,还需要修改客户 端被代替的redis的IP和端口为现在新的服务器,只要顺序不变,不会影响一致性哈希分片(刚才上面刚说了哈)。

2.       单点故障问题:

还是用到Redis主从复制的功能,两台物理主机上分别都运行有Redis-Server,其中一个Redis-Server是另一个的从库,采用双机热备技术,客户端通过虚拟IP访问主库的物理IP,当主库宕机时,切换到从库的物理IP。只是事后修复主库时,应该将之前的从库改为主库(使用命令slaveof no one),主库变为其从库(使命令slaveof IP PORT),这样才能保证修复期间新增数据的一致性。

 

http://blog.csdn.net/lang_man_xing/article/details/38405269

分享到:
评论

相关推荐

    jedis连接池配置demo

    总结一下,ShardedJedisPool通过分片技术提高了Redis操作的效率,而连接池则有效地管理了与Redis服务器的连接,避免了频繁创建和销毁连接的开销。正确配置和使用ShardedJedisPool是优化Java应用与Redis交互性能的...

    redis源码以及哨片分片连接池实现

    总之,了解Redis源码、哨兵系统和分片连接池的实现对于开发高效、可靠的分布式应用至关重要。通过研究这些内容,我们可以更好地优化系统性能,提升服务的稳定性和可扩展性。在实际项目中,结合使用哨兵和分片策略,...

    Redis分片池 代码

    3. **连接池管理**:连接池负责维护与各个Redis实例的连接,如JedisPool或Lettuce Pool。连接池管理包括创建、释放连接,以及超时、最大连接数等配置,以确保系统稳定运行。 4. **数据路由**:根据分片策略,工具类...

    spring分片+jedis+sentinel

    综上所述,"spring分片+jedis+sentinel"的组合为分布式系统提供了强大的数据缓存管理和高可用性保障。通过Spring Data Redis、Jedis和Sentinel的结合使用,我们可以构建出稳定、高效且易于扩展的Redis解决方案。

    jedis单机版,集群版工具类

    3. **哈希分片**:Jedis 集群版会自动处理哈希槽分配,确保数据均匀分布。 4. **故障转移**:当某个节点失效时,Jedis 集群会自动检测并重新路由请求到其他正常节点。 5. **分布式锁**:在集群中实现分布式锁,...

    jedis-2.8-src

    4. **命令分片支持**:对于大规模数据,Jedis 支持命令分片,可以在多个 Redis 节点上并行执行命令,提高处理速度。 **二、Jedis 2.8 主要改进和更新** 1. **性能优化**:2.8 版本可能包含了对之前版本的性能优化,...

    spring整合redis(spring模板+连接池+json序列化+cluster集群).zip

    Redis Cluster是Redis的分布式解决方案,它能自动分片数据并提供故障转移功能。在Spring中,我们可以使用`ClusterRedisConnectionFactory`来连接到Redis集群。配置时需要提供所有节点的IP和端口,以及集群的其他...

    jedis-jedis-2.10.2.zip

    6. **命令分片**:在分布式环境中,Jedis可以处理多台Redis服务器,支持命令的分片操作。 在Jedis 2.10.2版本中,开发者可能关注的改进包括: 1. **性能优化**:通过对内部逻辑和网络通信的优化,提高了命令执行...

    Jedis相关jar包

    - **Redis Cluster**:对于大规模部署,可以使用Redis Cluster搭建分布式数据库,实现数据的自动分片。 综上所述,Jedis是Java开发人员与Redis交互的重要库,提供了丰富的功能来操作Redis中的数据。正确配置和使用...

    jedis-jedis-3.0.0-m1 (1).zip

    8. **集群支持**:Jedis 3.0版本开始,增加了对Redis Cluster的支持,可以方便地操作分布式的Redis集群,实现数据的分片和高可用性。 9. **命令行接口**:Jedis还提供了一些命令行工具,如JedisClusterInfoCmdArgs...

    jedis-jedis-2.4.0.tar.gz

    7. **分片(Sharding)**:Jedis支持对Redis集群进行分片操作,通过`JedisCluster`类进行管理和操作。 8. **持久化(Persistence)**:虽然Jedis不直接处理Redis的持久化设置,但可以通过相关命令控制Redis的RDB或...

    jedis-jedis-3.4.1.tar.gz

    5. **复制与分片支持**: - Jedis提供了对Redis主从复制和Cluster模式的支持,可以轻松地在多个节点之间切换或分发操作。 6. **异常处理**: - Jedis库中有各种特定的异常,如`JedisConnectionException`表示连接...

    Java系统分布式缓存PPT

    这部分可能会介绍Spring Boot与Redis的整合,包括配置Redis连接池、使用Jedis或Lettuce客户端进行数据操作,以及设置过期策略、事务处理等内容。 “分布式缓存-第三章:实践技巧篇.pdf”深入探讨了分布式缓存的优化...

    分布式redis储存方式

    使用Java与Redis交互时,可以考虑使用连接池(如JedisPool)提高性能,减少网络开销。同时,合理设置超时时间、缓冲池大小等参数,以优化客户端性能。 9. **安全性与监控** 分布式Redis在Java应用中,应考虑数据...

    redis集群批量插入

    Redis集群是通过分片(Sharding)技术来分散数据到多个节点,每个节点存储一部分数据。在集群中,数据被分割成多个槽(Slot),每个槽对应一个特定的键空间范围。Java客户端库如JedisCluster或Lettuce提供了连接和...

    redis集群环境搭建以及java中jedis客户端集群代码实现

    // 创建JedisPoolConfig对象,设置连接池参数 JedisPoolConfig poolConfig = new JedisPoolConfig(); poolConfig.setMaxTotal(100); poolConfig.setMaxIdle(50); poolConfig.setMinIdle(20); // 设置集群节点信息,...

    redis单机和集群Java版、缓存及缓存同步

    - **Jedis 连接池**:为了更高效地复用连接,可以使用 JedisPool,它实现了连接池功能,如下: ```java JedisPoolConfig config = new JedisPoolConfig(); JedisPool pool = new JedisPool(config, "192.168.101...

    JedisCluster

    3. **连接池**: JedisCluster内部使用连接池管理与各个节点的连接,提高性能和资源利用率。 4. **事务支持**: 虽然Redis本身支持简单的事务,但在集群环境中,事务的处理需要特别注意,因为它们不能跨节点执行。 ##...

    redis涉及的jar包和工具

    Java客户端如Jedis和Lettuce都支持与这些机制的交互,允许开发者在代码中处理故障转移和分片。 7. **Redis Commander**: Redis Commander是一个Web界面工具,用于可视化管理和操作Redis数据库。它可以帮助开发者...

    redis学习资料,包含基础指令操作,场景实战结合java代码(秒杀,分布式锁),分布式多级缓存,原理讲解等等

    最后,Redis Cluster能实现数据的自动分片,支持大规模的数据存储和读写。 "04-原理篇"深入到Redis的内部机制,包括底层数据结构(如SDS、ZipMap、IntSet等)、网络模型(基于Epoll事件驱动)以及通信协议(RESP,...

Global site tag (gtag.js) - Google Analytics