http://blog.csdn.net/it_man/article/details/9730605

2013-08-03 11:01 1786人阅读 评论(0) 收藏 举报
 
 

Memcached,对于缓存对象大小有要求,单个对象不得大于1MB,且不支持复杂的数据类型,譬如SET

等。基于这些限制,有必要考虑Redis

相关链接:

Redis实战

Redis实战之Redis + Jedis

Redis实战之征服 Redis + Jedis + Spring (一)

Redis实战之征服 Redis + Jedis + Spring (二)

Redis实战之征服 Redis + Jedis + Spring (三)

言归正传,目前Redis大概有3中基于Java语言的Client:

  • Jredis
  • Jedis
  • Redis4J

这里只说Jedis,因为它是官方提供的唯一Redis Client For Java Provider!

一、简单使用Jedis

需要Jedis就从Maven获取吧!
Maven Pom.xml

  1. <dependency>
  2. <groupId>redis.clients</groupId>
  3. <artifactId>jedis</artifactId>
  4. <version>2.1.0</version>
  5. <type>jar</type>
  6. <scope>compile</scope>
  7. </dependency>
  1. <dependency>
  2. <groupId>redis.clients</groupId>
  3. <artifactId>jedis</artifactId>
  4. <version>2.1.0</version>
  5. <type>jar</type>
  6. <scope>compile</scope>
  7. </dependency>

如果只是简单使用Jedis,以下这么几行代码足够:

  1. Jedis jedis = new Jedis("10.11.20.140");
  2. String keys = "name";
  3. // 删数据
  4. jedis.del(keys);
  5. // 存数据
  6. jedis.set(keys, "snowolf");
  7. // 取数据
  8. String value = jedis.get(keys);
  9. System.out.println(value);
  1. Jedis jedis = new Jedis("10.11.20.140");
  2. String keys = "name";
  3. // 删数据
  4. jedis.del(keys);
  5. // 存数据
  6. jedis.set(keys, "snowolf");
  7. // 取数据
  8. String value = jedis.get(keys);
  9. System.out.println(value);

二、池化使用Jedis

Jedis使用commons-pool完成池化实现。

先做个配置文件:

  1. #最大分配的对象数
  2. redis.pool.maxActive=1024
  3. #最大能够保持idel状态的对象数
  4. redis.pool.maxIdle=200
  5. #当池内没有返回对象时,最大等待时间
  6. redis.pool.maxWait=1000
  7. #当调用borrow Object方法时,是否进行有效性检查
  8. redis.pool.testOnBorrow=true
  9. #当调用return Object方法时,是否进行有效性检查
  10. redis.pool.testOnReturn=true
  11. #IP
  12. redis.ip=10.11.20.140
  13. #Port
  14. redis.port=6379

在静态代码段中完成初始化:

  1. private static JedisPool pool;
  2. static {
  3. ResourceBundle bundle = ResourceBundle.getBundle("redis");
  4. if (bundle == null) {
  5. throw new IllegalArgumentException(
  6. "[redis.properties] is not found!");
  7. }
  8. JedisPoolConfig config = new JedisPoolConfig();
  9. config.setMaxActive(Integer.valueOf(bundle
  10. .getString("redis.pool.maxActive")));
  11. config.setMaxIdle(Integer.valueOf(bundle
  12. .getString("redis.pool.maxIdle")));
  13. config.setMaxWait(Long.valueOf(bundle.getString("redis.pool.maxWait")));
  14. config.setTestOnBorrow(Boolean.valueOf(bundle
  15. .getString("redis.pool.testOnBorrow")));
  16. config.setTestOnReturn(Boolean.valueOf(bundle
  17. .getString("redis.pool.testOnReturn")));
  18. pool = new JedisPool(config, bundle.getString("redis.ip"),
  19. Integer.valueOf(bundle.getString("redis.port")));
  20. }
  1. private static JedisPool pool;
  2. static {
  3. ResourceBundle bundle = ResourceBundle.getBundle("redis");
  4. if (bundle == null) {
  5. throw new IllegalArgumentException(
  6. "[redis.properties] is not found!");
  7. }
  8. JedisPoolConfig config = new JedisPoolConfig();
  9. config.setMaxActive(Integer.valueOf(bundle
  10. .getString("redis.pool.maxActive")));
  11. config.setMaxIdle(Integer.valueOf(bundle
  12. .getString("redis.pool.maxIdle")));
  13. config.setMaxWait(Long.valueOf(bundle.getString("redis.pool.maxWait")));
  14. config.setTestOnBorrow(Boolean.valueOf(bundle
  15. .getString("redis.pool.testOnBorrow")));
  16. config.setTestOnReturn(Boolean.valueOf(bundle
  17. .getString("redis.pool.testOnReturn")));
  18. pool = new JedisPool(config, bundle.getString("redis.ip"),
  19. Integer.valueOf(bundle.getString("redis.port")));
  20. }

