首页 体育 教育 财经 社会 娱乐 军事 国内 科技 互联网 房产 国际 女人 汽车 游戏

了解 Redis 并在 Spring Boot 项目中使用 Redis

2019-12-18

在实践的开发过程中,多多少少都会涉及到缓存,而 Redis 一般来说是咱们分布式缓存的最佳挑选。Redis 也是咱们熟知的 NoSQL之一,尽管其不能彻底的代替联系性数据库,但它可作为其杰出的弥补。本文就和咱们一同了解一下 Redis,并实战在 Spring Boot 项目运用它。

Redis 是一个开源、内存存储的数据结构服务器,可用作数据库,高速缓存和音讯行列署理。它支撑字符串、哈希表、列表、调集、有序调集等数据类型。内置仿制、Lua 脚本、LRU 回收、业务以及不同等级磁盘耐久化功用,一同经过 Redis Sentinel 供给高可用,经过 Redis Cluster 供给主动分区。

微服务以及分布式被广泛运用后,Redis 的运用场景就越来越多了,这儿我罗列了首要的几种场景。

当然 Redis 的运用场景并不仅仅只要这么多,还有许多未列出的场景,如计数、排行榜等,可见 Redis 的强壮。不过 Redis 说到底仍是一个数据库,那么咱们仍是有必要了解一下它支撑存储的数据结构。

前面也提到过,Redis 支撑字符串、哈希表、列表、调集、有序调集五种数据类型的存储。了解这五种数据结构十分重要,能够说假如吃透了这五种数据结构,你就把握了 Redis 运用常识的三分之一,下面咱们就来逐个解析。

string 这种数据结构应该是咱们最为常用的。在 Redis 中 string 表明的是一个可变的字节数组,咱们初始化字符串的内容、能够拿到字符串的长度,能够获取 string 的子串,能够掩盖 string 的子串内容,能够追加子串。

如上图所示,在 Redis 中咱们初始化一个字符串时,会选用预分配冗余空间的办法来削减内存的频频分配,如图 1 所示,实践分配的空间 capacity 一般要高于实践字符串长度 len。假如您看过 Java 的 ArrayList 的源码信任会对此种形式很了解。

在 Redis 中列表 list 选用的存储结构是双向链表,由此可见其随机定位功用较差,比较合适首位刺进删去。像 Java 中的数组相同,Redis 中的列表支撑经过下标拜访,不同的是 Redis 还为列表供给了一种负下标,-1 表明倒数一个元素,-2 表明倒数第二个数,依此类推。归纳列表首尾增删功用优异的特色,一般咱们运用 rpush/rpop/lpush/lpop 四条指令将列表作为行列来运用。

如上图所示,在列表元素较少的情况下会运用一块接连的内存存储,这个结构是 ziplist,也便是紧缩列表。它将一切的元素紧挨着一同存储,分配的是一块接连的内存。当数据量比较多的时分才会改成 quicklist。由于一般的链表需求的附加指针空间太大,会比较糟蹋空间。比方这个列表里存的仅仅 int 类型的数据,结构上还需求两个额定的指针 prev 和 next。所以 Redis 将链表和 ziplist 结合起来组成了 quicklist。也便是将多个 ziplist 运用双向指针串起来运用。这样既满意了快速的刺进删去功用,又不会呈现太大的空间冗余。

hash 与 Java 中的 HashMap 差不多,完成上选用二维结构,榜首维是数组,第二维是链表。hash 的 key 与 value 都存储在链表中,而数组中存储的则是各个链表的表头。在检索时,首要核算 key 的 hashcode,然后经过 hashcode 定位到链表的表头,再遍历链表得到 value 值。或许您比较猎奇为啥要用链表来存储 key 和 value,直接用 key 和 value 一对一存储不就能够了吗?其实是由于有些时分咱们无法确保 hashcode 值的仅有,若两个不同的 key 产生了相同的 hashcode,咱们需求一个链表在存储两对键值对,这便是所谓的 hash 磕碰。

了解 Java 的同学应该知道 HashSet 的内部完成运用的是 HashMap,只不过一切的 value 都指向同一个目标。Redis 的 Set 结构也是相同,它的内部也运用 Hash 结构,一切的 value 都指向同一个内部值。

