redis使用基础

redis springboot常用命令

1
2
3
4
5
6
7
8
9
10
11
@Autowired
StringRedisTemplate redisTemplate;
//----------------------------------------------------------------------
//给key设置value
redisTemplate.opsForValue().set("key","value"); //SET key "value"
//取key的value
redisTemplate.opsForValue().get("key");//GET key
//设置key在new Date()过期
redisTemplate.expireAt("key",new Date()); //EXPIREAT key timestamp
redisTemplate.getExpire("testttl"); //返回过期时间

reids设置过期key监听事件

  1. 在redis命令行执行config set notify-keyspace-events Ex

  2. 在java代码添加监听事件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    import org.springframework.data.redis.connection.Message;
    import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
    import org.springframework.data.redis.listener.RedisMessageListenerContainer;
    import org.springframework.stereotype.Component;

    @Component
    public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {
    public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {
    super(listenerContainer);
    }
    @Override
    public void onMessage(Message message, byte[] pattern) {
    // 处理接收到的消息
    String channel = new String(message.getChannel());
    String body = new String(message.getBody());
    System.out.println("接收到来自通道 " + channel + " 的消息:" + body);
    }
    }
  3. 等待过期,就会打印如下内容

    1
    2
    3
    接收到来自通道 __keyevent@1__:expired 的消息:GATE:DEVICE:HEART:1725361717475983361
    接收到来自通道 __keyevent@1__:expired 的消息:GATE:DEVICE:HEART:1728969231125295105
    接收到来自通道 __keyevent@1__:expired 的消息:GATE:DEVICE:HEART:1726505401086349313

从redis里面获取二进制图片

redis的key是camera:frames:1838502535022682114,类型是SORTED SET,里面的数据格式是:

Member Score
\xff\xd8\xff\xe0\x00\x10JFIF\x…..\t\x8e\xc7\xff\xd9 173312719710
\xff\xd8\xff\xe0\x00\x10JFIF\x…..\t\x8e\xc7\xff\xd9 173312719711
\xff\xd8\xff\xe0\x00\x10JFIF\x…..\t\x8e\xc7\xff\xd9 173312719712

对应的java代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Resource
private RedisTemplate<String, byte[]> redisTemplate;

@GetMapping("/getVideoImg")
public String getVideoImg(@RequestParam(value = "deviceId") String deviceId) {
// 动态设置序列化器为 ByteArrayRedisSerializer
redisTemplate.setKeySerializer(new StringRedisSerializer()); // 键:String 类型,指的是key=camera:frames:1838502535022682114是string
//设置自定义序列号类型
redisTemplate.setValueSerializer(new ByteArrayRedisSerializer()); // 值:byte[] 类型
// 获取 Sorted Set 中分数最高的成员,成员为 byte[]
Set<byte[]> members = redisTemplate.opsForZSet().range("camera:frames:" + deviceId, 0, 0); //取第0个到第0个数据,也就是只拿一个数据
if (members != null && !members.isEmpty()) {
byte[] latestFrameKey = members.iterator().next();//获取一个元素的本身
// 将图片转换为 Base64 编码
return Base64.getEncoder().encodeToString(latestFrameKey);
}
return "not found";
}

对应的序列号类:ByteArrayRedisSerializer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import org.springframework.data.redis.serializer.RedisSerializer;

public class ByteArrayRedisSerializer implements RedisSerializer<byte[]> {

@Override
public byte[] serialize(byte[] bytes) {
return bytes; // 不需要额外处理,直接返回
}

@Override
public byte[] deserialize(byte[] bytes) {
return bytes; // 不需要额外处理,直接返回
}
}

访问测试:apifox掉[http://127.0.0.1:8080/test/getVideoImg?deviceId=1838502535022682114]接口,就可以得倒base64的图片了,在apifox的后置脚本添加如下自定义脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 获取图片数据
let svgContent = pm.response.text();

// 将图片声明为Base64编码
let imgBase64 = `data:image/jpeg;base64,${svgContent}`;

// html 模板
const template = `<html>
<img src="{{imgTemplate}}" />
</html>`;

// 设置 visualizer 数据。传模板、解析对象。
pm.visualizer.set(template, {
imgTemplate: imgBase64,
})

然后可以直接在结果切到Visualize视图就可以看到图片了。

python里面设置可以java序列号的json字符串

最重要的是要在json外层添加"@class": "java.lang.Object",为什么是java.lang.Object,因为这个支持嵌套,其他hash map不支持多层嵌套,除非python在每层都是在@class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import redis
import json

# 创建 Redis 客户端
r = redis.StrictRedis(host='172.16.80.117', port=6479, db=1, password='123456')

# 示例 JSON 对象
data = {
"@class": "java.lang.Object", # 手动添加类型标识
"name": "Alice",
"age": 30,
"city": "New York"
}

data2={
"@class": "java.lang.Object",
"algo_name": "OBJECT_SEGMENTATION",
"algo_show_name": "OBJECT_SEGMENTATION",
"algo_icon": "&#xe671",
"algo_args": {},
"bus_args": {"ROI": [[[0, 0], [1919, 0], [1919, 1079], [0, 1079]]], "ThreshIOU": 0.0, "ObjectType": ["person"]}
}


# 将 JSON 对象转换为字符串
data_string = json.dumps(data)
data_string2 = json.dumps(data2)

try:
# 使用 hset 存储 JSON 字符串
r.hset("user:1000", "sdfsdfsdfsdf", data_string)
r.hset("user:1000", "www", data_string2)
r.hset("user:1000", "www2", data_string2)
print("数据已成功存储到 Redis")
except Exception as e:
print(f"存储时发生错误: {e}")

注意

reids重新设值会覆盖expireAt过期时间的设置

参考

记一次Redis_Key值无效监听失效的失败历程