然后,修改前面那段jedis操作Redis

  1. // 从池中获取一个Jedis对象
  2. Jedis jedis = pool.getResource();
  3. String keys = "name";
  4. // 删数据
  5. jedis.del(keys);
  6. // 存数据
  7. jedis.set(keys, "snowolf");
  8. // 取数据
  9. String value = jedis.get(keys);
  10. System.out.println(value);
  11. // 释放对象池
  12. pool.returnResource(jedis);
  1. // 从池中获取一个Jedis对象
  2. Jedis jedis = pool.getResource();
  3. String keys = "name";
  4. // 删数据
  5. jedis.del(keys);
  6. // 存数据
  7. jedis.set(keys, "snowolf");
  8. // 取数据
  9. String value = jedis.get(keys);
  10. System.out.println(value);
  11. // 释放对象池
  12. pool.returnResource(jedis);

改为从对象池中,获取Jedis实例:

  1. // 从池中获取一个Jedis对象
  2. Jedis jedis = pool.getResource();
  1. // 从池中获取一个Jedis对象
  2. Jedis jedis = pool.getResource();

切记,最后使用后,释放Jedis对象:

  1. // 释放对象池
  2. pool.returnResource(jedis);
  1. // 释放对象池
  2. pool.returnResource(jedis);

三、一致性哈希

Memcached完全基于分布式集群,而RedisMaster-Slave,如果想把Reids,做成集群模式,无外乎多做几套Master-Slave,每套Master-Slave完成各自的容灾处理,通过Client工具,完成一致性哈希。

PS:Memcached是在Server端完成ShardingRedis只能依靠各个ClientSharding。可能会在Redis 3.0系列支持ServerSharding

保留前面的JedisPoolConfig,新增两个Redis的IP(redis1.ip,redis2.ip),完成两个JedisShardInfo实例,并将其丢进List中:

  1. JedisShardInfo jedisShardInfo1 = new JedisShardInfo(
  2. bundle.getString("redis1.ip"), Integer.valueOf(bundle                       .getString("redis.port")));
  3. JedisShardInfo jedisShardInfo2 = new JedisShardInfo(
  4. bundle.getString("redis2.ip"), Integer.valueOf(bundle                       .getString("redis.port")));
  5. List<JedisShardInfo> list = new LinkedList<JedisShardInfo>();
  6. list.add(jedisShardInfo1);
  7. list.add(jedisShardInfo2);
  1. JedisShardInfo jedisShardInfo1 = new JedisShardInfo(
  2. bundle.getString("redis1.ip"), Integer.valueOf(bundle                       .getString("redis.port")));
  3. JedisShardInfo jedisShardInfo2 = new JedisShardInfo(
  4. bundle.getString("redis2.ip"), Integer.valueOf(bundle                       .getString("redis.port")));
  5. List<JedisShardInfo> list = new LinkedList<JedisShardInfo>();
  6. list.add(jedisShardInfo1);
  7. list.add(jedisShardInfo2);

