《一步到位,走进一站式服务治理时代:Redis管理16个数据库的最佳实践》

news2024/9/25 7:21:17

目录

1. 我们为什么要使用Redis缓存数据库?

2. 关系型与非关系型数据库有哪些区别?

3. Redis中的缓存问题与解决方案:穿透、击穿、雪崩 

4. 为什么要在一个项目中使用/管理16个数据库呢? 

5. 使用16个数据库比使用1个数据库的好处在哪里? 

6. 怎么将应用集成到项目开发中使用?

6.1 配置application.yml文件

6.2 Redis缓存数据库核心配置文件

6.3 Redis一站式服务治理核心配置文件

6.4 测试

1. 我们为什么要使用Redis缓存数据库?

  • 快速的内存存储:Redis是一种基于内存的高性能键值存储系统,读取和写入都发生在内存中,这使得它具有极快的读写速度。相比于传统的磁盘存储系统(如关系型数据库),Redis可以提供更低的延迟和更高的吞吐量。

  • 缓存加速:作为缓存层,Redis常用于提升应用程序的性能。它可以将经常访问的数据存储在内存中,从而避免了频繁地访问磁盘或数据库。这可以大大减少应用程序的响应时间,并减轻后端数据库的负载。

  • 数据结构丰富:Redis支持多种数据结构,如字符串、哈希表、列表、集合和有序集合等。这使得Redis不仅可以作为简单的键值存储使用,还可以处理更复杂的数据操作,如计数器、排行榜、发布与订阅等。

  • 高可用性和容错性:Redis提供了主从复制和Sentinel机制来实现高可用性和容错性。通过复制数据到多个副本,当主节点发生故障时,系统可以自动切换到一个备用节点。这确保了数据的可用性和系统的稳定性。

  • 持久化选项:Redis支持不同的持久化选项,可以将内存中的数据持久化到磁盘上,以防止数据丢失。您可以选择在需要时将数据写入磁盘(RDB快照)或实时记录所有写操作(AOF日志)。这增加了数据的恢复能力和持久性。

  • 分布式缓存:Redis还可以作为分布式缓存系统使用。多个Redis节点可以组成一个集群,数据可以在节点间进行分片和复制,提供了更高的可伸缩性和容量。

2. 关系型与非关系型数据库有哪些区别?

1. 数据模型:

  • 关系型数据库使用表格(二维表)的形式来组织和存储数据,数据之间通过键和关系进行连接和表示。使用SQL语言进行数据的查询和操作,具有固定的结构和严格的数据模式。
  • 非关系型数据库:不使用传统的表格结构来组织数据,采用键值对、文档、列族或图形等方式来存储数据,数据模型更加灵活。非关系型数据库可以根据需要存储各种类型的数据,无需遵循固定的模式。

2. 可扩展性:

  • 关系型数据库通常采用垂直扩展(增加硬件资源)的方式来提高性能和容量,需要在单个节点上增加更多的计算和存储资源。
  • 非关系型数据库:多数非关系型数据库采用水平扩展(横向扩展)的方式,通过添加更多的节点来分布和处理数据,从而实现更高的可扩展性和负载均衡。

3. 数据一致性:

  • 关系型数据库关系型数据库强调ACID事务的一致性,确保数据的完整性和可靠性。在写入和更新操作时提供强一致性。
  • 非关系型数据库:非关系型数据库在一致性方面有不同的权衡。一些非关系型数据库提供强一致性,但通常会以性能损失为代价;而其他非关系型数据库(如分布式数据库)可能提供最终一致性或柔性一致性,允许数据在一段时间内存在不一致。

4. 应用场景:

  • 关系型数据库适用于需要严格数据模型和结构的应用场景,如金融系统、电子商务平台、管理系统等,对事务支持和数据一致性要求较高的应用。
  • 非关系型数据库:适用于大规模数据存储和处理、需要高吞吐量和低延迟的应用,如社交网络、实时分析、缓存、日志处理等,对数据模型灵活性和可扩展性要求较高的应用。

