首页 > 数据库 >springboot之RedisTemplate的访问单机,哨兵,集群模式

springboot之RedisTemplate的访问单机,哨兵,集群模式

时间:2023-08-23 17:37:03浏览次数:52  
标签:springboot 单机 Redis 使用 new 序列化 public RedisTemplate

springboot2默认已经使用了lettuce-core,没有使用jedis和Redisson,springboot1使用的是jedis。

我使用的springboot版本是2.6.14。(对应的lettuce版本为6.1.10.RELEASE,对应jedis版本为3.7.1)

  <dependency>
    <groupId>io.lettuce</groupId>
    <artifactId>lettuce-core</artifactId>
    <version>6.1.10.RELEASE</version>
  </dependency>
  <!-- 或者 -->
  <dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>3.7.1</version>
  </dependency>

添加依赖

<!--redis-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--连接池依赖-->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
</dependency>

spring和redis这建立连接不管你使用那种客户端都只需要使用一组Spring Data Redis API(在所有连接器上都表现一致):org.springframework.Data.Redis.connection包及其RedisConnection和RedisConnectionFactory接口,用于处理和检索Redis的活动连接。


配置Lettuce连接器(Configuring the Lettuce Connector)

@Configuration
class AppConfig {

  @Bean
  public LettuceConnectionFactory redisConnectionFactory() {

    return new LettuceConnectionFactory(new RedisStandaloneConfiguration("server", 6379));
  }
}


配置jedis连接器(Configuring the Jedis Connector)

Jedis is a community-driven connector supported by the Spring Data Redis module through the org.springframework.data.redis.connection.jedis package.

  <dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>3.7.1</version>
  </dependency>

在最简单的形式中,Jedis配置如下所示:

@Configuration
class AppConfig {

  @Bean
  public JedisConnectionFactory redisConnectionFactory() {
    return new JedisConnectionFactory();
  }
}

但是,对于生产使用,您可能需要调整主机或密码等设置,如以下示例所示:

@Configuration
class RedisConfiguration {

  @Bean
  public JedisConnectionFactory redisConnectionFactory() {

    RedisStandaloneConfiguration config = new RedisStandaloneConfiguration("server", 6379);
    return new JedisConnectionFactory(config);
  }
}

Redis主/副本设置 — 没有自动故障切换(有关自动故障切换,请参阅:Sentinel) — 不仅允许数据安全地存储在更多的节点上。它还允许使用Lettuce从复制副本读取数据,同时将写入操作推送给主控。您可以使用LettuceClientConfiguration设置要使用的读/写策略,如下例所示:

@Configuration
class WriteToMasterReadFromReplicaConfiguration {

  @Bean
  public LettuceConnectionFactory redisConnectionFactory() {

    LettuceClientConfiguration clientConfig = LettuceClientConfiguration.builder()
      .readFrom(REPLICA_PREFERRED)
      .build();

    RedisStandaloneConfiguration serverConfig = new RedisStandaloneConfiguration("server", 6379);

    return new LettuceConnectionFactory(serverConfig, clientConfig);
  }
}

注:

对于通过INFO命令报告非公共地址的环境(例如,使用AWS时),请使用RedisStaticMasterReplicaConfiguration而不是RedisStandaloneConfiguration。请注意,RedisStaticMasterReplicaConfiguration不支持Pub/Sub,因为缺少跨各个服务器的Pub/Sub消息传播。

Redis哨兵模式支持(Redis Sentinel Support)

/**
 * Jedis
 */
@Bean
public RedisConnectionFactory jedisConnectionFactory() {
  RedisSentinelConfiguration sentinelConfig = new RedisSentinelConfiguration()
  .master("mymaster")
  .sentinel("127.0.0.1", 26379)
  .sentinel("127.0.0.1", 26380);
  return new JedisConnectionFactory(sentinelConfig);
}

/**
 * Lettuce
 */
@Bean
public RedisConnectionFactory lettuceConnectionFactory() {
  RedisSentinelConfiguration sentinelConfig = new RedisSentinelConfiguration()
  .master("mymaster")
  .sentinel("127.0.0.1", 26379)
  .sentinel("127.0.0.1", 26380);
  return new LettuceConnectionFactory(sentinelConfig);
}

RedisStinelConfiguration也可以用PropertySource来定义,它允许您设置以下属性:

配置属性

spring.dis.setinel.master:主节点的名称。

spring.redis.setinel.nodes:以逗号分隔的主机:端口对列表。

spring.redis.setinel.password:使用redis sentinel进行身份验证时应用的密码

有时,需要与其中一名哨兵直接互动。使用RedisConnectionFactory.getSentinelConnection()或RedisConnection.getSentinelCommands()可以访问配置的第一个活动Sentinel。

通过RedisTemplate处理对象

大多数用户可能会使用RedisTemplate及其相应的包org.springframework.data.redis.core。由于其丰富的功能集,该模板实际上是redis模块的中心类。该模板为Redis交互提供了高级抽象。虽然RedisConnection提供了接受和返回二进制值(字节数组)的低级方法,但该模板负责序列化和连接管理,使用户无需处理这些细节。

此外,该模板提供了操作视图(遵循Redis命令引用中的分组),这些视图提供了丰富的通用接口,用于(通过KeyBound接口)对特定类型或特定密钥进行操作,如下表所示:

springboot之RedisTemplate的访问单机,哨兵,集群模式_Redis

配置后,模板是线程安全的,可以在多个实例中重用。

RedisTemplate的大部分操作都使用基于Java的序列化程序。这意味着模板编写或读取的任何对象都是通过Java序列化和反序列化的。您可以更改模板上的序列化机制,Redis模块提供了几个实现,这些实现在org.springframework.data.Redis.serializer包中提供。有关详细信息,请参阅序列化程序。您还可以将任何序列化程序设置为null,并通过将enableDefaultSerializer属性设置为false将RedisTemplate与原始字节数组一起使用。请注意,该模板要求所有键都为非null。但是,只要底层序列化程序接受值,它们就可以为null。有关详细信息,请阅读每个序列化程序的Javadoc。

对于需要某个模板视图的情况,请将该视图声明为依赖项并注入模板。容器会自动执行转换,从而消除opsFor[X]调用,如下例所示:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:p="http://www.springframework.org/schema/p"
  xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">

  <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" p:use-pool="true"/>
  <!-- redis template definition -->
  <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate" p:connection-factory-ref="jedisConnectionFactory"/>
  ...

</beans>
public class Example {

  // inject the actual template
  @Autowired
  private RedisTemplate<String, String> template;

  // inject the template as ListOperations
  @Resource(name="redisTemplate")
  private ListOperations<String, String> listOps;

  public void addLink(String userId, URL url) {
    listOps.leftPush(userId, url.toExternalForm());
  }
}

以字符串为中心的便利类(StringRedistTemplate)

由于Redis中存储的键和值是java.lang.String是很常见的,Redis模块为RedisConnection和RedisTemplate提供了两个扩展,分别是StringRedisConnect(及其DefaultStringRedisConfiguration实现)和StringRedistTemplate,作为密集String操作的一站式解决方案。除了绑定到String键之外,模板和连接还使用下面的StringRedisSerializer,这意味着存储的键和值是可读的(假设Redis和代码中使用相同的编码)。以下列表显示了一个示例:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:p="http://www.springframework.org/schema/p"
  xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">

  <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" p:use-pool="true"/>

  <bean id="stringRedisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate" p:connection-factory-ref="jedisConnectionFactory"/>
  ...
</beans>
public class Example {

  @Autowired
  private StringRedisTemplate redisTemplate;

  public void addLink(String userId, URL url) {
    redisTemplate.opsForList().leftPush(userId, url.toExternalForm());
  }
}

与其他Spring模板一样,RedisTemplate和StringRedisTemplate可以通过RedisCallback接口直接与Redis对话。此功能可以完全控制您,因为它可以直接与RedisConnection对话。请注意,当使用StringRedisTemplate时,回调将接收StringRedisConnection的实例。下面的例子展示了如何使用RedisCallback接口:

public void useCallback() {

  redisTemplate.execute(new RedisCallback<Object>() {
    public Object doInRedis(RedisConnection connection) throws DataAccessException {
      Long size = connection.dbSize();
      // Can cast to StringRedisConnection if using a StringRedisTemplate
      ((StringRedisConnection)connection).set("key", "value");
    }
   });
}

序列化(Serializers)