初始化ShardedJedisPool代替JedisPool:

  1. ShardedJedisPool pool = new ShardedJedisPool(config, list);
  1. ShardedJedisPool pool = new ShardedJedisPool(config, list);

改由ShardedJedis,获取Jedis对象:

  1. // 从池中获取一个Jedis对象
  2. ShardedJedis jedis = pool.getResource();
  3. String keys = "name";
  4. String value = "snowolf";
  5. // 删数据
  6. jedis.del(keys);
  7. // 存数据
  8. jedis.set(keys, value);
  9. // 取数据
  10. String v = jedis.get(keys);
  11. System.out.println(v);
  12. // 释放对象池
  13. pool.returnResource(jedis);
  1. // 从池中获取一个Jedis对象
  2. ShardedJedis jedis = pool.getResource();
  3. String keys = "name";
  4. String value = "snowolf";
  5. // 删数据
  6. jedis.del(keys);
  7. // 存数据
  8. jedis.set(keys, value);
  9. // 取数据
  10. String v = jedis.get(keys);
  11. System.out.println(v);
  12. // 释放对象池
  13. pool.returnResource(jedis);

四、Spring封装参考

Ok,完成上述代码足够完成简单任务,如果有必要,可以用Spring封装初始化:

  1. <context:property-placeholder location="classpath:redis.properties" />
  2. <bean
  3. id="jedisPoolConfig"
  4. class="redis.clients.jedis.JedisPoolConfig"
  5. >
  6. <property
  7. name="maxActive"
  8. value="${redis.pool.maxActive}" />
  9. <property
  10. name="maxIdle"
  11. value="${redis.pool.maxIdle}" />
  12. <property
  13. name="maxWait"
  14. value="${redis.pool.maxWait}" />
  15. <property
  16. name="testOnBorrow"
  17. value="${redis.pool.testOnBorrow}" />
  18. </bean>
  19. <bean
  20. id="shardedJedisPool"
  21. class="redis.clients.jedis.ShardedJedisPool"
  22. >
  23. <constructor-arg
  24. index="0"
  25. ref="jedisPoolConfig" />
  26. <constructor-arg index="1">
  27. <list>
  28. <bean class="redis.clients.jedis.JedisShardInfo">
  29. <constructor-arg
  30. index="0"
  31. value="${redis1.ip}" />
  32. <constructor-arg
  33. index="1"
  34. value="${redis.port}"
  35. type="int" />
  36. </bean>
  37. <bean class="redis.clients.jedis.JedisShardInfo">
  38. <constructor-arg
  39. index="0"
  40. value="${redis2.ip}" />
  41. <constructor-arg
  42. index="1"
  43. value="${redis.port}"
  44. type="int" />
  45. </bean>
  46. </list>
  47. </constructor-arg>
  48. </bean>
  1. <context:property-placeholder location="classpath:redis.properties" />
  2. <bean
  3. id="jedisPoolConfig"
  4. class="redis.clients.jedis.JedisPoolConfig"
  5. >
  6. <property
  7. name="maxActive"
  8. value="${redis.pool.maxActive}" />
  9. <property
  10. name="maxIdle"
  11. value="${redis.pool.maxIdle}" />
  12. <property
  13. name="maxWait"
  14. value="${redis.pool.maxWait}" />
  15. <property
  16. name="testOnBorrow"
  17. value="${redis.pool.testOnBorrow}" />
  18. </bean>
  19. <bean
  20. id="shardedJedisPool"
  21. class="redis.clients.jedis.ShardedJedisPool"
  22. >
  23. <constructor-arg
  24. index="0"
  25. ref="jedisPoolConfig" />
  26. <constructor-arg index="1">
  27. <list>
  28. <bean class="redis.clients.jedis.JedisShardInfo">
  29. <constructor-arg
  30. index="0"
  31. value="${redis1.ip}" />
  32. <constructor-arg
  33. index="1"
  34. value="${redis.port}"
  35. type="int" />
  36. </bean>
  37. <bean class="redis.clients.jedis.JedisShardInfo">
  38. <constructor-arg
  39. index="0"
  40. value="${redis2.ip}" />
  41. <constructor-arg
  42. index="1"
  43. value="${redis.port}"
  44. type="int" />
  45. </bean>
  46. </list>
  47. </constructor-arg>
  48. </bean>