3. Redis中的缓存问题与解决方案:穿透、击穿、雪崩 

1. 缓存穿透(Cache Penetration)

  • 问题描述指恶意或非法的请求经过缓存层,直接访问数据库,导致数据库压力过大。
  • 解决方案使用布隆过滤器(Bloom Filter)等技术,对查询结果为空的请求进行过滤,避免对数据库的直接访问。另外,还可以将空结果缓存一段时间,避免频繁查询。

2. 缓存击穿(Cache Breakdown)

  • 问题描述指一个原本存在的key,在即将过期时被并发请求同时查询,导致多个请求同时访问数据库。
  • 解决方案使用互斥锁或分布式锁来保证只有一台服务器能够查询数据库,其他服务器在获取锁失败时等待查询结果。另外,在设置缓存时,可以给缓存设置一个随机的过期时间,避免缓存同时失效。

3. 缓存雪崩(Cache Avalanche)

  • 问题描述指在某个时间段内,大量的缓存同时失效,导致大量请求直接访问数据库,造成数据库负载过高。
  • 解决方案可以采用以下几种方式来应对缓存雪崩问题:
    1. 设置不同的过期时间:将缓存的过期时间分散开,避免同时失效。可以在原有的过期时间上增加一个随机值,使得每个缓存的失效时间不完全相同。
    2. 热点数据预加载:在缓存失效前,提前异步加载热点数据到缓存中,保证数据的可用性。
    3. 使用主从复制或者分片技术:通过部署多个缓存节点,将缓存的负载分散开,提高系统的可用性和容错性。
    4. 数据库限流:在缓存失效期间,对数据库查询进行限流,避免数据库压力过大。

4. 为什么要在一个项目中使用/管理16个数据库呢? 

  • 数据隔离:不同的数据库可以用来存储不同的业务数据,以实现数据的逻辑隔离。这样可以降低系统之间的耦合性,提高数据安全性和可维护性。

  • 数据性能:通过将数据分散存储在多个数据库中,可以提高系统的并发处理能力和响应速度。每个数据库可以专注于处理特定类型或特定区域的数据,减少数据库的负载压力。

  • 数据复制和备份:使用多个数据库可以方便进行数据的复制和备份。通过数据库间的数据同步和复制,可以实现数据的容灾和紧急恢复,提高系统的可用性和数据的安全性。

  • 数据管理和扩展:对于大规模的项目,使用多个数据库可以更好地进行数据管理和扩展。不同的数据库可以部署在不同的服务器上,实现水平扩展和负载均衡。这样可以提高系统的灵活性和可扩展性。

  • 数据安全:通过将敏感数据分别存储在不同的数据库中,可以实现数据的分级保护和访问控制。不同的数据库可以设置不同的权限和加密机制,提高数据的安全性。

5. 使用16个数据库比使用1个数据库的好处在哪里? 

  • 数据分区:使用多个数据库可以将数据进行更细粒度的分区。每个数据库负责存储特定范围或特定类型的数据,这样可以更有效地组织和查询数据。例如,可以按照地理位置、时间范围、用户类型等进行数据分区,提高数据的查询效率。

  • 并行处理:通过将数据分散存储在多个数据库中,可以实现更高程度的并行处理。不同的数据库可以同时处理不同的查询或事务,提升系统的并发性能和吞吐量。这对于需要处理大量数据或高并发场景非常有利。

  • 减少锁竞争:在单个数据库中,数据的读写操作可能会导致锁竞争,限制了并发性能。而使用多个数据库,可以将数据分散到不同的数据库中,减少锁竞争的可能性,进而提高系统的并发处理能力。

  • 模块化开发:将系统的不同模块或功能存储在不同的数据库中,可以实现更好的模块化开发和维护。不同的团队或开发人员可以独立操作和管理各自负责的数据库,减少代码的耦合性,提高团队的协作效率。

  • 水平扩展:使用多个数据库可以更容易地实现水平扩展。不同的数据库可以部署在不同的服务器上,通过添加更多的服务器节点来增加系统的处理能力。这样可以更灵活地满足增长需求,避免单点故障,并提供更好的可伸缩性和可用性。

  • 多租户支持:如果您的应用程序是一个多租户系统,每个租户都有自己的数据集,使用多个数据库可以更好地实现租户数据的隔离和管理。每个租户可以拥有自己的数据库,这样可以更好地控制数据访问和管理。