从框架的角度来看,Redis中存储的数据只有字节。虽然Redis本身支持各种类型,但在大多数情况下,这些类型指的是数据的存储方式,而不是它所代表的内容。由用户决定是将信息转换为字符串还是任何其他对象。

在Spring Data中,用户(自定义)类型和原始数据之间的转换(反之亦然)由org.springframework.Data.Redis.serializer包中的Redis处理。

该包包含两种类型的序列化程序,顾名思义,它们负责序列化过程:

基于RedisSerializer的双向序列化程序。

使用RedisElementReader和RedisElementWriter的元素读取器和写入程序。

这些变体之间的主要区别在于RedisSerializer主要序列化到byte[],而读写器使用ByteBuffer。

有多种实现可用(包括本文档中已经提到的两种):

1、JdkSerializationRedisSerializer,默认用于RedisCache和RedisTemplate。
2、StringRedisSerializer。

但是,可以通过Spring OXM支持使用OxmSerializer进行Object/XML映射,或者使用Jackson2JsonRedisSerializer或GenericJackson2J sonRedisSserializer以JSON格式存储数据。

请注意,存储格式不仅限于值。它可以用于键、值或哈希,没有任何限制。

默认情况下,RedisCache和RedisTemplate配置为使用Java本机序列化。众所周知,Java本机序列化允许运行由有效负载引起的远程代码,这些有效负载利用易受攻0击的库和类注入未经验证的字节码。操作输入可能导致在反序列化步骤期间在应用程序中运行不需要的代码。因此,不要在不受信任的环境中使用序列化。通常,我们强烈建议使用任何其他消息格式(如JSON)。

Hash mapping(哈希映射)

可以使用Redis中的各种数据结构来存储数据。Jackson2JsonRedisSerializer可以转换JSON格式的对象。理想情况下,JSON可以通过使用纯键存储为值。通过使用Redis散列,可以实现更复杂的结构化对象映射。Spring Data Redis提供了各种将数据映射到哈希的策略(取决于用例):

1、直接映射,使用HashOperations和序列化程序进行。

2、使用Redis存储库。

3、使用HashMapper和HashOperations。

Hash Mappers

Hash mappers 是映射对象到map<K,V>和返回的转换器。HashMapper用于Redis哈希。

有多种实施方式可用:

以下示例显示了一种实现哈希映射的方法:

public class Person {
  String firstname;
  String lastname;

  // …
}

public class HashMapping {

  @Autowired
  HashOperations<String, byte[], byte[]> hashOperations;

  HashMapper<Object, byte[], byte[]> mapper = new ObjectHashMapper();

  public void writeHash(String key, Person person) {

    Map<byte[], byte[]> mappedHash = mapper.toHash(person);
    hashOperations.putAll(key, mappedHash);
  }

  public Person loadHash(String key) {

    Map<byte[], byte[]> loadedHash = hashOperations.entries("key");
    return (Person) mapper.fromHash(loadedHash);
  }
}

Jackson2HashMapper

Jackson2HashMapper通过使用FasterXMLJackson为域对象提供Redis哈希映射。Jackson2HashMapper可以将顶级属性映射为哈希字段名,还可以选择展平结构。简单类型映射到简单值。复杂类型(嵌套对象、集合、映射等)表示为嵌套JSON。

扁平化为所有嵌套属性创建单独的哈希条目,并尽可能将复杂类型解析为简单类型。

考虑以下类及其包含的数据结构:

public class Person {
  String firstname;
  String lastname;
  Address address;
  Date date;
  LocalDateTime localDateTime;
}

public class Address {
  String city;
  String country;
}

The following table shows how the data in the preceding class would appear in normal mapping:

springboot之RedisTemplate的访问单机,哨兵,集群模式_spring_02

The following table shows how the data in the preceding class would appear in flat mapping:

springboot之RedisTemplate的访问单机,哨兵,集群模式_spring_03

扁平化要求所有属性名称不干扰JSON路径。使用展开时,不支持在映射键中使用点或括号或将其用作特性名称。生成的哈希无法映射回对象。

java.util.Date和java.util.Calendar用毫秒表示。如果jackson-datatype-jsr310在类路径上,JSR-310日期/时间类型将序列化为它们的toString形式。





Redis集群模式(Redis Cluster)

启用Redis群集

