ToB企服应用市场:ToB评测及商务社交产业平台

标题: SSM中操作Redis—Jedis [打印本页]

作者: 反转基因福娃    时间: 2022-8-9 14:41
标题: SSM中操作Redis—Jedis
SSM中操作Redis——Jedis

1、Jedis

2、导入依赖
  1. <dependency>
  2.     <groupId>redis.clients</groupId>
  3.     <artifactId>jedis</artifactId>
  4.     <version>2.9.0</version>
  5. </dependency>
  6. <dependency>
  7.     <groupId>junit</groupId>
  8.     <artifactId>junit</artifactId>
  9.     <version>4.12</version>
  10. </dependency>
  11. <dependency>
  12.     <groupId>org.projectlombok</groupId>
  13.     <artifactId>lombok</artifactId>
  14.     <version>1.18.12</version>
  15.     <scope>provided</scope>
  16. </dependency>
复制代码
3、简单使用
  1. @Test
  2. public void quickTest() throws Exception {
  3.     // 参数一:redis服务器ip
  4.     // 参数二:redis服务器的端口号
  5.     Jedis jedis = new Jedis("192.168.27.132", 6379);
  6.     String name = jedis.set("name", "zhangsan");
  7.     System.out.println("name = " + name);
  8.     String value = jedis.get("name");
  9.     System.out.println("value = " + value);
  10. }
复制代码
4、连接池使用
  1. @Test
  2. public void JedisPoolTestDemo() {
  3.     GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
  4.     String host = "192.168.27.132";
  5.     int port = 6379;
  6.     int timeout = 5000;
  7.     //产生连接池对象
  8.     JedisPool jedisPool = new JedisPool(poolConfig, host, port, timeout);
  9.     Jedis jedis = jedisPool.getResource();
  10.     jedis.set("name","张三");
  11.     jedis.set("name1","张三1");
  12.     jedis.set("name2","张三2");
  13.     jedis.hset("person","name","李四");
  14.     jedis.hset("person","name1","李四1");
  15.     jedis.hset("person","name2","李四2");
  16.     System.out.println(jedis.get("name"));
  17.     System.out.println(jedis.get("name1"));
  18.     System.out.println(jedis.get("name2"));
  19.     Map<String, String> person = jedis.hgetAll("person");
  20.     System.out.println("person = " + person);
  21.     //关闭后归还到连接池
  22.     jedis.close();
  23. }
复制代码
5、工具类封装连接池
  1. public class JedisPoolUtils {
  2.     private  static JedisPool jedisPool = null;
  3.     private static final String HOST = "192.168.27.132";
  4.     private static final int PORT = 6379;
  5.     private static final int TIMEOUT = 3000;
  6.     static {
  7.         GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
  8.         jedisPool = new JedisPool(poolConfig,HOST,PORT,TIMEOUT);
  9.     }
  10.     public static Jedis getResource() {
  11.         return jedisPool.getResource();
  12.     }
  13. }
复制代码
6、连接池工具类使用
  1. Jedis jedis = JedisPoolUtils.getResource(); //在连接池中获取jedis连接对象
  2. String name = jedis.get("name");
  3. System.out.println("name = " + name);
  4. jedis.close();//关闭并归还连接
复制代码
7、Jedis保存一个对象

7.1 通过json存储

思路:将创建好的对象转成json格式字符串,存储到redis中
  1. //创建对象
  2. Device device = new Device();
  3. device.setId(1);
  4. device.setDeviceName("挖掘机");
  5. device.setPrice(30000D);
  6. //json转换
  7. ObjectMapper objectMapper = new ObjectMapper();
  8. String json = objectMapper.writeValueAsString(device);
  9. //获取jedis对象
  10. Jedis jedis = JedisPoolUtils.getResource();
  11. //存储对象
  12. jedis.set("device:" + device.getId(), json);
  13. String deviceString = jedis.get("device:" + device.getId());
  14. System.out.println("deviceString = " + deviceString);
  15. //归还连接到连接池
  16. jedis.close();
复制代码
7.2 字节存储

思路:
  1. //创建对象
  2. Device device = new Device();
  3. device.setId(1);
  4. device.setDeviceName("挖掘机");
  5. device.setPrice(30000D);
  6. //获取jedis对象
  7. Jedis jedis = JedisPoolUtils.getResource();
  8. //对象转换为字节数组,使用SerializationUtils的serialize()方法
  9. byte[] key = ("device:" + device.getId()).getBytes();
  10. byte[] value = SerializationUtils.serialize(device);
  11. //存储字节
  12. jedis.set(key, value);
  13. //获取key对应的value
  14. byte[] bytes = jedis.get(key);
  15. //SerializationUtils的deserialize()方法 将字节转为对象
  16. Device device1 = (Device) SerializationUtils.deserialize(bytes);
  17. System.out.println(device1);
  18. //归还连接到连接池
  19. jedis.close();
复制代码
8、Jedis管道操作

当我们有10000条数据要存储到redis中,使用原始方式存:
  1. @Test
  2. public void tenThousandTest(){
  3.     Jedis jedis = JedisPoolUtils.getResource();
  4.     long start = System.currentTimeMillis();
  5.     for (int i = 0; i < 10000; i++) {
  6.         jedis.set("i:"+i,"v:"+i);
  7.     }
  8.     System.out.println(System.currentTimeMillis()-start);//大概4秒
  9.     jedis.close();
  10. }
复制代码
当执行完之后得到时间差,发现用时大概4秒。
为什么redis读写性能优异,却花费了4秒钟?

使用过查看redis性能命令的小伙伴会发现读写的性能能达到100000次/s
据官方的bench-mark数据:读的速度是110000次/s,写的速度是81000次/s
  1. #redis写的性能
  2. redis-benchmark set
  3. #redis读的性能
  4. redis-benchmark get
复制代码
那为什么在这里执行10000次写却用了4秒钟,是不是redis性能不靠谱啊

其实不然,我们仔细想一下,我们的jedis程序和redis服务器是在不同服务器上,
那Jedis的数据要保存到redis中就要通过网络传输
对于上面代码而言,每写一个就要传一个到redis中,一共要发送10000次,这之间消耗的时间是比较久的,也就对代码执行完之后计算得出的时间产生了影响。

那有什么提升jedis传输性能的方法呢

有,Jedis提供了一个pipelined(),也就是管道操作,我们来看升级后的代码
  1. @Test
  2. public void test(){
  3.     Jedis jedis = JedisPoolUtils.getResource();
  4.     Long start = System.currentTimeMillis();
  5.     Pipeline pipelined = jedis.pipelined();
  6.     for (int i = 0; i < 10000; i++) {
  7.         pipelined.set("k:"+i,"v:"+i);
  8.     }
  9.     System.out.println(System.currentTimeMillis()-start);//55毫秒
  10.     jedis.close();
  11. }
复制代码
最后测试发现执行几乎瞬间完成,用时55毫秒,比4秒提升了70多倍。
为什么管道操作那么快

它将所有操作都打包,一次性发给redis服务器,由原先一万次的传输变为一次传输,大大提高了传输性能,节省了时间。
而redis接收到之后做一万次写入,一万次写入对于redis来说小菜一碟。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4