6. 怎么将应用集成到项目开发中使用?

6.1 配置application.yml文件

spring:
  datasource:
    type: com.zaxxer.hikari.HikariDataSource
    driver-class-name: 数据库驱动
    url: 数据库链接
    username: 数据库账号
    password: 数据库密码
    hikari:
      connection-timeout: 100000
      validation-timeout: 30000
      idle-timeout: 60000
      login-timeout: 5
      maximum-pool-size: 20
      max-lifetime: 60000
      minimum-idle: 5
      read-only: false
  redis:
    # Redis数据库索引(默认为0)
    database: 10
    # Redis服务器地址
    host: 127.0.0.1
    # Redis服务器连接端口
    port: 6379
    # 密码(默认为空)
    password: 1234
    # 连接超时时间 单位 ms(毫秒)
    timeout: 6000
    # 过期时间是30分钟30*60
    expire-time: 1800
    lettuce:
      pool:
        # 连接池最大连接数(使用负值表示没有限制) 默认 8,建议设置为CPU核数的两倍
        max-active: 6000
        # 连接池最大阻塞等待时间(使用负值表示没有限制) 默认 -1
        max-wait: -1
        # 连接池中的最大空闲连接 默认 8,建议设置为CPU核数的两倍
        max-idle: 100
        # 连接池中的最小空闲连接 默认 0
        min-idle: 50
        enabled: true

#--------------------------------Redis自定义一台服务配置操作多个库
redis:
  database:
    # 默认库
    database0: 0
    database1: 1
    database2: 2
    database3: 3
    database4: 4
    database5: 5
    database6: 6
    database7: 7
    database8: 8
    database9: 9
    database10: 10
    database11: 11
    database12: 12
    database13: 13
    database14: 14
    database15: 15

6.2 Redis缓存数据库核心配置文件

package com.jmh.demo03.config;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
 
import javax.annotation.Resource;
 
/**
 * @author 蒋明辉
 * @data 2022/10/1 17:08
 */
@Configuration
public class RedisConfig {
 
    @Bean
    public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){
        //实例化一个redis模板
        RedisTemplate<String,Object> redisTemplate=new RedisTemplate<>();
        //设置连接工厂
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        //针对string类型的key和value进行序列化
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        //针对has类型的key和value进行序列化
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
        //将上诉代码启用
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
 
    }
}
 

6.3 Redis一站式服务治理核心配置文件

package com.jmh.demo03.config;