集群支持基于与非集群通信相同的构建块。RedisClusterConnection是RedisConnection的扩展,它处理与Redis集群的通信,并将错误转换为Spring DAO异常层次结构。RedisClusterConnection实例是使用RedisConnectionFactory创建的,必须使用关联的RedisCluster配置进行设置,如下例所示:

@Component
@ConfigurationProperties(prefix = "spring.redis.cluster")
public class ClusterConfigurationProperties {

    /*
     * spring.redis.cluster.nodes[0] = 127.0.0.1:7379
     * spring.redis.cluster.nodes[1] = 127.0.0.1:7380
     * ...
     */
    List<String> nodes;

    /**
     * Get initial collection of known cluster nodes in format {@code host:port}.
     *
     * @return
     */
    public List<String> getNodes() {
        return nodes;
    }

    public void setNodes(List<String> nodes) {
        this.nodes = nodes;
    }
}

@Configuration
public class AppConfig {

    /**
     * Type safe representation of application.properties
     */
    @Autowired ClusterConfigurationProperties clusterProperties;

    public @Bean RedisConnectionFactory connectionFactory() {

        return new JedisConnectionFactory(
            new RedisClusterConfiguration(clusterProperties.getNodes()));
    }
}

RedisClusterConfiguration也可以通过PropertySource定义,并具有以下属性:

配置属性

spring.redis.cluster.nodes:host:port对的逗号分隔列表。
spring.redis.cluster.max-redirects:允许的群集重定向数。

使用Redis群集连接

如前所述,Redis集群的行为与单节点Redis甚至Sentinel监控的主副本环境不同。这是因为自动分片将一个密钥映射到16384个槽中的一个,这些槽分布在节点之间。因此,涉及多个密钥的命令必须断言所有密钥映射到完全相同的插槽,以避免跨插槽错误。单个集群节点仅提供一组专用密钥。针对某个特定服务器发出的命令只返回该服务器提供的密钥的结果。作为一个简单的例子,可以考虑KEYS命令。当发布到集群环境中的服务器时,它只返回请求发送到的节点提供的密钥,而不一定返回集群中的所有密钥。因此,要获得集群环境中的所有密钥,必须从所有已知的主节点读取密钥。

虽然特定密钥到相应插槽服务节点的重定向由驱动程序库处理,但RedisClusterConnection涵盖了更高级别的功能,如跨节点收集信息或向群集中的所有节点发送命令。根据前面的keys示例,这意味着keys(pattern)方法会拾取集群中的每个主节点,并在每个主节点上同时运行keys命令,同时拾取结果并返回累积的密钥集。只请求单个节点的密钥RedisClusterConnection为这些方法(例如,密钥(node,pattern))提供了重载。

RedisClusterNode可以从RedisCluster Connection.clusterGetNodes获得,也可以使用主机和端口或节点Id来构建。

以下示例显示了在集群中运行的一组命令:

示例6。在集群中运行命令的示例

springboot之RedisTemplate的访问单机,哨兵,集群模式_spring_04

当所有密钥映射到同一插槽时,本机驱动程序库会自动提供跨插槽请求,例如MGET。然而,一旦情况并非如此,RedisClusterConnection就会对插槽服务节点运行多个并行GET命令,并再次返回累积结果。这种方法的性能不如单槽方法,因此应谨慎使用。如果有疑问,可以考虑通过在花括号中提供前缀将密钥固定到同一个插槽,例如{myprefix}.thing1和{myprefix}.thing2,它们都将映射到同一插槽编号。以下示例显示跨插槽请求处理:

springboot之RedisTemplate的访问单机,哨兵,集群模式_Redis_05

前面的示例演示了Spring Data Redis所遵循的一般策略。请注意,有些操作可能需要将大量数据加载到内存中才能计算所需的命令。此外,并非所有跨槽请求都可以安全地移植到多个单槽请求,如果误用,则会出现错误(例如,PFCOUNT)。

使用RedisTemplate和ClusterOperations

使用任何JSON RedisSerializer设置RedisTemplate#keySerializer时要小心,因为更改JSON结构会直接影响哈希槽计算。

RedisTemplate通过ClusterOperations接口提供对集群特定操作的访问,该接口可以从RedisTemplate.opsForCluster()获得。这使您可以在集群中的单个节点上显式运行命令,同时保留为模板配置的序列化和反序列化功能。它还提供管理命令(如CLUSTER MEET)或更高级的操作(例如,重新发布)。