有时也被称作 ZSet,是 Redis 中一个比较特别的数据结构,在有序调集中咱们会给每个元素赋予一个权重,其内部元素会依照权重进行排序,咱们能够经过指令查询某个规模权重内的元素,这个特性在咱们做一个排行榜的功用时能够说十分实用了。其底层的完成运用了两个数据结构, hash 和跳动列表,hash 的作用便是相关元素 value 和权重 score,保证元素 value 的仅有性,能够经过元素 value 找到相应的 score 值。跳动列表的意图在于给元素 value 排序,依据 score 的规模获取元素列表。

开端在 Spring Boot 项目中运用 Redis 之前,咱们还需求一些准备工作。

Spring Boot 官方现已为咱们供给好了集成 Redis 的 Starter,咱们只需求简略地在 pom.xml 文件中增加如下代码即可。Spring Boot 的 Starter 给咱们在项目依靠办理上供给了许多便当,假如您想了解更多 Starter 的内容,能够拜访 这篇文章 。

 dependency 
 groupId org.springframework.boot /groupId 
 artifactId spring-boot-starter-data-redis /artifactId 
 /dependency 

增加完依靠之后,咱们还需求装备 Redis 的地址等信息才干运用,在 application.properties 中增加如下装备即可。

spring.redis.host=192.168.142.132
spring.redis.port=6379
# Redis 数据库索引
spring.redis.database=0 
# Redis 服务器衔接端口
# Redis 服务器衔接暗码
spring.redis.password=
#衔接池最大衔接数
spring.redis.jedis.pool.max-active=8
# 衔接池最大堵塞等待时刻
spring.redis.jedis.pool.max-wait=-1
# 衔接池中的最大闲暇衔接
spring.redis.jedis.pool.max-idle=8
# 衔接池中的最小闲暇衔接
spring.redis.jedis.pool.min-idle=0
# 衔接超时时刻
spring.redis.timeout=0

Spring Boot 的 spring-boot-starter-data-redis 为 Redis 的相关操作供给了一个高度封装的 RedisTemplate 类,而且对每种类型的数据结构都进行了归类,将同一类型操作封装为 operation 接口。RedisTemplate 对五种数据结构别离界说了操作,如下所示:

redisTemplate.opsForValue
Hash:redisTemplate.opsForHash
List:redisTemplate.opsForList
Set:redisTemplate.opsForSet
ZSet:redisTemplate.opsForZSet

可是关于 string 类型的数据,Spring Boot 还专门供给了 StringRedisTemplate 类,而且官方也主张运用该类来操作 String 类型的数据。那么它和 RedisTemplate 又有啥差异呢?

一个 Spring Boot 项目中,咱们只需求保护一个 RedisTemplate 目标和一个 StringRedisTemplate 目标就能够了。所以咱们需求经过一个 Configuration 类来初始化这两个目标而且交由的 BeanFactory 办理。咱们在 cn.itweknow.sbredis.config 包下面新建了一个 RedisConfig 类,其内容如下所示:

@Configuration
public class RedisConfig {
 @Bean
 @ConditionalOnMissingBean
 public RedisTemplate String, Object redisTemplate {
 Jackson2JsonRedisSerializer Object jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer Object ;
 ObjectMapper om = new ObjectMapper;
 om.setVisibility;
 om.enableDefaultTyping;
 jackson2JsonRedisSerializer.setObjectMapper;
 RedisTemplate String, Object template = new RedisTemplate String, Object 
 template.setConnectionFactory;
 template.setKeySerializer;
 template.setValueSerializer;
 template.setHashKeySerializer;
 template.setHashValueSerializer;
 template.afterPropertiesSet;
 return template;
 @Bean
 @ConditionalOnMissingBean
 public StringRedisTemplate stringRedisTemplate {
 StringRedisTemplate template = new StringRedisTemplate;
 template.setConnectionFactory;
 return template;
}

StringRedisTempalte 在上面现已初始化好了,咱们只需求在需求用到的当地经过 @AutoWired 注解注入就行。

@Test
public void testSet {
 stringRedisTemplate.opsForValue.set.get 办法来获取指定 key 对应的 value 值。 
@Test
public void testGet {
 String value = stringRedisTemplate.opsForValue.get;
}
设置值的时分设置过期时刻。在设置缓存的时分,咱们一般都会给他设置一个过期时刻,让其能够到达守时改写的作用。 StringRedisTemplate 供给了 void set 办法来到达设置过期时刻的意图,其间 var3 这个参数便是过期时刻的数值,而 TimeUnit 是个枚举类型,咱们用它来设置过期时刻的单位,是小时或是秒等等。
@Test
public void testSetTimeOut {
 stringRedisTemplate.opsForValue.set;
}
删去数据,咱们相同能够经过 StringRedisTmeplate 来删去数据, Boolean delete 办法供给了这个功用。
@Test
public void testDeleted {
 stringRedisTemplate.delete ,往 List 左面刺进一个元素,如 从左面往数组中 push 元素: 
@Test
 public void testLeftPush {
 redisTemplate.opsForList.leftPush 

,往 List 右侧刺进一个元素, 如从右边往数组中 push 元素:

@Test
 public void testRightPush {
 redisTemplate.opsForList.rightPush,从 List 左面取出榜首个元素,并移除, 如从数组头部获取并移除值:

@Test
public void testLeftPop {
 Object leftFirstElement = redisTemplate.opsForList.leftPop;
}

履行上面的代码之后,您会看到控制台会打印出 TestLeftPush,然后再去 RedisDesktopManager 中检查 TestList 的内容,如下图 所示。您会发现数组中的榜首个元素现已被移除了。

rightPop ,从 List 右侧取出榜首个元素,并移除, 如从数组尾部获取并移除值:
@Test
 public void testRightPop {
 Object rightFirstElement = redisTemplate.opsForList.rightPop;
 }
操作 Hash

Redis 中的 Hash 数据结构实践上与 Java 中的 HashMap 是十分相似的,供给的 API 也很相似。下面咱们就一同来看下 RedisTemplate 为 Hash 供给了哪些 API。

Hash 中新增元素。
@Test
public void testPut {
 redisTemplate.opsForHash.put.hasKey);
}
判别指定 key 对应的 Hash 中是否存在指定的 map 键,运用用法能够见上方代码所示。 获取指定 key 对应的 Hash 中指定键的值。
@Test
public void testGet {
 Object element = redisTemplate.opsForHash.get;
}
删去指定 key 对应 Hash 中指定键的键值对。
@Test
public void testDel {
 redisTemplate.opsForHash.delete.hasKey);
}
操作调集

调集很相似于 Java 中的 Set, RedisTemplate 也为其供给了丰厚的 API。

向调集中增加元素。
@Test
public void testAdd {
 redisTemplate.opsForSet.add.size;
}
获取调集中的元素。
@Test
public void testGet {
 Set String testSet = redisTemplate.opsForSet.members;
}

履行上面的代码后,控制台输出的是 [e1, e3, e2] ,当然您或许会看到其他成果,由于 Set 是无序的,并不是依照咱们增加的次序来排序的。

获取调集的长度,在像调集中增加元素的示例代码中展现了怎么获取调集长度。 移除调集中的元素。'
@Test
public void testRemove {
 redisTemplate.opsForSet.remove.members[0]);
}
操作有序调集

与 Set 不相同的当地是,ZSet 关于调集中的每个元素都保护了一个权重值,那么 RedisTemplate 供给了不少与这个权重值相关的 API。

@Test
public void testGet {
 String value = stringRedisTemplate.opsForValue.get;
}
@Test
public void testSetTimeOut {
 stringRedisTemplate.opsForValue.set;
}
@Test
public void testDeleted {
 stringRedisTemplate.delete ,往 List 左面刺进一个元素,如 从左面往数组中 push 元素: 
@Test
 public void testLeftPush {
 redisTemplate.opsForList.leftPush 

,往 List 右侧刺进一个元素, 如从右边往数组中 push 元素:

@Test
 public void testRightPush {
 redisTemplate.opsForList.rightPush,从 List 左面取出榜首个元素,并移除, 如从数组头部获取并移除值:

@Test
public void testLeftPop {
 Object leftFirstElement = redisTemplate.opsForList.leftPop;
}

履行上面的代码之后,您会看到控制台会打印出 TestLeftPush,然后再去 RedisDesktopManager 中检查 TestList 的内容,如下图 所示。您会发现数组中的榜首个元素现已被移除了。

rightPop ,从 List 右侧取出榜首个元素,并移除, 如从数组尾部获取并移除值:
@Test
 public void testRightPop {
 Object rightFirstElement = redisTemplate.opsForList.rightPop;
 }
操作 Hash

Redis 中的 Hash 数据结构实践上与 Java 中的 HashMap 是十分相似的,供给的 API 也很相似。下面咱们就一同来看下 RedisTemplate 为 Hash 供给了哪些 API。

Hash 中新增元素。
@Test
public void testPut {
 redisTemplate.opsForHash.put.hasKey);
}
判别指定 key 对应的 Hash 中是否存在指定的 map 键,运用用法能够见上方代码所示。 获取指定 key 对应的 Hash 中指定键的值。
@Test
public void testGet {
 Object element = redisTemplate.opsForHash.get;
}
删去指定 key 对应 Hash 中指定键的键值对。
@Test
public void testDel {
 redisTemplate.opsForHash.delete.hasKey);
}
操作调集

调集很相似于 Java 中的 Set, RedisTemplate 也为其供给了丰厚的 API。

向调集中增加元素。
@Test
public void testAdd {
 redisTemplate.opsForSet.add.size;
}
获取调集中的元素。
@Test
public void testGet {
 Set String testSet = redisTemplate.opsForSet.members;
}

履行上面的代码后,控制台输出的是 [e1, e3, e2] ,当然您或许会看到其他成果,由于 Set 是无序的,并不是依照咱们增加的次序来排序的。

获取调集的长度,在像调集中增加元素的示例代码中展现了怎么获取调集长度。 移除调集中的元素。'
@Test
public void testRemove {
 redisTemplate.opsForSet.remove.members[0]);
}
操作有序调集

与 Set 不相同的当地是,ZSet 关于调集中的每个元素都保护了一个权重值,那么 RedisTemplate 供给了不少与这个权重值相关的 API。

@Test
 public void testLeftPush {
 redisTemplate.opsForList.leftPush 

,往 List 右侧刺进一个元素, 如从右边往数组中 push 元素:

@Test
 public void testRightPush {
 redisTemplate.opsForList.rightPush,从 List 左面取出榜首个元素,并移除, 如从数组头部获取并移除值:

@Test
public void testLeftPop {
 Object leftFirstElement = redisTemplate.opsForList.leftPop;
}

履行上面的代码之后,您会看到控制台会打印出 TestLeftPush,然后再去 RedisDesktopManager 中检查 TestList 的内容,如下图 所示。您会发现数组中的榜首个元素现已被移除了。

rightPop ,从 List 右侧取出榜首个元素,并移除, 如从数组尾部获取并移除值:
@Test
 public void testRightPop {
 Object rightFirstElement = redisTemplate.opsForList.rightPop;
 }
操作 Hash

Redis 中的 Hash 数据结构实践上与 Java 中的 HashMap 是十分相似的,供给的 API 也很相似。下面咱们就一同来看下 RedisTemplate 为 Hash 供给了哪些 API。

Hash 中新增元素。
@Test
public void testPut {
 redisTemplate.opsForHash.put.hasKey);
}
判别指定 key 对应的 Hash 中是否存在指定的 map 键,运用用法能够见上方代码所示。 获取指定 key 对应的 Hash 中指定键的值。
@Test
public void testGet {
 Object element = redisTemplate.opsForHash.get;
}
删去指定 key 对应 Hash 中指定键的键值对。
@Test
public void testDel {
 redisTemplate.opsForHash.delete.hasKey);
}
操作调集

调集很相似于 Java 中的 Set, RedisTemplate 也为其供给了丰厚的 API。

向调集中增加元素。
@Test
public void testAdd {
 redisTemplate.opsForSet.add.size;
}
获取调集中的元素。
@Test
public void testGet {
 Set String testSet = redisTemplate.opsForSet.members;
}

履行上面的代码后,控制台输出的是 [e1, e3, e2] ,当然您或许会看到其他成果,由于 Set 是无序的,并不是依照咱们增加的次序来排序的。

获取调集的长度,在像调集中增加元素的示例代码中展现了怎么获取调集长度。 移除调集中的元素。'
@Test
public void testRemove {
 redisTemplate.opsForSet.remove.members[0]);
}
操作有序调集

与 Set 不相同的当地是,ZSet 关于调集中的每个元素都保护了一个权重值,那么 RedisTemplate 供给了不少与这个权重值相关的 API。

,往 List 右侧刺进一个元素, 如从右边往数组中 push 元素:

@Test
 public void testRightPush {
 redisTemplate.opsForList.rightPush,从 List 左面取出榜首个元素,并移除, 如从数组头部获取并移除值:

@Test
public void testLeftPop {
 Object leftFirstElement = redisTemplate.opsForList.leftPop;
}

履行上面的代码之后,您会看到控制台会打印出 TestLeftPush,然后再去 RedisDesktopManager 中检查 TestList 的内容,如下图 所示。您会发现数组中的榜首个元素现已被移除了。

rightPop ,从 List 右侧取出榜首个元素,并移除, 如从数组尾部获取并移除值:
@Test
 public void testRightPop {
 Object rightFirstElement = redisTemplate.opsForList.rightPop;
 }
操作 Hash

Redis 中的 Hash 数据结构实践上与 Java 中的 HashMap 是十分相似的,供给的 API 也很相似。下面咱们就一同来看下 RedisTemplate 为 Hash 供给了哪些 API。

Hash 中新增元素。
@Test
public void testPut {
 redisTemplate.opsForHash.put.hasKey);
}
判别指定 key 对应的 Hash 中是否存在指定的 map 键,运用用法能够见上方代码所示。 获取指定 key 对应的 Hash 中指定键的值。
@Test
public void testGet {
 Object element = redisTemplate.opsForHash.get;
}
删去指定 key 对应 Hash 中指定键的键值对。
@Test
public void testDel {
 redisTemplate.opsForHash.delete.hasKey);
}
操作调集

调集很相似于 Java 中的 Set, RedisTemplate 也为其供给了丰厚的 API。

向调集中增加元素。
@Test
public void testAdd {
 redisTemplate.opsForSet.add.size;
}
获取调集中的元素。
@Test
public void testGet {
 Set String testSet = redisTemplate.opsForSet.members;
}

履行上面的代码后,控制台输出的是 [e1, e3, e2] ,当然您或许会看到其他成果,由于 Set 是无序的,并不是依照咱们增加的次序来排序的。

获取调集的长度,在像调集中增加元素的示例代码中展现了怎么获取调集长度。 移除调集中的元素。'
@Test
public void testRemove {
 redisTemplate.opsForSet.remove.members[0]);
}
操作有序调集