import io.lettuce.core.resource.DefaultClientResources;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisPassword;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.util.ObjectUtils;
import java.time.Duration;
@Configuration
public class RedisConfigMultipleUnits {
    /**
     * 自定义redis配置获取
     */
    @Value("${redis.database.database0}")
    private int database0;
    @Value("${redis.database.database1}")
    private int database1;
    @Value("${redis.database.database2}")
    private int database2;
    @Value("${redis.database.database3}")
    private int database3;
    @Value("${redis.database.database4}")
    private int database4;
    @Value("${redis.database.database5}")
    private int database5;
    @Value("${redis.database.database6}")
    private int database6;
    @Value("${redis.database.database7}")
    private int database7;
    @Value("${redis.database.database8}")
    private int database8;
    @Value("${redis.database.database9}")
    private int database9;
    @Value("${redis.database.database10}")
    private int database10;
    @Value("${redis.database.database11}")
    private int database11;
    @Value("${redis.database.database12}")
    private int database12;
    @Value("${redis.database.database13}")
    private int database13;
    @Value("${redis.database.database14}")
    private int database14;
    @Value("${redis.database.database15}")
    private int database15;
    /**
     * spring继承redis配置获取
     */
    @Value("${spring.redis.host}")
    private String host;
    @Value("${spring.redis.port}")
    private int port;
    @Value("${spring.redis.password}")
    private String password;
    @Value("${spring.redis.lettuce.pool.max-active}")
    private int maxActive;
    @Value("${spring.redis.lettuce.pool.max-wait}")
    private int maxWait;
    @Value("${spring.redis.lettuce.pool.max-idle}")
    private int maxIdle;
    @Value("${spring.redis.lettuce.pool.min-idle}")
    private int minIdle;
    @Value("${spring.redis.timeout}")
    private long timeout;
    /**
     * 配置redis连接池
     */
    @Bean
    public GenericObjectPoolConfig poolConfig() {
        GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
        poolConfig.setMaxTotal(maxActive);
        poolConfig.setMaxIdle(maxIdle);
        poolConfig.setMinIdle(minIdle);
        poolConfig.setMaxWaitMillis(maxWait);
        return poolConfig;
    }
    /**
     * 配置默认客户端资源
     */
    @Bean("defaultClientResources")
    public  DefaultClientResources getDefaultClientResources(){
        return DefaultClientResources.create();
    }

    private StringRedisTemplate getStringRedisTemplate(int database, GenericObjectPoolConfig poolConfig, DefaultClientResources defaultClientResources) {
        StringRedisTemplate redisTemplate=new StringRedisTemplate();
        // 构建工厂对象
        RedisStandaloneConfiguration config = new RedisStandaloneConfiguration();
        config.setHostName(host);
        config.setPort(port);
        if (!ObjectUtils.isEmpty(password)) {
            RedisPassword redisPassword = RedisPassword.of(password);
            config.setPassword(redisPassword);
        }
        LettucePoolingClientConfiguration clientConfig = LettucePoolingClientConfiguration.builder()
                .commandTimeout(Duration.ofSeconds(timeout))
                .poolConfig(poolConfig)
                .clientResources(defaultClientResources)
                .build();
        LettuceConnectionFactory factory = new LettuceConnectionFactory(config, clientConfig);
        // 设置使用的redis数据库
        factory.setDatabase(database);
        // 重新初始化工厂
        factory.afterPropertiesSet();
        //设置连接工厂
        redisTemplate.setConnectionFactory(factory);
        //针对string类型的key和value进行序列化
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        //针对has类型的key和value进行序列化
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
        //将上诉代码启用
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }

    @Bean(name="redisTemplateDataBase0")
    public StringRedisTemplate redisTemplateDataBase0(GenericObjectPoolConfig poolConfig,
                                                    @Qualifier("defaultClientResources") DefaultClientResources defaultClientResources) {
        return getStringRedisTemplate(database0, poolConfig,defaultClientResources);
    }

    @Bean(name="redisTemplateDataBase1")
    public StringRedisTemplate redisTemplateDataBase1(GenericObjectPoolConfig poolConfig,
                                                 @Qualifier("defaultClientResources") DefaultClientResources defaultClientResources) {
        return getStringRedisTemplate(database1, poolConfig,defaultClientResources);
    }

    @Bean(name="redisTemplateDataBase2")
    public StringRedisTemplate redisTemplateDataBase2(GenericObjectPoolConfig poolConfig,
                                                      @Qualifier("defaultClientResources") DefaultClientResources defaultClientResources) {
        return getStringRedisTemplate(database2, poolConfig,defaultClientResources);
    }

    @Bean(name="redisTemplateDataBase3")
    public StringRedisTemplate redisTemplateDataBase3(GenericObjectPoolConfig poolConfig,
                                                    @Qualifier("defaultClientResources") DefaultClientResources defaultClientResources) {
        return getStringRedisTemplate(database3, poolConfig,defaultClientResources);
    }