代码可以更简洁一些:

  1. private ApplicationContext app;
  2. private ShardedJedisPool pool;
  3. @Before
  4. public void before() throws Exception {
  5. app = new ClassPathXmlApplicationContext("applicationContext.xml");
  6. pool = (ShardedJedisPool) app.getBean("shardedJedisPool");
  7. }
  8. @Test
  9. public void test() {
  10. // 从池中获取一个Jedis对象
  11. ShardedJedis jedis = pool.getResource();
  12. String keys = "name";
  13. String value = "snowolf";
  14. // 删数据
  15. jedis.del(keys);
  16. // 存数据
  17. jedis.set(keys, value);
  18. // 取数据
  19. String v = jedis.get(keys);
  20. System.out.println(v);
  21. // 释放对象池
  22. pool.returnResource(jedis);
  23. assertEquals(value, v);
  24. }
  1. private ApplicationContext app;
  2. private ShardedJedisPool pool;
  3. @Before
  4. public void before() throws Exception {
  5. app = new ClassPathXmlApplicationContext("applicationContext.xml");
  6. pool = (ShardedJedisPool) app.getBean("shardedJedisPool");
  7. }
  8. @Test
  9. public void test() {
  10. // 从池中获取一个Jedis对象
  11. ShardedJedis jedis = pool.getResource();
  12. String keys = "name";
  13. String value = "snowolf";
  14. // 删数据
  15. jedis.del(keys);
  16. // 存数据
  17. jedis.set(keys, value);
  18. // 取数据
  19. String v = jedis.get(keys);
  20. System.out.println(v);
  21. // 释放对象池
  22. pool.returnResource(jedis);
  23. assertEquals(value, v);
  24. }

当然,Spring提供了对于Redis的专门支持:spring-data-redis,以后有机会再深入研究。

相关链接:

Redis实战

Redis实战之Redis + Jedis

Redis实战之征服 Redis + Jedis + Spring (一)

Redis实战之征服 Redis + Jedis + Spring (二)

Redis实战之征服 Redis + Jedis + Spring (三)

 

