1、Redis Sharding:3.0以前基本上使用分片实现集群,目前主流方案,客户端实现
2、Redis Cluster:3.0后官方提供了集群方案,2015年4月发布,目前大型应用验证较少,服务端实现
上面两种方案的区别请见:
二、下面只说明使用Jedis实现Redis Sharding的方案
Redis Sharding特点:
- 客户端实现
- 各个Redis节点独立,之间无关系
- 某个Redis节点挂了,整个集群不可用,所以需要对每个节点做主从备份
- 主从备份方案一般通过读写分离设置,每个master至少两个slaver,只有这样master挂掉后,才能选举其中一个Slaver成为新的master,原来master节点加入集群后成为新master的slaver节点
- redis主从切换对客户端jedis使用时透明的,即redis发生了主从切换并不影响jedis的使用
缺点:
- 节点扩展和收缩不友好
三、Redis服务集群的搭建
- Redis集群的搭建可参考文章:搭建3个master-slaver的主从配置
http://www.cnblogs.com/gossip/p/5992716.html
http://www.cnblogs.com/gossip/p/5992821.html - 注意:一般会搭建3个master节点,每个master挂2个slaver,各个master之间并无联系。Redis Cluster的方案是所有master有联系并进行心跳通信,和Redis Sharding不一样
四、Jedis客户端的使用
- 版本:2.9.0
- 实现代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | import redis.clients.jedis.*; import redis.clients.util.JedisClusterCRC16; import java.util.ArrayList; import java.util.Date; import java.util.List; public class ShardingTest { private static String ip = "127.0.0.1" ; private static int timeout = 10000 ; public static void main(String[] args) { JedisPoolConfig poolConfig = getPoolConfig(); List<JedisShardInfo> listRedis = getListSherdInfo(); ShardedJedisPool jedisPool = new ShardedJedisPool(poolConfig, listRedis); ShardedJedis jedis = jedisPool.getResource(); testData(jedis); //initString(jedis); //initHash(jedis); //17秒 //initHashPipeline(jedis); //0秒(是的,0秒) System.out.println(jedis.get( "k1" )); System.out.println(jedis.hgetAll( "product2" )); //initHashPipeline100000(jedis); //100000 总时间 63秒 jedis.close(); jedisPool.destroy(); } private static JedisPoolConfig getPoolConfig() { JedisPoolConfig poolConfig = new JedisPoolConfig(); poolConfig.setMaxTotal( 200 ); poolConfig.setMaxIdle( 30 ); //就是在进行borrowObject进行处理时,对拿到的connection进行validateObject校验 //poolConfig.setTestOnBorrow(true); //就是在进行returnObject对返回的connection进行validateObject校验,个人觉得对数据库连接池的管理意义不大 //poolConfig.setTestOnReturn(true); //GenericObjectPool中针对pool管理,起了一个Evict的TimerTask定时线程进行控制(可通过设置参数 //poolConfig.setTestWhileIdle(true); return poolConfig; } private static List<JedisShardInfo> getListSherdInfo() { JedisShardInfo redis1 = new JedisShardInfo(ip, 9111 ); redis1.setConnectionTimeout(timeout); JedisShardInfo redis2 = new JedisShardInfo(ip, 9112 ); redis2.setConnectionTimeout(timeout); JedisShardInfo redis3 = new JedisShardInfo(ip, 9113 ); redis3.setConnectionTimeout(timeout); List<JedisShardInfo> listRedis = new ArrayList<JedisShardInfo>(); listRedis.add(redis1); listRedis.add(redis2); listRedis.add(redis3); return listRedis; } private static void testData(ShardedJedis jedis) { String key = "k5" ; String value = "v5" ; jedis.set(key, value); System.out.println( "key:" + jedis.get(key)); System.out.println( "key:" + JedisClusterCRC16.getSlot(key)); System.out.println(jedis.type(key)); } } |