redis学习记录08-分片

说明

Redis的分片(Sharding或者Partitioning)技术是指将数据分散到多个Redis实例中的方法,分片之后,每个redis拥有一部分原数据集的子集。在数据量非常大时,这种技术能够将数据量分散到若干主机的redis实例上,进而减轻单台redis实例的压力。分片技术能够以更易扩展的方式使用多台计算机的存储能力(这里主要指内存的存储能力)和计算能力:
(1)从存储能力的角度,分片技术通过使用多台计算机的内存来承担更大量的数据,如果没有分片技术,那么redis的存储能力将受限于单台主机的内存大小。
(2) 从计算能力的角度,分片技术通过将计算任务分散到多核或者多台主机中,能够充分利用多核、多台主机的计算能力。

分片算法

采用分片之后,数据将被分散到4个redis实例中,对数据的操作也被分散到每个redis实例中,此时单台主机的压力将大大减轻。
分片的部署,即实例2中分片算法被放在哪里?是在分片时需要首先考虑的问题,分片部署方式一般分为以下三种:

(1)在客户端做分片;这种方式在客户端确定要连接的redis实例,然后直接访问相应的redis实例;

(2)在代理中做分片;这种方式中,客户端并不直接访问redis实例,它也不知道自己要访问的具体是哪个redis实例,而是由代理转发请求和结果;其工作过程为:客户端先将请求发送给代理,代理通过分片算法确定要访问的是哪个redis实例,然后将请求发送给相应的redis实例,redis实例将结果返回给代理,代理最后将结果返回给客户端。

(3)在redis服务器端做分片;这种方式被称为“查询路由”,在这种方式中客户端随机选择一个redis实例发送请求,如果所请求的内容不再当前redis实例中它会负责将请求转交给正确的redis实例,也有的实现中,redis实例不会转发请求,而是将正确redis的信息发给客户端,由客户端再去向正确的redis实例发送请求。

分片的缺点

上面主要描述了分片的优点,当然分片的存在也有缺陷,例如:

(1) 通常无法支持涉及多键的操作;在redis中有很多一次操作多个key的操作,例如求集合交集的SINTER操作,该操作将涉及到多个键,而这多个键有可能被分片到不同的redis实例中,此时就无法执行这种操作。

(2)Redis的事务操作中涉及多个键时也不能用;

(3)分片将导致数据处理更加复杂;例如在分片过程中,随着redis实例的增加,数据备份等操作都将会变得更加复杂。

(4)Redis目前不支持动态分片操作,扩容和缩容操作都会比较复杂,尤其分片操作部署在客户端时,需要重新配置和启动客户端。在使用过程中缩容用的不多,扩容可以采用后面介绍的预分片策略来缓解此问题。

Jedis分片连接池

Jedis通过一致性哈希分片算法来实现数据分片,一致性哈希算法:http://blog.csdn.net/cywosp/article/details/23397179/。简单用Jedis分片连接池来实现多Redis的master节点进行数据分片,步骤如下:
1. 部署2个Redis master节点。
2. 用ShardedJedisPool连接Redis maser节点,并将数据根据一致性哈希算法存放到不同的master节点,从而达成数据分片。
客户端代码如下:

public class RedisShardPoolTest {  
    static ShardedJedisPool pool;  
    static{  
        JedisPoolConfig config =new JedisPoolConfig();//Jedis池配置  
        config.setMaxActive(500);//最大活动的对象个数  
          config.setMaxIdle(1000 * 60);//对象最大空闲时间  
          config.setMaxWait(1000 * 10);//获取对象时最大等待时间  
          config.setTestOnBorrow(true);  
        String hostA = "10.7.12.52";  
          int portA = 6379;  
          String hostB = "10.7.112.52";  
          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.set(key,"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++);  
    }  
}  

通过执行结果会发现这100条数据会被分开存放到10.7.12.52和10.7.112.52机器上的master节点中,查看源码会发现jds.set(key,value)方法会调用jds.getShared(key)来根据key的hash值来获取该key应该存放到那个节点上。
转至http://blog.csdn.net/xianymo/article/details/46433165

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
关于java程序员发展需要学习的路线整理集合 技术 应用技术 计算机基础知识 cpu mem disk net 线程,进程 第三方库 poi Jsoup zxing Gson 数据结构 树 栈 链表 队列 图 操作系统 linux 代码控制 自动化代码检查 sonar 代码规范 阿里巴巴Java开发规范手册 UMPAY——编码规范 日志规范 异常规范 网络 协议 TCP/IP HTTP hession file HTTPS 负载均衡 容器 JBOSS tomcat resin jetty 容灾 日志框架 开源框架 slf4j 框架实现 log4j logback commong logging jdk logger 测试框架 测试框架 junit easymock testng mockito bug管理 禅道 jira 开发工具 编程工具 eclipse myeclipse idea vi VS webstorm sublime text 版本控制 svn git 项目管理 maven Nexus Jenkins 工作软件 反编译软件 office系列 下载器 adobe系列 记录软件 思维导图 office--Note 邮件管理 性能优化 分层优化 系统级别 中间件级别 JVM级别 代码级别 分段优化 前端 web应用 服务应用 资源池 数据库 大数据与nosql zookeeper hadoop hbase mongodb strom spark java语言 语言语法基础 异常 泛型 内部类 反射 序列化 nIo 匿名类 包装类 优先级 引用 语言工具类库 容器类 集合 链表 map 工具类 系统类 日期类 数字类 字符串+正则 流 字符流 字节流 语言特性 继承 封装 多态 JVM 多线程与并发 GC机制 GC收集器类型 串行 CMS 并行 G1 算法 复制 标记清理 标记整理 分区 新生代 eden survivor 老年代(old区) 永久代(perm区) 版本变化 1.5 1.6 1.7 1.8 1.9 IO/NIO IO类型 同步阻塞 同步非阻塞 基于信号 多路复用 异步IO 类加载机制 双亲委派 OSGI 算法 搜索 二分 排序 选择 冒泡 插入 快速 归并 堆 桶 基数 常用算法 贪婪 回溯 剪枝 动态规划 数据挖掘算法 KMP算法 GZZ算法 HASH分桶 关联规则算法 APRORIVE算法 分布式 负载均衡 水平伸缩 集群 分片 Key-hash 异步 一致性hash 消峰 分库分表 锁 悲观锁 乐观锁 行级锁 分布式锁 分区排队 一致性 一致性算法 paxos zab nwr raft gossip 柔性事务(TCC) 一致性原理 CAP BASE 中间件 数据库 mysql 存储引擎 索引 锁 oracle db2 缓存 redis 数据结构 持久 复制 cas 单线程 memcache eacache Tair 消息队列 jms Queue Topic kafka 持久 复制 Stream Partition rocketMQ RabbitMQ ActiveMQ 常用开源框架 Spring Spring MVC Spring WebFlow spring tx aop ioc Struts ibatis Mybatis CAS Dubbo 工作能力 软实力 应急能力 创新能力 管理能力 分享能力 学习能力 沟通能力 解决问题能力 经历 技术攻关案例 程序开发案例 程序设计案例 设计 设计原则 单一职责原则 开闭原则 里氏替换原则 依赖倒转原则 接口隔离原则 迪米特原则 设计模式 结构模式 适配器模式 桥接模式 组合模式 装饰模式 外观模式 享元模式 代理模式 创建模式 抽象工厂模式 工厂方法模式 建造这模式 原型模式 单例模式 行为模式 责任链模式 命令模式 解释器模式 迭代器模式 中介者模式 备忘录模式 观察者模式 状态模式 策略模式 模板方法模式 访问者模式 设计案例 UML 架构 系统架构能力 基本理论 扩展性设计 可用性设计 可靠性设计 一致性设计 负载均衡设计 过载保护设计 协议设计 二进制协议 文本协议 接入层架构设计 DNS轮询 动静态分离 静态化 反向代理 LVS F5 CDN 逻辑层架构设计 连接池 串行化技术 影子Master架构 批量写入 配置中心 去中心化 通讯机制 同步 RPC RMI 异步 MQ Cron 数据层架构设计 缓存优化 DAO&ORM; 双主架构 主从同步 读写分离 性能优化架构能力 代码级别 关联代码优化 cache对其 分支预测 copy on write 内联优化 系统优化 cache 延迟计算 数据预读 异步 轮询与通知 内存池 模块化 工程架构能力 开发语言 运维与监控 监控 系统监控 日志监控 流量监控 接口监控 数据库监控 业务监控 性能监控 告警 日志 设计模式 数据结构与算法 各种工具

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值