一下内容来自网络,但是很多细节没有写出来,所以我经过自己琢磨,终于找到原因了。
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实际,那么我们的分片列表中实际有9个Redis实例,当我们需要扩容时,增加一台物理机,步骤如下:
A. 在新的物理机上运行Redis-Server;
B. 该Redis-Server从属于(slaveof)分片列表中的某一Redis-Server(假设叫RedisA);
C. 等主从复制(Replication)完成后,将客户端分片列表中RedisA的IP和端口改为新物理机上Redis-Server的IP和端口;
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
相关推荐
总结一下,ShardedJedisPool通过分片技术提高了Redis操作的效率,而连接池则有效地管理了与Redis服务器的连接,避免了频繁创建和销毁连接的开销。正确配置和使用ShardedJedisPool是优化Java应用与Redis交互性能的...
总之,了解Redis源码、哨兵系统和分片连接池的实现对于开发高效、可靠的分布式应用至关重要。通过研究这些内容,我们可以更好地优化系统性能,提升服务的稳定性和可扩展性。在实际项目中,结合使用哨兵和分片策略,...
3. **连接池管理**:连接池负责维护与各个Redis实例的连接,如JedisPool或Lettuce Pool。连接池管理包括创建、释放连接,以及超时、最大连接数等配置,以确保系统稳定运行。 4. **数据路由**:根据分片策略,工具类...
综上所述,"spring分片+jedis+sentinel"的组合为分布式系统提供了强大的数据缓存管理和高可用性保障。通过Spring Data Redis、Jedis和Sentinel的结合使用,我们可以构建出稳定、高效且易于扩展的Redis解决方案。
3. **哈希分片**:Jedis 集群版会自动处理哈希槽分配,确保数据均匀分布。 4. **故障转移**:当某个节点失效时,Jedis 集群会自动检测并重新路由请求到其他正常节点。 5. **分布式锁**:在集群中实现分布式锁,...
4. **命令分片支持**:对于大规模数据,Jedis 支持命令分片,可以在多个 Redis 节点上并行执行命令,提高处理速度。 **二、Jedis 2.8 主要改进和更新** 1. **性能优化**:2.8 版本可能包含了对之前版本的性能优化,...
Redis Cluster是Redis的分布式解决方案,它能自动分片数据并提供故障转移功能。在Spring中,我们可以使用`ClusterRedisConnectionFactory`来连接到Redis集群。配置时需要提供所有节点的IP和端口,以及集群的其他...
6. **命令分片**:在分布式环境中,Jedis可以处理多台Redis服务器,支持命令的分片操作。 在Jedis 2.10.2版本中,开发者可能关注的改进包括: 1. **性能优化**:通过对内部逻辑和网络通信的优化,提高了命令执行...
- **Redis Cluster**:对于大规模部署,可以使用Redis Cluster搭建分布式数据库,实现数据的自动分片。 综上所述,Jedis是Java开发人员与Redis交互的重要库,提供了丰富的功能来操作Redis中的数据。正确配置和使用...
8. **集群支持**:Jedis 3.0版本开始,增加了对Redis Cluster的支持,可以方便地操作分布式的Redis集群,实现数据的分片和高可用性。 9. **命令行接口**:Jedis还提供了一些命令行工具,如JedisClusterInfoCmdArgs...
7. **分片(Sharding)**:Jedis支持对Redis集群进行分片操作,通过`JedisCluster`类进行管理和操作。 8. **持久化(Persistence)**:虽然Jedis不直接处理Redis的持久化设置,但可以通过相关命令控制Redis的RDB或...
5. **复制与分片支持**: - Jedis提供了对Redis主从复制和Cluster模式的支持,可以轻松地在多个节点之间切换或分发操作。 6. **异常处理**: - Jedis库中有各种特定的异常,如`JedisConnectionException`表示连接...
这部分可能会介绍Spring Boot与Redis的整合,包括配置Redis连接池、使用Jedis或Lettuce客户端进行数据操作,以及设置过期策略、事务处理等内容。 “分布式缓存-第三章:实践技巧篇.pdf”深入探讨了分布式缓存的优化...
使用Java与Redis交互时,可以考虑使用连接池(如JedisPool)提高性能,减少网络开销。同时,合理设置超时时间、缓冲池大小等参数,以优化客户端性能。 9. **安全性与监控** 分布式Redis在Java应用中,应考虑数据...
Redis集群是通过分片(Sharding)技术来分散数据到多个节点,每个节点存储一部分数据。在集群中,数据被分割成多个槽(Slot),每个槽对应一个特定的键空间范围。Java客户端库如JedisCluster或Lettuce提供了连接和...
// 创建JedisPoolConfig对象,设置连接池参数 JedisPoolConfig poolConfig = new JedisPoolConfig(); poolConfig.setMaxTotal(100); poolConfig.setMaxIdle(50); poolConfig.setMinIdle(20); // 设置集群节点信息,...
- **Jedis 连接池**:为了更高效地复用连接,可以使用 JedisPool,它实现了连接池功能,如下: ```java JedisPoolConfig config = new JedisPoolConfig(); JedisPool pool = new JedisPool(config, "192.168.101...
3. **连接池**: JedisCluster内部使用连接池管理与各个节点的连接,提高性能和资源利用率。 4. **事务支持**: 虽然Redis本身支持简单的事务,但在集群环境中,事务的处理需要特别注意,因为它们不能跨节点执行。 ##...
Java客户端如Jedis和Lettuce都支持与这些机制的交互,允许开发者在代码中处理故障转移和分片。 7. **Redis Commander**: Redis Commander是一个Web界面工具,用于可视化管理和操作Redis数据库。它可以帮助开发者...
最后,Redis Cluster能实现数据的自动分片,支持大规模的数据存储和读写。 "04-原理篇"深入到Redis的内部机制,包括底层数据结构(如SDS、ZipMap、IntSet等)、网络模型(基于Epoll事件驱动)以及通信协议(RESP,...