一 理解前提
分片是为了把鸡蛋放到几个篮子里,而Dynamo型的分片加备份可以再把数据几份,每一份copy放到不同的节点上。
Redis在数据容灾处理方面可以通过服务器端配置Master-Slave模式来实现,而在分布式集群方面目前只能通过客户端工具来实现一致性哈希分布存储,即key分片存储。Redis可能会在3.0版本支持服务器端的分布存储。Redis只能依靠各个Client做Sharding。可能会在Redis 3.0系列支持Server端Sharding。
Redis是Master-Slave,如果 想把Reids,做成集群模式,无外乎多做几套Master-Slave,每套Master-Slave完成各自的容灾处理,通过Client工具,完成一致性哈希。
二 jedis源码中ShardedJedis实现sharding
1、一个JedisShardInfo类,里面包含了jedis服务器的一些信息,比如
- private int timeout;
- private String host;
- private int port;
- private String password = null;
- private String name = null;
最重要的是它的父类中有一个weight字段,作为本jedis服务器的权值。
这个类还有一个继承自父类的方法createResource,用来生成该类对应的Jedis对象.
public Jedis createResource()
2、在构造ShardedJedis的时候传入一个JedisShardInfo的list列表。然后ShardedJedis的父类的父类及Sharede就会对这个list进行一些操作:
- 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>();
Sharded中的三个字段,nodes是用来模拟一致性哈希算法用的;algo是用来对字符串产生哈希值的hash函数,这里默认的是 murmurhash,这个算法的随机分布特征表现比较好;resources这个map是用来存储JedisShardInfo与其对应的Jedis类 之间的映射关系。
在上面提到的对list的操作:
- 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());
- }
- }
if-else块---------------------------------------------------------------------------- 完成虚拟节点 到真实节点的映射
resources.put(shardInfo, shardInfo.createResource())---完成真实节点 到具体Jedis实例的映射
在for循环中,遍历主机列表(shards.get(i)),之后对每个主机按照单权重160的比例计算shard值,将shard值和主机信息(shardInfo)放到nodes中,将主机信息(shardInfo)和其对应的链接资源(Jedis)映射放入到resources中。
Weight是权重,用于调节单个主机被映射值个数,如果weight为1,那么当前主机将被映射为160个值,weight为2,当前主机将被映射为320个值,因此weight为2的节点被访问到的概率就会高一些。
遍历list中的每一个shardInfo,将其权重weight*160生成n,然后用名字或者编号来生成n个哈希值(这个是为了保证哈希算法的平衡 性而生成的虚拟节点),然后将其和本shardInfo的对应关系存储到treemap里面(这是在模拟一致性哈希算法中将虚拟节点映射到环上的操作), 最后将shardInfo与对应的Jedis类的映射关系存储到resources里面。
3、在使用ShardedJedis进行操作的时候,每个方法都要先获得key经过hash后对应的Jedis对象,才能执行对应的方法,这个Jedis对象获取步骤如下:
1)、首先根据传入的key按照hash算法(默认为murmurhash)取得其value,然后用这个value到treemap中找key大于前面生成的value值的第一个键值对,这个键值对的value既是对应的shardedInfo
- 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());
- }
2)、根据得到的shardedInfo从resources中取得对应的Jedis对象
Feature速览
- 所有数据都在内存中。
- 五种数据结构:String / Hash / List / Set / Ordered Set。
- 数据过期时间支持。
- 不完全的事务支持。
- 服务端脚本:使用Lua Script编写,类似存储过程的作用。
- PubSub:捞过界的消息一对多发布订阅功能,起码Redis-Sentinel使用了它。
- 持久化:支持定期导出内存的Snapshot 与 记录写操作日志的Append Only File两种模式。
- Replication:Master-Slave模式,Master可连接多个只读Slave,暂无专门的Geographic Replication支持。
- Fail-Over:Redis-Sentinel节点负责监控Master节点,在master失效时提升slave,独立的仲裁节点模式有效防止脑裂。
- Sharding:开发中的Redis-Cluser。
- 动态配置:所有参数可用命令行动态配置不需重启,并重新写回配置文件中,对云上的大规模部署非常合适。
参考:
jedis源码中ShardedJedis实现sharding
http://blog.csdn.net/mydreamongo/article/details/8951905
API---JedisShardInfo
API----ShardedJedis
http://tool.oschina.net/uploads/apidocs/redis/clients/jedis/ShardedJedis.html
http://blog.csdn.net/lang_man_xing/article/details/38405269
相关推荐
2. **数据分片**:理解一致性哈希的工作原理,合理规划槽分配,确保数据均衡分布。 3. **容错策略**:配置适当的故障恢复策略,如备用节点、数据备份等。 4. **版本兼容**:Jedis-Cluster-Setup-Tool 可能需要特定...
7. **Cluster支持**:自Jedis 2.8版本起,开始支持Redis Cluster,可以连接到Redis集群并进行操作,实现了槽(Slot)的自动路由和数据分片。 8. **异常处理**:Jedis抛出一系列与Redis操作相关的异常,如`...
- **Cluster集群**:当数据量和访问量进一步增长时,可以搭建Redis Cluster,实现数据分片和并行处理。 总的来说,"100讲带你实战基于Redis的抢购系统"将带领我们掌握如何利用Redis的特性和Java的编程能力,设计和...
5. **Redis集群**:当单个Redis实例无法满足需求时,可以搭建Redis集群,实现数据分片,提高并发处理能力。但要注意集群间的数据一致性问题,例如主从复制、槽迁移等。 6. **客户端库**:使用Java的Jedis或Lettuce...
- **Redis集群**:如果例子中包含,可以学习如何搭建和使用Redis Cluster,了解槽的概念和分片原理。 - **Java客户端使用**:熟悉Jedis或Lettuce的API,了解如何在Java代码中进行连接、发送命令、关闭连接等操作。 ...
Redis集群通过数据分片(Sharding)策略将数据分散存储在多个节点上,实现负载均衡,增强系统的扩展性和可用性。在Redis 3.0及以上版本,引入了集群功能,支持主从复制、槽分配以及故障转移等特性。 **集群搭建** ...
7. **分片(Sharding)**:Jedis支持对Redis集群进行分片操作,通过`JedisCluster`类进行管理和操作。 8. **持久化(Persistence)**:虽然Jedis不直接处理Redis的持久化设置,但可以通过相关命令控制Redis的RDB或...
最后,Redis集群是Redis提供的高可用、高扩展性的数据存储方案,支持自动分片和故障转移。集群的搭建、查询集群信息、添加主节点、删除节点等操作均需要特定的命令和策略。 需要注意的是,本文档中提到的所有命令和...
6. **集群支持**:Redis Cluster 是 Redis 的分布式解决方案,可以自动将数据分片到多个节点,提供水平扩展能力。 **Jedis 知识点:** 1. **连接管理**:Jedis 提供了连接池功能,如 JedisPool,可以高效管理和...
Spring Data Redis提供了`JedisConnectionFactory`(基于Jedis客户端)和`LettuceConnectionFactory`(基于Lettuce客户端)两种方式。它们都支持连接池配置,如最大连接数、最小空闲连接数、超时时间等。配置连接池...
4. 集群支持:Redis Cluster提供自动分片功能,可扩展到上千个节点。 5. 事务支持:Redis支持简单的事务操作,保证多条命令的原子执行。 6. 消息队列:Redis内置发布/订阅功能,可作为轻量级的消息中间件。 三、...
2. **定义ShardInfo列表**:如果你有多个Redis实例,可以将它们添加到列表中,以实现数据的分片。 ```java List<JedisShardInfo> shards = new ArrayList(); shards.add(shardInfo1); shards.add(shardInfo2); ...
4. **扩展性**:随着任务量的增加,可能需要考虑队列的分片和负载均衡。 在实际项目中,还可以结合Spring框架,使用Spring Data Redis模块简化Redis的集成,以及使用Spring Task或Quartz等定时任务框架来定期检查和...
Redis Cluster 是Redis提供的分布式解决方案,它可以将数据分散存储在多个节点上,实现数据的自动分片,提供高可用性和水平扩展性。然而,对于想要在JFinal项目中利用Redis Cluster特性的开发者来说,这需要额外的...
- Redis Cluster:数据分片、槽自动迁移,实现水平扩展。 8. 性能优化与监控 - 使用Redis内置的INFO命令监控系统状态。 - 优化策略:调整内存使用、选择合适的数据结构、控制并发量等。 - 第三方工具:如Redmon...
- 当数据量增长时,可以通过创建Redis集群来分片存储,提高可扩展性。 - 集群模式下,数据分布、槽迁移和故障转移都是需要考虑的问题。 8. 监控和性能优化: - Redis提供监控工具,如`INFO`命令可以查看服务器...
在Redis集群中,数据被分片到多个节点,每个节点只存储部分数据,这样可以实现数据的水平扩展。在Spring Boot中,配置Redis集群需要指定所有节点的地址,并启用集群模式。使用`JedisCluster`或者Lettuce的`Cluster...
Redis Cluster 是官方提供的分布式解决方案,通过分片技术将数据分散在多个节点上,实现高可用性和水平扩展。 九、Redis 在 Java 中的应用 在 Java 开发中,Jedis 是常用的 Redis 客户端库,提供了丰富的 API 进行...
- Redis Cluster提供了分布式存储能力,可以将数据分片到多个节点,但不支持事务。 10. **最佳实践**: - 限制Redis内存大小以避免OOM异常。 - 为敏感数据启用加密传输。 - 定期备份,以防数据丢失。 - 监控...
Spring Data Redis同样支持Redis Sentinel和Redis Cluster,以实现高可用性和数据分片。通过配置`RedisSentinelConfigurtion`或`RedisClusterConfiguration`,可以轻松连接到哨兵集群或Redis集群。 ### 结论 ...