Redis实战之Redis + Jedis[转]的更多相关文章

  1. Redis实战之Redis + Jedis

    用Memcached,对于缓存对象大小有要求,单个对象不得大于1MB,且不支持复杂的数据类型,譬如SET 等.基于这些限制,有必要考虑Redis! 相关链接: Redis实战 Redis实战之Redi ...

  2. 分布式缓存技术redis学习系列(五)——redis实战(redis与spring整合,分布式锁实现)

    本文是redis学习系列的第五篇,点击下面链接可回看系列文章 <redis简介以及linux上的安装> <详细讲解redis数据结构(内存模型)以及常用命令> <redi ...

  3. 分布式缓存技术redis系列(五)——redis实战(redis与spring整合,分布式锁实现)

    本文是redis学习系列的第五篇,点击下面链接可回看系列文章 <redis简介以及linux上的安装> <详细讲解redis数据结构(内存模型)以及常用命令> <redi ...

  4. Redis实战总结-Redis的高可用性

    在之前的博客<Redis实战总结-配置.持久化.复制>给出了一种Redis主从复制机制,简单地实现了Redis高可用.然后,如果Master服务器宕机,会导致整个Redis瘫痪,这种方式的 ...

  5. Redis 实战 —— 05. Redis 其他命令简介

    发布与订阅 P52 Redis 实现了发布与订阅(publish/subscribe)模式,又称 pub/sub 模式(与设计模式中的观察者模式类似).订阅者负责订阅频道,发送者负责向频道发送二进制字 ...

  6. Redis 实战 —— 14. Redis 的 Lua 脚本编程

    简介 Redis 从 2.6 版本开始引入使用 Lua 编程语言进行的服务器端脚本编程功能,这个功能可以让用户直接在 Redis 内部执行各种操作,从而达到简化代码并提高性能的作用. P248 在不编 ...

  7. .Net Redis实战——使用Redis构建Web应用

    示例介绍 示例1:借助Redis实现购物车功能 示例2:Redis实现网页缓存和数据缓存 借助Redis实现购物车功能 每个用户的购物车都是一个散列,散列存储了商品ID与商品订购数量之间的映射.订购商 ...

  8. Redis实战之Redis命令

    阅读目录 1. 字符串命令 2. 列表命令 3. 集合命令 4. 散列命令 5. 有序集合命令 6. 发布与订阅命令 7. 小试牛刀 Redis可以存储键与5种不同数据结构类型之间的映射,这5种数据结 ...

  9. Redis 实战 —— 01. Redis 数据结构简介

    一些数据库和缓存服务器的特性和功能 P4 名称 类型 数据存储选项 查询类型 附加功能 Redis 使用内存存储(in-memory)的非关系数据库 字符串.列表.哈希表.集合.有序集合 每种数据类型 ...

随机推荐

  1. 【原创】Mvc学习笔记(1)

    1.新建MVC4项目 在MVC4中有App_Data文件夹,这个文件夹里可以放一些重要的数据,比如说数据库的mdf文件等等,这个文件夹非常安全,因为这个文件夹不允许被别人下载,不允许被浏览器访问. A ...

  2. asp.net mvc4 Controller与Action执行过程的研究(学习笔记)

    当IIS收到一个http请求,把请求信息发给对应的HttpModel(实际是实现类UrlRoutingModule),在HttpModel中会注册HttpApplication 类中的PostReso ...

  3. C++的类和对象

    #include <iostream> // 预处理命令 using namespace std; class Student{ // 声明一个类,类名为Student private : ...

  4. 使用ImageMagick和Tesseract进行简单数字图像识别

    使用ImageMagick和Tesseract进行简单数字图像识别 由于直接使用 tesseract 进行识别,识别率很低, ImageMagick 安装.配置及使用: 平台:winXP 1. 安装I ...

  5. 更改JENKINS主目录

    在部署时,发现直接启动WAR包没办法改主目录,而此主目录空间太小, 唯有安装TOMCAT之后进行更改... 参考文档: 工作中,由于Jenkins默认的主目录空间太小,导致需要将Jenkins默认的主 ...

  6. Hibernate 多对一关系中,在多的一方进行数据的插入

    先看两个映射关系: 部门: <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//H ...

  7. [转贴]JAVA :CXF 简介

    Apache CXF = Celtix + XFire,Apache CXF 的前身叫 Apache CeltiXfire,现在已经正式更名为 Apache CXF 了,以下简称为 CXF.CXF 继 ...

  8. Android Training精要(二)開啟ActionBar的Overlay模式

    在3.0上的實現 <resources> <!-- the theme applied to the application or activity --> <style ...

  9. linux字符图形界面

    /etc/inittab 1)  字符界面标识: id:3:initdefault: 2)  图形界面标识: id:5:initdefault:   [root@ora9i ~]# vi /etc/i ...

  10. C# winform 导出导入Excel/Doc 完整实例教程[网上看到的]

    还真没做过winform的导出导入,今天上网百度了一下.结果--- 所以还是我自己写个吧.之前做过web的,半搬半做就OK. 1添加引用:Aspose.Cells.dll(我们就叫工具包吧,可以从网上 ...