与 Set 不相同的当地是,ZSet 关于调集中的每个元素都保护了一个权重值,那么 RedisTemplate 供给了不少与这个权重值相关的 API。

@Test
public void testLeftPop {
 Object leftFirstElement = redisTemplate.opsForList.leftPop;
}

履行上面的代码之后,您会看到控制台会打印出 TestLeftPush,然后再去 RedisDesktopManager 中检查 TestList 的内容,如下图 所示。您会发现数组中的榜首个元素现已被移除了。

@Test
 public void testRightPop {
 Object rightFirstElement = redisTemplate.opsForList.rightPop;
 }

Redis 中的 Hash 数据结构实践上与 Java 中的 HashMap 是十分相似的,供给的 API 也很相似。下面咱们就一同来看下 RedisTemplate 为 Hash 供给了哪些 API。

@Test
public void testPut {
 redisTemplate.opsForHash.put.hasKey);
}
@Test
public void testGet {
 Object element = redisTemplate.opsForHash.get;
}
@Test
public void testDel {
 redisTemplate.opsForHash.delete.hasKey);
}

调集很相似于 Java 中的 Set, RedisTemplate 也为其供给了丰厚的 API。

@Test
public void testAdd {
 redisTemplate.opsForSet.add.size;
}
@Test
public void testGet {
 Set String testSet = redisTemplate.opsForSet.members;
}

履行上面的代码后,控制台输出的是 [e1, e3, e2] ,当然您或许会看到其他成果,由于 Set 是无序的,并不是依照咱们增加的次序来排序的。

@Test
public void testRemove {
 redisTemplate.opsForSet.remove.members[0]);
}

与 Set 不相同的当地是,ZSet 关于调集中的每个元素都保护了一个权重值,那么 RedisTemplate 供给了不少与这个权重值相关的 API。

热门文章

随机推荐

推荐文章