    @Bean(name="redisTemplateDataBase4")
    public StringRedisTemplate redisTemplateDataBase4(GenericObjectPoolConfig poolConfig,
                                                    @Qualifier("defaultClientResources") DefaultClientResources defaultClientResources) {
        return getStringRedisTemplate(database4, poolConfig,defaultClientResources);
    }

    @Bean(name="redisTemplateDataBase5")
    public StringRedisTemplate redisTemplateDataBase5(GenericObjectPoolConfig poolConfig,
                                                    @Qualifier("defaultClientResources") DefaultClientResources defaultClientResources) {
        return getStringRedisTemplate(database5, poolConfig,defaultClientResources);
    }

    @Bean(name="redisTemplateDataBase6")
    public StringRedisTemplate redisTemplateDataBase6(GenericObjectPoolConfig poolConfig,
                                                    @Qualifier("defaultClientResources") DefaultClientResources defaultClientResources) {
        return getStringRedisTemplate(database6, poolConfig,defaultClientResources);
    }

    @Bean(name="redisTemplateDataBase7")
    public StringRedisTemplate redisTemplateDataBase7(GenericObjectPoolConfig poolConfig,
                                                    @Qualifier("defaultClientResources") DefaultClientResources defaultClientResources) {
        return getStringRedisTemplate(database7, poolConfig,defaultClientResources);
    }

    @Bean(name="redisTemplateDataBase8")
    public StringRedisTemplate redisTemplateDataBase8(GenericObjectPoolConfig poolConfig,
                                                    @Qualifier("defaultClientResources") DefaultClientResources defaultClientResources) {
        return getStringRedisTemplate(database8, poolConfig,defaultClientResources);
    }

    @Bean(name="redisTemplateDataBase9")
    public StringRedisTemplate redisTemplateDataBase9(GenericObjectPoolConfig poolConfig,
                                                    @Qualifier("defaultClientResources") DefaultClientResources defaultClientResources) {
        return getStringRedisTemplate(database9, poolConfig,defaultClientResources);
    }

    @Bean(name="redisTemplateDataBase10")
    public StringRedisTemplate redisTemplateDataBase10(GenericObjectPoolConfig poolConfig,
                                                    @Qualifier("defaultClientResources") DefaultClientResources defaultClientResources) {
        return getStringRedisTemplate(database10, poolConfig,defaultClientResources);
    }

    @Bean(name="redisTemplateDataBase11")
    public StringRedisTemplate redisTemplateDataBase11(GenericObjectPoolConfig poolConfig,
                                                    @Qualifier("defaultClientResources") DefaultClientResources defaultClientResources) {
        return getStringRedisTemplate(database11, poolConfig,defaultClientResources);
    }

    @Bean(name="redisTemplateDataBase12")
    public StringRedisTemplate redisTemplateDataBase12(GenericObjectPoolConfig poolConfig,
                                                    @Qualifier("defaultClientResources") DefaultClientResources defaultClientResources) {
        return getStringRedisTemplate(database12, poolConfig,defaultClientResources);
    }

    @Bean(name="redisTemplateDataBase13")
    public StringRedisTemplate redisTemplateDataBase13(GenericObjectPoolConfig poolConfig,
                                                    @Qualifier("defaultClientResources") DefaultClientResources defaultClientResources) {
        return getStringRedisTemplate(database13, poolConfig,defaultClientResources);
    }

    @Bean(name="redisTemplateDataBase14")
    public StringRedisTemplate redisTemplateDataBase14(GenericObjectPoolConfig poolConfig,
                                                    @Qualifier("defaultClientResources") DefaultClientResources defaultClientResources) {
        return getStringRedisTemplate(database14, poolConfig,defaultClientResources);
    }

    @Bean(name="redisTemplateDataBase15")
    public StringRedisTemplate redisTemplateDataBase15(GenericObjectPoolConfig poolConfig,
                                                    @Qualifier("defaultClientResources") DefaultClientResources defaultClientResources) {
        return getStringRedisTemplate(database15, poolConfig,defaultClientResources);
    }
}