以下示例显示如何使用RedisTemplate访问RedisClusterConnection:

springboot之RedisTemplate的访问单机,哨兵,集群模式_Redis_06


Redis Repositories


标签:springboot,单机,Redis,使用,new,序列化,public,RedisTemplate
From: https://blog.51cto.com/lenglingx/7205078

相关文章

  • SpringBoot集成liquibase
    Liquibase是一个用于跟踪、管理和应用数据库变化的开源的数据库重构工具。它将所有数据库的变化(包括结构和数据)都保存在XML文件中,便于版本控制。前置准备创建一个SpringBoot项目开发环境SpringBoot-2.7.14�Java(jdk8)Mysql-8.0.27开始集成引入坐标mysql-conne......
  • 任务调度工具_Spring Task在SpringBoot中使用教程
    ##SpringTask1.1介绍SpringTask是Spring框架提供的任务调度工具,可以按照约定的时间自动执行某个代码逻辑。定位:定时任务框架作用:定时自动执行某段Java代码为什么要在Java程序中使用SpringTask?应用场景:1).信用卡每月还款提醒2).银行贷款每月还款提醒3).火车......
  • springboot整合资源文件
    1:什么是SpringBoot?SpringBoot基于Spring4.0设计,不仅继承了Spring框架原有的优秀特性,而且还通过==简化配置==来进一步简化Spring应用的整个搭建和开发过程。另外SpringBoot还通过继承大量框架使依赖包的版本冲突,以及引用不稳定性等问题的到了很好的解决。2:SpringBoot的优点(1)可以......
  • 基于Springboot的个人网站的设计与实现-计算机毕业设计源码+LW文档
    一、设计(论文)选题的依据1.研究背景与意义现在越来越多的人关注网站的自动化设计与开发,什么是个人网站呢?它的出现和运营究竟承载这怎样的信息?这并不是每个人都清楚的很多人无法准确的理解个人网站的优势和作用,我对网站的认识还处于相当低的程度中所以在正文开始前我想先阐述自己对......
  • Vue+SpringBoot项目分离部署踩坑记录
    昨天花了一晚上终于成功部署了个人网站,在这个过程中踩了很多坑,现在回顾总结记录一下,以免今后继续犯错误前端:Vue后端:SpringBoot数据库:Mysql一、前端1、前端项目采用Nginx进行部署,其中Nginx配置文件部分内容如下nginx.conf部分内容1server{2listen443ssl......
  • idea无法构建springboot工程
    1、出现的问题Initializationfailedfor'http://start.aliyun.com'PleasecheckURL,networkandproxysettings.Errormessage:ErrorparsingJSONresponse 2.解决方案   ......
  • SpringBoot整合FFmpeg进行视频分片上传------>Windows
    SpringBoot整合FFmpeg进行视频分片上传------>Windows分片上传的核心思路:将文件按一定的分割规则(静态或动态设定,如手动设置20M为一个分片),用slice分割成多个数据块。为每个文件生成一个唯一标识Key,用于多数据块上传时区分所属文件。所有分片上传完成,服务端校验合并标识为Key的......
  • Springboot生成二维码整合
    Springboot生成二维码整合我们使用两种方式,去生成二维码,但是其实,二维码的生成基础,都是zxing包,这是Google开源的一个包,第一种是使用原始的zxing方式去实现,第二种是使用hutool来实现,hutool其实也是对于zxing的一个封装,但是封装前后,确实比较简单了。Zxing原生方式添加依赖<!--zx......
  • 原来你是这样的SpringBoot--初识SpringBootAdmin
    简介SpringBootAdmin(SBA)是一个针对spring-boot的actuator接口进行UI美化封装的监控工具。它可以:在列表中浏览所有被监控spring-boot项目的基本信息,详细的Health信息、内存信息、JVM信息、垃圾回收信息,还可以直接修改logger日志的level。SBA分为server端和client端,下面来看一个......
  • redhat8.6 安装 19c 单机
    hosts文件配置echo"192.168.2.8319c">>/etc/hostscat/etc/hostsecho"exportLANG=en_US.UTF8">>~/.bash_profilecat~/.bash_profile挂载镜像mount/dev/cdrom/mntcd/etc/yum.repos.dmkdirbkmv*.repobk/echo"[EL8-1]&quo......