Redis数据结构存储系统:第二章:如何使用

Redis数据结构详解及不同场景应用指南 Redis是一个开源的、基于内存的键值存储系统,支持持久化到磁盘。它以其高性能、丰富的数据结构和灵活的扩展性而闻名。Redis的常见用途包括缓存、会话存储、消息队列、实时分析等。Redis的丰富数据结构使其成为解决多种问题的强大工具。通过合理选择数据结构,可以显著提高应用的性能和可扩展性。字符串:缓存、计数器。哈希:存储对象数据。列表:消息队列、最新消息列表。集合:标签系统、去重数据存储。有序集合:排行榜、优先级队列。 阅读详情

Redis与SpringBoot整合:

第一步:在项目中引入

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

第二步:将连接池和配置类创建好

RedisUtil:

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

public class RedisUtil {

    private JedisPool jedisPool;

    public void initPool(String host,int port ,int database){
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        poolConfig.setMaxTotal(200);
        poolConfig.setMaxIdle(30);
        poolConfig.setBlockWhenExhausted(true);
        poolConfig.setMaxWaitMillis(10*1000);
        poolConfig.setTestOnBorrow(true);
        jedisPool=new JedisPool(poolConfig,host,port,20*1000);
    }

    public Jedis getJedis(){
        Jedis jedis = jedisPool.getResource();
        return jedis;
    }

}

RedisConfig:

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration//Spring容器中的注解
public class RedisConfig {

    //读取配置文件中的redis的ip地址,@Value注入赋值
    @Value("${spring.redis.host:disabled}")
    private String host;

    @Value("${spring.redis.port:0}")
    private int port;

    @Value("${spring.redis.database:0}")
    private int database;

    @Bean//将返回值给Spring,Spring容器中就有了RedisUtil(连接池)
    public RedisUtil getRedisUtil(){
        if(host.equals("disabled")){
            return null;
        }
        RedisUtil redisUtil=new RedisUtil();
        redisUtil.initPool(host,port,database);
        return redisUtil;
    }

}

在哪个项目中使用Redis就在application.properties中配置以下:

 

客户端登录:

cd /usr/local/redis/bin

./redis-cli -h 192.168.0.100 -p 6379

192.168.0.100:6379> ping
PONG

测试一下:

@RunWith(SpringRunner.class)
@SpringBootTest
public class GmallManageServiceApplicationTests {

	@Autowired
	RedisUtil redisUtil;

	@Test
	public void contextLoads() {

		Jedis jedis = redisUtil.getJedis();

		String ping = jedis.ping();

		System.out.println(ping);
	}

}

使用redis进行业务开发

开始开发先说明redis key的命名规范,由于Redis不像数据库表那样有结构,其所有的数据全靠key进行索引,所以redis数据的可读性,全依靠key。

企业中最常用的方式就是:object:id:field

                比如:sku:1314:info

                           user:1092:password

拿一个之前的例子:

public SkuInfo getSkuInfo(String skuId){

        Jedis jedis = redisUtil.getJedis();
        String skuKey= RedisConst.sku_prefix+skuId+RedisConst.skuInfo_suffix;
        String skuInfoJson = jedis.get(skuKey);
        if(skuInfoJson!=null ){
            System.err.println( Thread.currentThread().getName()+":命中缓存"  );
            SkuInfo skuInfo = JSON.parseObject(skuInfoJson, SkuInfo.class);
            jedis.close();
            return skuInfo;
        }else{
               System.err.println( Thread.currentThread().getName()+":未命中缓存"  );

                System.err.println( Thread.currentThread().getName()+": 查询数据##################### ##" );
                SkuInfo skuInfoDB = getSkuInfoDB(skuId);
                String skuInfoJsonStr = JSON.toJSONString(skuInfoDB);
                jedis.setex(skuKey,RedisConst.skuinfo_exp_sec,skuInfoJsonStr);
                System.err.println( Thread.currentThread().getName()+":数据库更新完毕############### #####" );
                jedis.close();
                return skuInfoDB;
        }
}

以上基本实现使用缓存的方案。

高并发时可能会出现的问题:

但在高并发环境下还有如下三个问题。

  1. 如果redis宕机了,或者链接不上,怎么办?
  2. 如果redis缓存在高峰期到期失效,在这个时刻请求会向雪崩一样,直接访问数据库如何处理?
  3.  如果用户不停地查询一条不存在的数据,缓存没有,数据库也没有,那么会出现什么情况,如何处理?
 public SkuInfo getSkuInfo(String skuId){
    SkuInfo skuInfo = null;
    try {
        Jedis jedis = redisUtil.getJedis();
        String skuInfoKey = ManageConst.SKUKEY_PREFIX + skuId + ManageConst.SKUKEY_SUFFIX;
        String skuInfoJson = jedis.get(skuInfoKey);

        if (skuInfoJson == null || skuInfoJson.length() == 0) {
            System.err.println(Thread.currentThread().getName()+"缓存未命中!");
            String skuLockKey = ManageConst.SKUKEY_PREFIX + skuId + ManageConst.SKULOCK_SUFFIX;
            String lock = jedis.set(skuLockKey, "OK", "NX", "PX", ManageConst.SKULOCK_EXPIRE_PX);

            if ("OK".equals(lock) ){
                System.err.println(Thread.currentThread().getName()+"获得分布式锁!");
                skuInfo = getSkuInfoFromDB(skuId);
                if(skuInfo==null){
                    jedis.setex(skuInfoKey, ManageConst.SKUKEY_TIMEOUT, "empty");
                    return null;
                }


                String skuInfoJsonNew = JSON.toJSONString(skuInfo);
                jedis.setex(skuInfoKey, ManageConst.SKUKEY_TIMEOUT, skuInfoJsonNew);
                jedis.close();
                return skuInfo;
            }else{
                System.err.println(Thread.currentThread().getName()+"未获得分布式锁,开始自旋!");
                Thread.sleep(1000);
                jedis.close();
                return   getSkuInfo(  skuId);
            }

        } else if(skuInfoJson.equals("empty")){
            return null;
        } else {
            System.err.println(Thread.currentThread().getName()+"缓存已命中!!!!!!!!!!!!!!!!!!!");
            skuInfo = JSON.parseObject(skuInfoJson, SkuInfo.class);
            jedis.close();
            return skuInfo;
        }

    }catch (JedisConnectionException e){
        e.printStackTrace();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

    return getSkuInfoFromDB(skuId);
}

最近写的也一样:

controller:

    @RequestMapping("{skuId}.html")
    public String item(@PathVariable("skuId") String skuId, ModelMap map, HttpServletRequest request){
        SkuInfo skuInfo = skuService.item(skuId,request.getRemoteAddr());
    }

service接口我就不写了

Serviceimpl:

@Override
    public SkuInfo item(String skuId,String ip) {
        System.out.println(ip+"访问"+skuId+"商品");
        SkuInfo skuInfo = null;
        //从redis获取redis的客户端jedis
        Jedis jedis = redisUtil.getJedis();
        // 从缓存中取出skuId的数据
        String skuInfoStr = jedis.get("sku:"+skuId+":info");
        //Json格式转成实体类类型
        skuInfo = JSON.parseObject(skuInfoStr, SkuInfo.class);
        //从db中取出sku的数据
        //缓存中没有
        if(skuInfo == null){
            System.out.println(ip+"发现缓存中没有"+skuId+"商品数据,申请分布式锁");
            // 拿到分布式锁
            String OK = jedis.set("sku:" + skuId + ":lock", "1", "nx", "px", 10000);
            if(StringUtils.isBlank(OK)){
                System.out.println(ip+"分布式锁申请失败,三秒后开始自旋");
                // 缓存锁被占用,等一会儿继续申请
                try {
                    Thread.sleep(3000);//让它等3秒
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                return item(skuId,ip);//自旋,这里没有启动新线程,item(skuId,ip);才会启动新线程
            }else{
                System.out.println(ip+"分布式锁申请成功,访问数据库");
                // 拿到缓存锁,可以访问数据库
                skuInfo = getSkuInfo(skuId);
            }
            System.out.println(ip+"成功访问数据库后,归还锁,将"+skuId+"商品放入缓存");
            jedis.del("sku:"+skuId+":lock");
        }
        //关闭redis客户端
        jedis.close();
        return skuInfo;
    }

getSkuInfo方法:

    public SkuInfo getSkuInfo(String skuId) {
        SkuInfo skuInfo = new SkuInfo();
        skuInfo.setId(skuId);
        SkuInfo skuInfos = skuInfoMapper.selectOne(skuInfo);

        SkuImage skuImage = new SkuImage();
        skuImage.setSkuId(skuId);
        List<SkuImage> skuImages = skuImageMapper.select(skuImage);

        skuInfos.setSkuImageList(skuImages);

        return skuInfos;
    }

如果对于

String skuInfoStr = jedis.get("sku:"+skuId+":info");

String OK = jedis.set("sku:" + skuId + ":lock", "1", "nx", "px", 10000);

jedis.del("sku:"+skuId+":lock");

不太理解,大家可以看看前一章节的博客,或者去官网查看

我这里截下来一部分

 

 

 

 

 

 

 

 

 

 

 

 

 

 

使用 StackExchange.Redis 在 C# 中开始使用 Redis Redis(Remote Dictionary Server)是一个开源的、内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。Redis 支持多种类型的数据结构,如字符串(strings)、哈希表(hashes)、列表(lists)、集合(sets)、有序集合(sorted sets)与位图(bitmaps)、超日志(hyperloglogs)和地理空间(geospatial)索引半径查询等。 阅读详情

相关推荐

云计算虚拟化实验(一)——虚拟机软件VMware的安装以及虚拟机系统的安装(Windows7+CentOS7)

主要内容: 1、虚拟机软件的安装(以VMware为例) 2、虚拟机系统的安装(Window7 + CentOS7) 3、虚拟主机网络互访 4、不同局域网内的虚拟主机互访(软路由——海蜘蛛) 0 ——首先介绍一下什么是虚拟化? 虚拟化,是指通过虚拟化技术将一台计算机虚拟为多台逻辑计算机。在一台计算机上同时运行多个逻辑计算机,每个逻辑计算机可运行不同的操作系统,并且应用程序都可以在

gg_asd的博客 1万+

Redis通用组件封装

Redis

liu_ares的博客 813

STM32学习笔记(江协科技)-----OLED显示屏

SSD1306简介:•SSD1306是一款OLED/PLED点阵显示屏的控制器,可以嵌入在屏幕中,用于执行接收数据、显示存储、扫描刷新等任务••驱动接口:128个SEG引脚和64个COM引脚,对应128*64像素点阵显示屏••内置显示存储器(GDDRAM):128*64 bit128*8 ByteSRAM••供电:IC逻辑),VCC=7~15V(面板驱动)••通信接口:8位6800/8080并行接口,3/4线SPI。

lu322f的博客 1064

第六章 商品详情进阶 + redis分布式锁 + redis问题解决 + redisson + 布隆过滤器

1、商品详情的优化--->redis 2、redis的缓存问题 3.布隆过滤器 4、redisson对象 5.redis做分布式锁

weixin_67093769的博客 1483

SAM3模型国内快速上手:Modelscope权重下载+环境配置一条龙指南

本文详细介绍了SAM3模型在国内的快速部署方案,包括通过Modelscope平台下载权重文件、优化CUDA 11.8环境配置以及实战避坑技巧。针对国内开发者常见的网络问题和环境兼容性问题,提供了从权重下载到模型加载的全流程指南,帮助用户高效完成部署并快速上手SAM3模型。

weixin_28465009的博客 1156

一文详解脉搏血氧测量原理与方法

本文摘要:血氧饱和度(SpO2)是评估人体氧合功能的重要指标,反映血红蛋白携氧能力。其测量基于光电容积描记法(PPG),利用红光(660nm)和红外光(940nm)通过组织时的吸收差异计算。脉搏波特征与心血管状态相关,动脉硬化会影响波形特征。Masimo公司的信号提取技术(SET)通过并行算法有效解决了传统血氧仪在运动、弱灌注情况下的测量误差问题,显著提升了临床监测的准确性和可靠性。该技术已成为血氧监测的金标准,在降低误报率、缩短响应时间方面具有显著优势。

m0_50146396的博客 2018

Redis缓存优化、本地锁及分布式锁的入门使用思想实现

redis的key是不能进行重复的,否则数据会覆盖,同时也不会通过硬编码的形式写死在储存的key位置上,这样不便于后面的维护,一般都是通过定义枚举、接口、静态类进行统一的描述key的使用,这样在后面需要进行key重新定义的时候就可以一处修改处处生效/**单位:秒 尝试获取锁的最大等待时间*/ public static final long SKULOCK_EXPIRE_PX1 = 1;

我要记录学习博客 1296

麒麟V10 ARM环境离线部署MySQL:从依赖缺失到服务自启的完整避坑指南

本文详细介绍了在麒麟V10 ARM环境下离线部署MySQL的完整流程,包括依赖缺失解决方案、目录配置、服务自启设置及性能调优。特别针对国产操作系统和ARM架构的兼容性问题,提供了实用的避坑指南和优化建议,帮助用户高效完成MySQL部署与维护。

weixin_28741413的博客 409

redis使用

redis使用步骤 在common模块下的service-util中添加redis依赖 复制工具类 在需要使用到redis的模块加入配置文件 service-item 、service-product redis中设计数据结构 key Redis设计的好不好,完全看key, key模板:Object:userId:field 举个例子: Key = User:2:password Value = 123456(需md5加密) Key为User:2:password,表示为user表中id为2的密码。

weixin_45920582的博客 230

RDKit | 基于Pytorch和RDKit建立QSAR模型

QSAR 定量构效方法(quantitative structure-activity relationship, QSAR)是应用最为广泛的药物设计方法。所谓定量构效方法就是通过一些数理统计方法建立其一系列化合物的生理活性或某种性质与其物理化学性质之间的定量关系,通过这些定量关系。可以预测化合物的生理活性或某些性质,指导我们设计出具有更高活性的化合物。 早在...

DrugOne 5079

YOLO-V8训练自己的数据集之标注样本

四、标注样本 4.1、标注样本概述 4.1.1、样本标注主要方法 4.1.2、标注样本概念 4.1.3、标注样本实现方式 4.1.4、常见标注样本软件 4.2、标注工具LabelImg 4.2.1、LabelImg介绍 4.2.2、LabelImg特点 4.2.3、LabelImg安装方法 4.2.4、LabelImg使用方法 4.3、标注样本实操 4.3.1、安装标注软件Labelimg 4.3.2、Labelimg界面介绍 4.3.3、LabelImg实操过程中常

qq_29633789的博客 666

2020-09-23

Redis 高并发问题,及解决方案! (一)redis技术的使用: redis真的是一个很好的技术,它可以很好的在一定程度上解决网站一瞬间的并发量,例如商品抢购秒杀等活动。。。 redis之所以能解决高并发的原因是它可以直接访问内存,而以往我们用的是数据库(硬盘),提高了访问效率,解决了数据库服务器压力。 为什么redis的地位越来越高,我们为何不选择memcache,这是因为memcache只能存储字符串,而redis存储类型很丰富(例如有字符串、LIST、SET等),memcache每个值最大只能存储1

weixin_41045487的博客 380

SAPFiori Elements Analytical List Page 概述

ALP(Analytical List Page)是SAP Fiori提供的一种复合页面类型,结合了分析(图表/KPI)与事务(表格/操作)功能,适用于需要分析后立即执行处理的业务场景(如采购价格监控、销售逾期处理等)。其核心价值在于让用户在同一页面完成从数据洞察到事务处理的闭环,减少应用切换带来的效率损耗。 页面结构包含页头KPI标签、交互式图表和明细表格,通过联动过滤、选择同步等机制实现数据钻取与即时操作。支持标准过滤和可视化过滤,并依赖OData注解(SelectionVariant/Presenta

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 272

Redis数据结构存储系统:第二章:如何使用,BAT等大厂必问技术面试题

public class RedisUtil { private JedisPool jedisPool; public void initPool(String host,int port ,int database) 《一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》 【docs.qq.com/doc/DSmxTbFJ1cmN1R2dB】 完整内容开源分享 { JedisPoolConfig poolConfig = new JedisPoolConfig(); p

m0_64867688的博客 1648

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

Redis 开源的、基于键值对的内存数据结构存储系统

Redis 是一个开源的、基于键值对的内存数据结构存储系统,它可以用作数据库、缓存和消息中间件。Redis 支持多种类型的数据结构,如字符串(strings)、哈希(hashes)、列表(lists)、集合(sets)、有序集合(sorted sets)以及位图(bitmaps)、地理空间索引(geospatial indexes)等。应用场景:Redis 作为一种高性能的键值存储系统,由于其丰富的数据结构、高速的数据访问能力以及灵活的功能特性,被广泛应用于各种不同的场景中。

shaozheng0503的博客 1204

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

Redis:高性能的键值存储系统

Redis是一个高性能的键值存储系统,支持多种数据结构如字符串、哈希、列表、集合和有序集合。它广泛应用于缓存、会话存储、消息队列、实时分析和排行榜等场景。Redis的主要优势在于其基于内存的存储方式,提供了极高的读写性能,并支持数据持久化。本文介绍了Redis的基本概念、主要用途以及常用命令,帮助开发者更好地理解和使用Redis。

2401_84892260的博客 1397

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

Redis的数据结构及使用场景

Redis是一种基于内存的高性能键值存储系统,它支持多种数据结构,每种数据结构都有其特定的用途和优势。

夏壹分享 1292

【Redis】Resdis介绍及5种常用数据结构

Redis(Remote Dictionary Server)是一种开源的键值存储系统,它支持多种数据结构如字符串(strings)、哈希(hashes)、列表(lists)、集合(sets)以及有序集合(sorted sets)。Redis 的主要特点是其内存中的数据存储方式,这使得 Redis 能够实现非常高的读写速度。此外,Redis 还支持数据持久化,可以将内存中的数据异步写入硬盘中

chenzhong373095238的博客 2163

Redis中的数据结构详解与示例

Redis 是一个开源的内存数据结构存储系统,它可以作为数据库、缓存和消息代理。它支持多种类型的数据结构,包括字符串(String)、哈希(Hash)、列表(List)、集合(Set)、有序集合(ZSet)等。本文将详细介绍 Redis 中这些主要的数据结构,并通过示例展示其用法。字符串是 Redis 中自定义的数据结构。由于Redis是由C语言编写的,所以想要支持String类型的数据结构,必须要重新定义String这个数据结构。

萌萌白白的博客 1524

Redis核心数据结构与分布式锁实现详解

Redis核心数据结构与分布式锁实现摘要 本文详细介绍了Redis的常用数据结构(字符串、哈希、列表、集合、有序集合)及其应用场景,并提供了Python操作示例。重点讲解了基于Redis的分布式锁实现方案,包括基本SETNX命令、SET扩展命令以及Redlock算法三种实现方式。分布式锁需要满足互斥性、避免死锁、容错性和自旋等待等要求。文章通过代码示例展示了如何获取和释放锁,并分析了不同方案的优缺点。Redis因其丰富的数据结构和原子性操作,成为实现分布式系统协调的理想选择。

私聊前往站内信:https://i.youkuaiyun.com/#/msg/chat/weixin_44976692 2225

Redis的数据结构和使用场景

Redis是一个开源的Key-Value内存数据库,支持多种数据结构(字符串、列表、哈希、集合、有序集合),适用于高并发场景。它采用内存存储保证高性能,同时支持持久化和主从同步。Redis的有序集合(ZSet)底层采用ziplist(小数据量)或skiplist+dict(大数据量)实现,能高效支持范围查询和排序操作。相比关系型数据库,Redis能更好应对秒杀、排行榜等高并发场景,通过原子操作保证数据一致性,是提升系统性能的重要缓存中间件。

cxbtdd的博客 1010

Redis简介和数据结构

Redis是一个开源的内存中数据结构存储系统,通常用作数据库、缓存和消息代理。它支持各种数据结构,包括字符串、哈希、列表、集合等,并提供了丰富的功能,如事务、持久化、发布/订阅等。内存中数据结构存储系统:Redis主要将数据存储在内存中,这使得它具有非常高的读写速度。它通过使用持久化技术来保证数据在重启后不会丢失,因此即使是存储在内存中,也能够满足持久化的需求。数据库、缓存和消息代理:Redis可以用作多种用途,包括传统数据库的替代品、缓存系统和消息代理。

2201_75839679的博客 1325

【Redis】Redis 数据结构详解:从基础到进阶

Redis(REmote DIctionary Server)是一个高效的键值存储数据库,支持多种数据结构和持久化选项,能够快速处理大量的读写请求。它主要用于缓存、数据存储和消息队列等场景。Redis 是一个强大的数据存储解决方案,其多样的数据结构能够满足各种应用需求。掌握这些基础知识和操作,将帮助你在实际开发中高效利用 Redis。如果你对 Redis 有更多疑问或想法,欢迎分享和交流!

人生苦短,睡觉要紧,睡醒再说 1046

【Redis】初识Redis(定义、特征、使用场景)

本篇文章介绍 Redis 的基本情况,说明其在内存中存储数据的特点,以及它可作为数据库、缓存、消息中间件的多重角色。还讲解了Redis特性,包括内存数据结构、可编程性、可扩展性、持久化、集群、高可用和速度快等方面。​

是阿建吖! 1562

深入解析Redis:一种快速、高效的键值存储系统

Redis最初由Salvatore Sanfilippo开发,于2009年首次发布。它是一个开源项目,使用ANSI C编写,支持多种操作系统和语言。Redis的发展受益于其简单、高效和可靠的设计,因此得到了广泛的应用和支持。字符串:存储一个字符串值。哈希:存储键值对的无序集合。列表:存储一个有序的字符串列表。集合:存储一个无序的字符串集合。有序集合:存储一个有序的字符串集合,并为每个成员指定一个分数。

博客 757
上一篇: 模板引擎:第二章:Thymeleaf
下一篇: 全文检索工具elasticsearch:第一章:理论知识
Java程序员廖志伟
Java程序员廖志伟 优质创作者: Java技术领域 优质创作者: Java技术领域 领域专家: 后端开发技术领域 领域专家: 后端开发技术领域
博客等级 码龄8年 2万+粉丝 1902原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java程序员廖志伟

赏我包辣条呗

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值