6.4 测试

package com.jmh.demo03;

import com.alibaba.fastjson2.JSONObject;
import com.jmh.demo03.utils.HttpClientUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.entity.ContentType;
import org.ehcache.xml.model.TimeUnit;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author 蒋明辉
 * @data 2023/5/27 0:24
 */
@SpringBootTest
@Slf4j
public class demo13 {

    @Resource(name = "redisTemplateDataBase0")
    private StringRedisTemplate stringRedisTemplate0;
    @Resource(name = "redisTemplateDataBase1")
    private StringRedisTemplate stringRedisTemplate1;
    @Resource(name = "redisTemplateDataBase2")
    private StringRedisTemplate stringRedisTemplate2;
    @Resource(name = "redisTemplateDataBase3")
    private StringRedisTemplate stringRedisTemplate3;
    @Resource(name = "redisTemplateDataBase4")
    private StringRedisTemplate stringRedisTemplate4;
    @Resource(name = "redisTemplateDataBase5")
    private StringRedisTemplate stringRedisTemplate5;
    @Resource(name = "redisTemplateDataBase6")
    private StringRedisTemplate stringRedisTemplate6;
    @Resource(name = "redisTemplateDataBase7")
    private StringRedisTemplate stringRedisTemplate7;
    @Resource(name = "redisTemplateDataBase8")
    private StringRedisTemplate stringRedisTemplate8;
    @Resource(name = "redisTemplateDataBase9")
    private StringRedisTemplate stringRedisTemplate9;
    @Resource(name = "redisTemplateDataBase10")
    private StringRedisTemplate stringRedisTemplate10;
    @Resource(name = "redisTemplateDataBase11")
    private StringRedisTemplate stringRedisTemplate11;
    @Resource(name = "redisTemplateDataBase12")
    private StringRedisTemplate stringRedisTemplate12;
    @Resource(name = "redisTemplateDataBase13")
    private StringRedisTemplate stringRedisTemplate13;
    @Resource(name = "redisTemplateDataBase14")
    private StringRedisTemplate stringRedisTemplate14;
    @Resource(name = "redisTemplateDataBase15")
    private StringRedisTemplate stringRedisTemplate15;
    @Test
    public void demo04(){
        stringRedisTemplate0.opsForValue().set("0","我是第1个数据库【redis】");
        stringRedisTemplate1.opsForValue().set("1","我是第2个数据库【redis】");
        stringRedisTemplate2.opsForValue().set("2","我是第3个数据库【redis】");
        stringRedisTemplate3.opsForValue().set("3","我是第4个数据库【redis】");
        stringRedisTemplate4.opsForValue().set("4","我是第5个数据库【redis】");
        stringRedisTemplate5.opsForValue().set("5","我是第6个数据库【redis】");
        stringRedisTemplate6.opsForValue().set("6","我是第7个数据库【redis】");
        stringRedisTemplate7.opsForValue().set("7","我是第8个数据库【redis】");
        stringRedisTemplate8.opsForValue().set("8","我是第9个数据库【redis】");
        stringRedisTemplate9.opsForValue().set("9","我是第10个数据库【redis】");
        stringRedisTemplate10.opsForValue().set("10","我是第11个数据库【redis】");
        stringRedisTemplate11.opsForValue().set("11","我是第12个数据库【redis】");
        stringRedisTemplate12.opsForValue().set("12","我是第13个数据库【redis】");
        stringRedisTemplate13.opsForValue().set("13","我是第14个数据库【redis】");
        stringRedisTemplate14.opsForValue().set("14","我是第15个数据库【redis】");
        stringRedisTemplate15.opsForValue().set("15","我是第16个数据库【redis】");

    }

}
  • 测试结果如图

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/696443.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

OpenStack(T版)——网络(Neutron)服务介绍与安装

