整理了以前学习 redis 的笔记,强烈建议看最后总结。html
在大型系统数据读请求中,基本上90%均可以经过分布式缓存集群来抗下来,而 Redis 又是分布式缓存集群的主要践行者,所以了解 Redis 是必不可少的技能。java
在 javaWeb 中实现对 Redis 的操做,主要有两种方式:Jedis、RedisTemplate。redis
Jedis 是 Redis 官方推荐的面向 Java 的操做Redis 的客户端,经过jedis咱们能够实现链接Redis,以及操做 Redis 。spring
RedisTemplate 是 SpringDataRedis 中对JedisAp i的高度封装。SpringDataRedis 相对于 Jedis 来讲能够方便地更换 Redis 的 Java客户端,比 Jedis 多了自动管理链接池的特性,方便与其余 Spring 框架进行搭配使用如:SpringCache数据库
就像在学习 springmvc 框架以前学习 servlet 同样,了解 jedis 的使用,看一下单机中 Jedis 的使用,首先要导入相关架包,
jedis.jar数组
import redis.clients.jedis.Jedis;
public class RedisJava {
public static void main(String[] args) {
//链接本地的 Redis 服务
Jedis jedis = new Jedis("localhost");
System.out.println("链接成功");
//查看服务是否运行
System.out.println("服务正在运行: "+jedis.ping());
}
}
编译以上 Java 程序,确保驱动包的路径是正确的,打印以下:缓存
链接成功
服务正在运行: PONG
redis 中最主要的就是读写数据。Redis 操做5大基本类型:String、List、Hash、Set、SortedSe。t
菜鸟教程中关于 Redis 操做 String 、List 等:http://www.runoob.com/redis/redis-java.html安全
首先咱们若是每次使用缓存都生成一个 Jedis 对象的话,这样意味着会创建不少 socket 链接,形成系统资源被不可控调用,甚至会致使奇怪错误的发生。微信
若是使用单例模式,在线程安全模式下适应不了高并发的需求,非线程安全模式又可能会出现与时间相关的错误。网络
所以,为了不这些问题,引入了池的概念 JedisPool。JedissPool 是一个线程安全的网络链接池,咱们能够经过 JedisPool 建立和管理 Jedis 实例,这样能够有效的解决以上问题以实现系统的高性能。
咱们能够理解成项目中的数据库链接池,例如:阿里巴巴的 druid~
优势 | 缺点 | |
---|---|---|
直连 | 简单方便适用于少许长期链接的场景 | 存在每次新建/关闭TCP开销,资源没法控制,存在链接泄露的可能,Jedis对象线程不安全 |
链接池 | Jedis预先生成,下降开销,链接池的形式保护和控制资源的使用 | 相对于直连,使用相对麻烦,尤为在资源管理上须要不少参数来保证,一旦规划不合理也会出现问题。 |
private static JedisPool pool = null;
if( pool == null ){
JedisPoolConfig config = new JedisPoolConfig();
控制一个pool可分配多少个jedis实例,经过pool.getResource()来获取;
若是赋值为-1,则表示不限制;若是pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽)。
config.setMaxTotal(50);
控制一个pool最多有多少个状态为idle(空闲的)的jedis实例。
config.setMaxIdle(5);
表示当borrow(引入)一个jedis实例时,最大的等待时间,若是超过等待时间,则直接抛出JedisConnectionException;单位毫秒
小于零:阻塞不肯定的时间, 默认-1
config.setMaxWaitMillis(1000*100);
在borrow(引入)一个jedis实例时,是否提早进行validate操做;若是为true,则获得的jedis实例均是可用的;
config.setTestOnBorrow(true);
return 一个jedis实例给pool时,是否检查链接可用性(ping())
config.setTestOnReturn(true);
connectionTimeout 链接超时(默认2000ms)
soTimeout 响应超时(默认2000ms)
}
获取实例
public static Jedis getJedis() {
return pool.getResource();
}
释放 redis
public static void returnResource(Jedis jedis) {
if(jedis != null) {
jedis.close();
}
}
JedisPool的配置参数大部分是由JedisPoolConfig的对应项来赋值的。
经过最开始的简单概述,咱们了解到 SpringDataRedis(RedisTemplate) 相对于 Jedis 来讲能够方便地更换 Redis 的 Java 客户端,比 Jedis 多了自动管理链接池的特性,方便与其余 Spring 框架进行搭配使用如:SpringCache;
或者能够理解成,redisTemplate 是对 Jedis 的对 redis 操做的扩展,有更多的操做, 封装使操做更便捷。
首先说一下,序列化,由于 redis 存储的数据必需要通过序列化处理。
那么你要知道 SDK 默认采用的序列化策略有两种,一种是 String 的序列化策略,一种是 JDK 的序列化策略。
在说如何使用以前再引伸出来个 StringRedisTemplate….
经过上边咱们清楚了 RedisTemplate ,可是这个 StringRedisTemplate 又是个啥呢?
其实做用是同样的? what???
其实他们二者之间的区别主要在于他们使用的序列化类。
RedisTemplate 使用的是 JdkSerializationRedisSerializer (JDK 序列化)
StringRedisTemplate 使用的是 StringRedisSerializer(String 序列化)
RedisTemplate :
RedisTemplate 使用的序列类在在操做数据的时候,好比说存入数据会将数据先序列化成字节数组,而后在存入 Redis 数据库,这个时候打开 Redis 查看的时候,你会看到你的数据不是以可读的形式展示的,而是以字节数组显示,相似下面:
StringRedisTemplate
当Redis当中的数据值是以可读的形式显示出来的时候,只能使用StringRedisTemplate才能获取到里面的数据。
因此当你使用RedisTemplate获取不到数据的时候请检查一下是否是Redis里面的数据是可读形式而非字节数组。
序列化总结
当你的 redis 数据库里面原本存的是字符串数据或者你要存取的数据就是字符串类型数据的时候,那么你就使用 StringRedisTemplate 便可,可是若是你的数据是复杂的对象类型,而取出的时候又不想作任何的数据转换,直接从 Redis 里面取出一个对象,那么使用RedisTemplate 是更好的选择。
不太喜欢写长篇文章,总感受太长的篇幅本身都不喜欢看下去,因此就此总结一下,实战就放下一篇吧。
Jedis 是 Redis 官方推荐的面向 Java 操做 Redis 的客户端,但在项目中使用 Jedis jedis = new Jedis("xxx"); 的操做有失大雅,就比如还在用 servlet…,同时用 JedisPool 来得到链接进行 get、set、del 等操做也相对简单,可是须要注意的是,存入 Redis 是须要序列化的,至于选择哪一种序列化须要本身抉择;
再说到 RedisTemplate,Spring 针对 Redis 的使用,封装了一个比较强大的 Template ,在没有这个 Template 以前,是使用 Jedis 直连进行相应的交互操做,值得一提的是,作这个封装的是 SpringData,简单了解一下 SpringData:
Spring Data: Spring 的一个子项目。用于简化数据库访问,支持NoSQL和关系数据库存储。其主要目标是使数据库的访问变得方便快捷。
Spring Data 项目所支持 NoSQL 存储:
- - MongoDB(文档数据库)
- - Neo4j (图形数据库)
- - Redis(键/值存储)
- - Hbase(列族数据库)
Spring Data 项目所支持的关系数据存储技术:
- - JDBC
- - JPA
从以前了解的 SpringDataJpa,咱们不难想象,RedisTemplate 的使用也必定是很是简单的,下一篇看一下项目中的应用。
最后:来都来了,左上角不关注一下吗。
若是文章有错的地方欢迎指正,你们互相留言交流。习惯在微信看技术文章,想要获取更多的Java资源的同窗,能够关注微信公众号:niceyoo