Redis一些常用的技术

news2024/11/26 19:33:35

文章目录

  • 第1关:Redis 事务与锁机制
  • 第2关:流水线
  • 第3关:发布订阅
  • 第4关:超时命令
  • 第5关:使用Lua语言


第1关:Redis 事务与锁机制

编程要求
根据提示,在右侧编辑器Begin-End补充代码,根据以下要求完成一个模拟一次银行卡支付扣款的流程:
1、当余额不足时,放弃所有被监控的键,返回false。
2、在余额扣除消费的金额,在支付金额里加上消费的金额。

测试说明
我会对你编写的代码进行测试:

测试输入:无;
预期输出:

支付成功
本次扣款10元,余额为90元
开始你的任务吧,祝你成功!
示例代码如下:

package com.test;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;
import java.util.List;
public class TestRedis {
    private static String host = "127.0.0.1";
    private static int port = 6379;
    private static Jedis jedis = new Jedis(host, port);
    public static boolean payMent(int deduction) throws InterruptedException {
        int balance;  // 余额
        //设置余额金额
        jedis.set("balance", "100");
        jedis.set("deduction", "0");
        //监控扣款和余额
        jedis.watch("balance", "deduction");
        /***********Begin***********/
        balance = Integer.parseInt(jedis.get("balance"));
        // 余额不足
        if (balance < deduction) {
            jedis.unwatch();  // 放弃所有被监控的键
            System.out.println("对不起,你的余额不足");
            return false;
        }
        Transaction transaction = jedis.multi();
        // 扣钱
        transaction.decrBy("balance", deduction);
        Thread.sleep(5000);  // 在外部修改 balance 或者 debt
        transaction.incrBy("deduction", deduction);
        // list为空说明事务执行失败
        List<Object> list = transaction.exec();
        return !list.isEmpty();
        /***********End***********/
    }
    public static void main(String[] args) throws InterruptedException {
        boolean resultValue = payMent(10);
        if (resultValue==true){
            System.out.println("支付成功");
            int balance = Integer.parseInt(jedis.get("balance"));
            int deduction = Integer.parseInt(jedis.get("deduction"));
            System.out.printf("本次扣款"+deduction+"元,余额为"+balance+"元");
        }else{
            System.out.println("支付失败");
        }
        jedis.close();
    }
}

在这里插入图片描述

第2关:流水线

编程要求
根据提示,在右侧编辑器Begin-End补充代码,按照以下要求开启一次流水线技术:

开启流水线。
测试十万条读写操作,设置 key 值为 key0 、 key1 、 key2 …key99998、key99999,对应 value 值为 value0 、value1、value2…value99998、value99999。
结束流水线。
测试说明
我会对你编写的代码进行测试:

测试输入:无;
预期输出:

开启流水线
消耗时间:XXX毫秒
关闭流水线
流水线成功完成!
开始你的任务吧,祝你成功!
示例代码如下:

package com.test;
import redis.clients.jedis.*;
import java.util.List;
public class RedisPipeline {
    public  boolean pipeline() {
        String redisHost = "127.0.0.1";
        int redisPort = 6379;
        Jedis jedis = new Jedis(redisHost, redisPort);
        jedis.flushDB();
        /**********Begin**********/
        long start = System.currentTimeMillis();
        // 开启流水线
        Pipeline pipeline = jedis.pipelined();
        System.out.println("开启流水线");
        // 测试十万条读写操作
        for (int i = 0; i < 100000; i++) {
            pipeline.set("key"+i,"value"+i);
            pipeline.get("key"+i);
        }
        long end = System.currentTimeMillis();
        //关闭流水线
        pipeline.close();
        System.out.println("消耗时间:"+(end-start)+"毫秒");
        System.out.println("关闭流水线");
        /**********End**********/
        return true;
    }
}

在这里插入图片描述

第3关:发布订阅

编程要求
根据提示,在右侧编辑器Begin-End补充代码,按照以下要求:

在SubThread类中订阅指定频道redis。
测试说明
我会对你编写的代码进行测试:

测试输入:quit;
预期输出:

订阅redis, 订阅频道为 redis, 线程将被阻塞
订阅redis频道成功, 频道为 redis, 订阅频道为 1
请输入传输的信息:
关闭程序
开始你的任务吧,祝你成功!
示例代码如下:

package com.test;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
public class SubThread extends  Thread {
    private final JedisPool jedisPool;
    private final Subscriber subscriber = new Subscriber();
    private final String channel = "redis";
    public SubThread(JedisPool jedisPool) {
        super("SubThread");
        this.jedisPool = jedisPool;
    }
    @Override
    public void run() {
        System.out.println(String.format("订阅redis, 订阅频道为 %s, 线程将被阻塞", channel));
        Jedis jedis = null;
        try {
            /************* Begin ***************/
            jedis = jedisPool.getResource();
            jedis.subscribe(subscriber, channel);
             /************* End ***************/
        } catch (Exception e) {
            System.out.println(String.format("订阅频道错误, %s", e));
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
    }
}

第4关:超时命令

编程要求
根据提示,在右侧编辑器Begin-End补充代码,按照以下要求使用 Spring 操作 Redis 超时命令过程:

创建键值对:key 值为“今天你吃了吗?”
获取 key 值
设置 key 的过期时间为 5 秒
测试说明
我会对你编写的代码进行测试:

测试输入:无;
预期输出:

今天你吃了吗?
null
开始你的任务吧,祝你成功!
示例代码如下:

package com.redis;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.RedisTemplate;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import java.util.concurrent.TimeUnit;
public class OverTimeRedisTest {
    @SuppressWarnings({ "unchecked", "rawtypes", "resource" })
    public static void main(String[] args) {
        ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
        RedisTemplate redisTemplate=applicationContext.getBean(RedisTemplate.class);
        redisTemplate.execute((RedisOperations ops) -> {
       
       /************Begin************/
        ops.boundValueOps("key").set("今天你吃了吗?");
        System.out.println(ops.boundValueOps("key").get());
        ops.expire("key",5L, TimeUnit.SECONDS);
        /************End************/
        //睡眠6秒,使得key值过期
        try {
            Thread.sleep(6000);
        }catch (InterruptedException e){
            e.printStackTrace();
        }
        //获取key值
        System.out.println(ops.boundValueOps("key").get());
        //结束所有线程,退出系统
        System.exit(0);
        return null;
        });
    }
}

在这里插入图片描述

第5关:使用Lua语言

编程要求
根据提示,在右侧编辑器 Begin - End 处补充代码,根据以下要求完成一次手机销售库存的操作:

编写 ItemRedisTest.lua 文件,判断销售量是否比库存数量多,如果库存数量大于这次销售量,将新的库存数量更新到原来的 key 值上。
编写 ItemRedisTest.java 文件,使用 BufferedReader 读取ItemRedisTest.lua 文件,使用 eval 命令执行文件里的字符串,设置手机销售量为10。
ItemRedisTest.lua 地址为:/data/workspace/myshixun/step5/ItemRedisTest.lua
测试说明
我会对你编写的代码进行测试:

测试输入:无;
预期输出:

手机库存剩余:90
开始你的任务吧,祝你成功!
代码示例如下:

package com.redis;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.data.redis.core.RedisTemplate;
import redis.clients.jedis.Jedis;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class ItemRedisTest {
    public static void main(String[] args) throws IOException {
        ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
        RedisTemplate redisTemplate=applicationContext.getBean(RedisTemplate.class);
        Jedis jedis=(Jedis)redisTemplate.getConnectionFactory().getConnection().getNativeConnection();
        jedis.set("phone_item_stock", "100");
         /************Begin************/
        BufferedReader in= new BufferedReader(new FileReader("/data/workspace/myshixun/step5/ItemRedisTest.lua"));
        String context =null;
        String script="";
        while (null != (context = in.readLine())){
            script+=context+"\n";
        }
        Object obj =  jedis.eval(script, 1,"phone_item_stock","10");
        /************End************/
        
        System.out.println("手机库存剩余:"+obj);
        //关闭连接
        jedis.close();
        System.exit(0);
    }
}

之后在命令行中输入下列代码:

vim /data/workspace/myshixun/step5/ItemRedisTest.lua

编辑该文件内容
文件修改完之后的内容

local count = redis.call('get', KEYS[1])
local a=tonumber(count)
local b=tonumber(ARGV[1])
---Begin
if a>=b then
    redis.call('set',KEYS[1],count-b)
    return redis.call('get', KEYS[1])
end
---End

在这里插入图片描述


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

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

相关文章

vuepress-----25、右侧目录

# 25、vuepress 右侧目录 https://github.com/xuek9900/vuepress-plugin-right-anchor vuepress-plugin-right-anchor English &#xff5c;中文 在用 Vuepress 2.x 编写的文档页面右侧添加 锚点导航栏 # 版本 2.x.x -> Vuepress 2.x -> npm next -> master 分支0…

c语言突击

一&#xff1a;前序 1.一个c语言程序有且只有一个main函数&#xff0c;是程序运行的起点&#xff01; 每个c语言程序写完后&#xff0c;都是先编译&#xff08;.c---&#xff09;&#xff0c;后链接&#xff08;.obj---&#xff09;&#xff0c;最后运行&#xff08;.exe&…

ROS-分布式通信

ROS是一个分布式计算环境。一个运行中的ROS系统可以包含分布在多台计算机上多个节点。根据系统的配置方式&#xff0c;任何节点可能随时需要与任何其他节点进行通信。 因此&#xff0c;ROS对网络配置有某些要求&#xff1a; 所有端口上的所有机器之间必须有完整的双向连接。每…

【VScode】设置语言为中文

1、下载安装好vscode 2、此时可看到页面为英文&#xff0c;为方便使用可切换为中文 3、键盘按下 ctrlshiftP 4、在输入框内输入configure display language 5、选择中文&#xff0c;restart即可&#xff08;首次会有install安装过程&#xff0c;等待安装成功后重启即可&am…

反爬虫介绍及其处理方法

反爬虫机制 封IP&#xff1a;监控短时间内同一地址的请求次数过大登录及验证码&#xff1a;对于监控后封IP之后短时间内继续的大量请求&#xff0c;要求登陆或验证码通过验证之后才能继续进行。健全账号体制&#xff1a;即核心数据只能通过账号登录后才能进行访问。动态加载数…

【.NET】控制台应用程序的各种交互玩法

关于控制台交互&#xff0c;大伙伴们也许见得最多的是进度条&#xff0c;就是输出一行但末尾不加 \n&#xff0c;而是用 \r 回到行首&#xff0c;然后输出新的内容&#xff0c;这样就做出进度条了。不过这种方法永远只能修改最后一行文本。 于是&#xff0c;有人想出了第二种方…

【MATLAB】数据拟合第12期-基于高斯核回归的拟合算法

有意向获取代码&#xff0c;请转文末观看代码获取方式~也可转原文链接获取~ 1 基本定义 基于高斯核回归的拟合算法是一种处理回归问题的机器学习方法。以下是该算法的简单介绍&#xff1a; 核心思想&#xff1a;高斯核回归的核心思想是利用高斯核函数对数据点进行非线性映射&a…

AudioGPT 语音技术全覆盖:语音识别、增强、分离、风格迁移等 | 开源日报 No.114

stevearc/oil.nvim Stars: 1.7k License: MIT oil.nvim 是一个类似于 vim-vinegar 的文件浏览器&#xff0c;允许您像普通 Neovim 缓冲区一样编辑文件系统。其主要功能包括支持常见插件管理器、通过适配器抽象进行所有文件系统交互以及提供 API 来执行各种操作。该项目的关键…

RNN梯度爆炸实验

前情回顾 from torch.utils.data import Dataset import torch.nn as nn import torch.nn.functional as F import os import random import torch from nndl import Accuracy from nndl import RunnerV3 from torch.utils.data import DataLoader import matplotlib.pyplot a…

零基础自学C语言|字符函数和字符串函数

在编程的过程中&#xff0c;我们经常要处理字符和字符串&#xff0c;为了方便操作字符和字符串&#xff0c;C语言标准库中提供了一系列库函数&#xff0c;接下来我们就学习一下这些函数。 &#x1f4cc;字符分类函数 C语言中有一系列的函数是专门做字符分类的&#xff0c;也就…

06_Web框架之Django三

Web框架之Django三 学习目标和内容 1、能够通过ORM模型创建数据表 2、能够通过ORM模型对数据进行操作 3、能够理解ORM模型对应关系 一、ORM概念 1、ORM介绍 对象关系映射 用于实现面向对象编程语言里不同类型系统数据之间的转换。 其就是使用面向对象的方式&#xff0c;操作…

风速预测(六)基于Pytorch的EMD-CNN-GRU并行模型

目录 前言 1 风速数据EMD分解与可视化 1.1 导入数据 1.2 EMD分解 2 数据集制作与预处理 2.1 先划分数据集&#xff0c;按照8&#xff1a;2划分训练集和测试集 2.2 设置滑动窗口大小为96&#xff0c;制作数据集 3 基于Pytorch的EMD-CNN-GRU并行模型预测 3.1 数据加载&a…

得帆信息创始人-张桐,受邀出席 BV百度风投AIGC主题论坛

近日&#xff0c;得帆信息创始人兼CEO张桐&#xff0c;作为百度风投被投代表企业创始人受邀出席“向未来&#xff0c;共成长” BV百度风投AIGC主题论坛。 与包括上海市徐汇区相关部门领导、百度集团相关事业部负责人及代表&#xff0c;以及来自国寿资本、中网投、麦顿投资的投资…

IDEA运行JSP启动后页面中文乱码

源代码截图&#xff1a; 运行结果截图&#xff1a; 在<head>标签内加入代码 <% page contentType"text/html; charsetgb2312"%> 重启服务器&#xff0c;问题已改善 ————————————————— 该文仅供学习以及参考&#xff0c;可做笔记收藏…

SQL语句整理二--Mysql

文章目录 知识点梳理&#xff1a;1. mysql 中 in 和 exists 区别2. varchar 与 char 的区别 查看表结构&#xff1a;获取当前时间&#xff1a;查看建表语句&#xff1a;修改用户密码&#xff1a;查看所有用户&#xff1a;grant命令&#xff1a;判断当前数据库有多少连接数&…

部署promethues采集kubelet数据报错:server returned HTTP status 403 Forbidden

背景 笔者尝试部署手动部署promethues去采集kubelet的node节点数据信息时报错 笔者的promethus的配置文件和promthues的clusterrole配置如下所示&#xff1a; apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata:name: prometheus rules: - apiGroups: […

钡铼无线R10A工业级路由器在工业机器人领域的创新应用

随着工业机器人的普及&#xff0c;对于高可靠性和高稳定性的网络接入设备的需求也越来越大。传统的有线网络虽然稳定&#xff0c;但在现场布置和维护上面临很多困难&#xff0c;而无线网络虽然方便&#xff0c;但受到信号干扰和传输距离限制等问题的影响。如何解决这些问题&…

在centos7上安装docker

1.CentOS安装Docker Docker CE 支持 64 位版本 CentOS 7&#xff0c;并且要求内核版本不低于 3.10&#xff0c; CentOS 7 满足最低内核的要求&#xff0c;所以我们在CentOS 7安装Docker。 1.1.卸载&#xff08;可选&#xff09; 如果之前安装过旧版本的Docker&#xff0c;可…

Python tkinter控件全集之组合选择框 ttk.ComboBox

Tkinter标准库 Tkinter是Python的标准GUI库&#xff0c;也是最常用的Python GUI库之一&#xff0c;提供了丰富的组件和功能&#xff0c;包括窗口、按钮、标签、文本框、列表框、滚动条、画布、菜单等&#xff0c;方便开发者进行图形界面的开发。Tkinter库基于Tk for Unix/Wind…

DC-5靶场

目录 DC-5靶机&#xff1a; 先进行主机发现&#xff1a; 发现文件包含&#xff1a; 上传一句话木马&#xff1a; 反弹shell&#xff1a; 提权漏洞利用&#xff1a; 下载exp&#xff1a; 第一个文件 libhax.c 第二个文件r…