文章目录 OpenStack(T版)——网络(Neutron)服务介绍与安装安装和配置(controller)准备(1)创建数据库(2)加载admin user的环境变量(3)创建服务凭证 配置Neutron网络服务组件(1)安装软件(2)编辑文件/etc/neutron/neutron.conf&#xff0c;完成以下操作(3)配置Layer 2 (ML2)plug-i…

时序数据库 TDengine 与腾讯云多个产品线完成兼容性互认证明

随着数字经济蓬勃发展&#xff0c;数据成为驱动企业数字化转型的关键生产要素&#xff0c;如何加强对数据资源的治理利用、实现数据洞察、激活数据价值正成为亟待解决的问题。在此背景下&#xff0c;数据库与操作系统、云平台等国产化软件相互结合赋能成为解决问题的思路之一。…

Java中的String类真的不可变吗?java面试常见问题

其实在Java中&#xff0c;String类被final修饰&#xff0c;主要是为了保证字符串的不可变性&#xff0c;进而保证了它的安全性。那么final到底是怎么保证字符串安全性的呢&#xff1f;接下来就让我们一起来看看吧。 一. final的作用 1. final关键词修饰的类不可以被其他类继承…

车载通讯USB开发,增强车内娱乐体验

车载通讯开发中使用的 USB 协议常见于车内娱乐系统、车载设备和汽车诊断工具等应用。USB&#xff08;Universal Serial Bus&#xff0c;通用串行总线&#xff09;是一种常见的数字通信接口标准&#xff0c;用于连接计算机、外部设备及其他电子设备之间的数据传输和通信。 USB …

Python面向对象编程到底怎么用才是最好的(两个小案例告诉你其中优势)

目录 前言案例一&#xff1a;图书管理系统案例二&#xff1a;汽车制造系统 总结 前言 大家好&#xff0c;我是辣条哥~ 当谈到Python编程语言时&#xff0c;面向对象编程&#xff08;Object-Oriented Programming&#xff0c;简称OOP&#xff09;是一个重要的概念。 OOP是一种…

Leetcode52 N 皇后 II

n 皇后问题 研究的是如何将 n 个皇后放置在 n n 的棋盘上&#xff0c;并且使皇后彼此之间不能相互攻击。 给你一个整数 n &#xff0c;返回 n 皇后问题 不同的解决方案的数量。 示例 1&#xff1a; 输入&#xff1a;n 4 输出&#xff1a;2 解释&#xff1a;如上图所示&…

uin-app项目实现pdf文件预览以及下载

由于项目需要&#xff0c;需要对于pdf格式的文件进行预览由用户进行选择性下载&#xff0c;查阅相关文档后方知针对于这种 pdf.js有奇效 一、下载 官网地址https://mozilla.github.io/pdf.js/getting_started/#download 文档下载解压成功后&#xff0c;按照这种格式放入uin-…

认识GBK编码和UTF-8编码

GBK编码和UTF-8编码是两种不同的字符编码方式&#xff1b; 1、主要区别如下&#xff1a; &#xff08;1&#xff09;字符集范围不同&#xff1a;GBK编码支持中文字符和日韩字符&#xff0c;而UTF-8编码支持全球范围内的字符&#xff1b; &#xff08;2&#xff09;编码方式不…

4.28 poll API介绍及代码编写

4.28 poll API介绍及代码编写 #include <poll.h> struct pollfd{int fd;//委托内核检测的文件描述符short events;//委托内核检测文件描述符的什么事件short revents;//文件描述符实际发生的事件 }; int poll(struct pollfd *fds,nfds_t nfds,int timeout);-参数&#x…

EDA云实证Vol.13:暴力堆机器之王——Calibre

Siemens的Calibre是业内权威的版图验证软件&#xff0c;被各大Foundry厂广泛认可。用户可以直接在Virtuoso界面集成Calibre接口&#xff0c;调用版图验证结果数据&#xff0c;使用起来极为方便。 今天&#xff0c;我们就来聊聊这款软件。 版图验证是芯片设计中非常重要的一环…

3.5.1MapReduce原理详解

单机程序计算流程 输入数据—>读取数据—>处理数据—>写入数据—>输出数据 Hadoop计算流程 input data&#xff1a;输入数据 InputFormat&#xff1a;对数据进行切分&#xff0c;格式化处理 map&#xff1a;将前面切分的数据做map处理(将数据进行分类&#xf…

怎么写一份好的接口文档?

目录 前言&#xff1a; 接口文档结构 参数说明 示例 错误码说明 语言基调通俗易懂 及时更新与维护 总结 前言&#xff1a; 写一份好的接口文档有助于开发者理解和使用你的API。&#xff0c; 编写一份优秀的接口文档会让软件开发中变得更加轻松&#xff0c;更有效率。…

一个大于6的偶数,能被两个质数相加得到

一个大于6的偶数,能被两个质数相加得到 1.描述 证明&#xff1a;一个大于6的偶数,能被两个质数相加得到 2.代码 先判断输入的数据是不是大于6的偶数 编写判断某个数是不是质数的方法 从中间两侧把数相加看看能不能得到对应的偶数两个奇数相加能够得到的值 public class Main…

linux入门之进程概念上(冯诺依曼系统,系统概念与定位,PCB,fork初识)

文章目录 目录 一、认识冯诺依曼系统 二、操作系统 1.概念 2.设计os的目的 3.定位 4.如何理解管理 三、系统调用和库函数 四、进程 1.基本概念 2.描述进程-PCB 3.组织进程 4.查看进程 5.通过系统调用获取进程标识符 6.通过系统调用创建进程-fork初识 6.1fork原理…

Spring(9) IOC容器中的单例Bean的线程安全问题

目录 1.知识点回顾2.线程安全3.总结 1.知识点回顾 在 Spring 中我们可以通过 Scope 注解来指定 Bean 的创建方式。 Servcie Scope("singleton") public class UserServiceImpl implements UserService {}Scope 注解的值有两种&#xff1a; singleton&#xff1a;B…

vue3使用高德地图实现点击获取经纬度

话不多说直接上干活 在此之前你需要有高德地图的 key&#xff0c;这个自己去申请即可 1&#xff0c;首先需要在终端安装 npm i amap/amap-jsapi-loader --save 2&#xff0c;准备一个容器 <template><div id"container"></div> </templat…

Redis+Lua脚本解决高并发情况下库存超卖的问题

文章目录 一、实现思路二、实现代码 一、实现思路 二、实现代码 order.lua脚本代码&#xff1a; -- 参数列表 local productIdStr ARGV[1] local productNameStr ARGV[2] local cartQuantityStr ARGV[3] local orderId ARGV[4] local userId ARGV[5] local orderDate A…

Android 控件颜色与实际不符「解决方案」

问题复现 背景色设置为 绿色&#xff0c;然而 Button 控件却显示 紫色 解决方案 这是由于 Theme 修改导致&#xff0c;只需要修改配置文件 themes.xml 中 parent 属性 即可 如果找不到该文件&#xff0c;先将工程结构展示改为 Project 即可 原配置&#xff1a; <style nam…

【网络智能化】网络杂谈(9)之如何做到网络管理智能化

涉及知识点 什么是网络管理智能化&#xff0c;基于专家系统的网络管理&#xff0c;基于智能 Agent 的网络管理&#xff0c;基于计算智能的宽带网络管理&#xff0c;深入了解网络管理智能化技术。 原创于&#xff1a;CSDN博主-《拄杖盲学轻声码》&#xff0c;更多内容可去其主页…

软件业务连续性管理的意义是什么?

软件业务连续性管理是指在软件开发和运营过程中&#xff0c;确保业务能够持续进行的管理方法和实践&#xff0c;它是一种综合性的管理方法&#xff0c;旨在确保在软件系统出现故障、灾难或其他不可预测的情况时&#xff0c;能够快速、有效地恢复业务&#xff0c;以最大程度地减…