Skip to content

Commit a971382

Browse files
committed
update: redis post & filename
1 parent a9dff03 commit a971382

File tree

3 files changed

+132
-5
lines changed

3 files changed

+132
-5
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ tags = ['DeepLearning']
66
+++
77

88
- Course Note: d2l-video-04 - 数据操作+数据预处理
9-
- Jupyter Notebook: chapter\_preliminaries
9+
- Jupyter Notebook: chapter\_preliminaries/
1010

1111
### 介绍
1212

content/posts/2025-08-19_redis-learn.md renamed to content/posts/2025-08-19_redis-learn-01.md

Lines changed: 124 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ class Cache:
6666
return self.client.get(key)
6767

6868
def update(self, new_value, key):
69-
return self.client.getset(key, new_value)
69+
return self.client.getset(key, new_value) # 设置新值, 返回旧值
7070

7171
```
7272

@@ -295,7 +295,7 @@ class Article:
295295
- APPEND: 追加新内容到值的末尾
296296
> APPEND key suffix
297297
298-
若用户给定的 key 不存在, 则会先将键执行追加操作
298+
若用户给定的 key 不存在, 则相当于 SET key suffix
299299

300300

301301
### 示例: 存储日志
@@ -326,10 +326,130 @@ class Log:
326326
```
327327

328328

329-
----------
330-
329+
## 数字值
331330
下面介绍使用字符串键存储数字值:
332331

333332
每当存储一个值到字符串键里面的时候, 有下面两种情况
334333
1. C 语言 long long int 类型的整数, 取值范围为 -2^63 ~ 2^63-1 (超出范围会被当成字符串)
335334
2. C 语言 long double 类型的浮点数
335+
336+
为了方便地处理字符串键的值, Redis 提供了一系列加法和减法操作命令, 下面介绍这些命令
337+
338+
- INCRBY, DECRBY: 对整数执行加法和减法操作 O(1)
339+
> INCRBY key increment
340+
> DECRBY key increment
341+
342+
如果类型为浮点数, 使用上面方法会报错 (key的值 和 increment 都必须为整数)
343+
344+
当该命令遇到**不存在的键**时, 会将键的值初始化为0, 然后再执行操作
345+
346+
- INCR, DECR: 对整数执行加1和减1操作 O(1)
347+
> INCR key
348+
> DECR key
349+
350+
- INCRBYFLOAT: 对数字值执行浮点数加减法操作
351+
> INCRBYFLOAT key increment
352+
353+
INCRBYFLOAT 命令即执行加法操作, 也可以执行加法操作, 并且操作对象和 increment 都既可以为整数也可以为浮点数
354+
355+
虽然 Redis 没有限制字符串键存储浮点数的小数位数, 但是 INCRBYFLOAT 最多只会保留小数点后的17位数字, 超出部分将被截断
356+
357+
### 示例: ID 生成器
358+
identifier 标识符, 经常在程序中使用, 通常以数字形式出现, 并通过递增的方法创建新的ID.
359+
360+
```Python
361+
from redis import Redis
362+
363+
class IdGenerator:
364+
def __init__(self, client, key):
365+
self.client = client
366+
self.key = key
367+
def produce(self):
368+
"""生成下一个id"""
369+
return self.client.incr(self.key)
370+
def reserve(self, n):
371+
"""初始化"""
372+
result = self.client.set(self.key, n, nx=1) # key 不存在才行
373+
return result is True
374+
375+
client = Redis(decode_responses=True)
376+
id_generator = IdGenerator(client, "user::id")
377+
print(id_generator.reserve(1000000)) # 保留100万个ID -> True
378+
print(id_generator.produce()) # 生成ID, 均大于100万
379+
380+
print(id_generator.reserve(1000)) # 已存在 -> False
381+
```
382+
383+
### 示例: 计数器
384+
除了ID生成器, 计数器也是常用的组件之一, 例如点赞回复数量, 播放量等.
385+
```Python
386+
from redis import Redis
387+
388+
class Counter:
389+
def __init__(self, client, key):
390+
self.client = client
391+
self.key = key
392+
def increase(self, n=1):
393+
return self.client.incr(self.key, n)
394+
def decrease(self, n=1):
395+
return self.client.decr(self.key, n)
396+
def get(self):
397+
value = self.client.get(self.key)
398+
if value in None:
399+
return 0
400+
else:
401+
return int(value)
402+
def reset(self):
403+
old_value = self.client.getset(self.key)
404+
if old_value is None:
405+
return 0
406+
else:
407+
return(old_value)
408+
409+
client = Redis(decode_responses=True)
410+
counter = Counter(client, "counter::page_viewed")
411+
412+
print(counter.increase()) # +1
413+
print(counter.increase())
414+
print(counter.increase(10)) # +10
415+
416+
print(counter.decrease()) # -1
417+
print(counter.decrease(5)) # -5
418+
419+
print(counter.reset()) # 重置计数器
420+
print(counter.get()) # 返回计数器当前值
421+
```
422+
> 注: 在 redis-py 中 INCR 和 INCRBY 都使用 .incr() 方法
423+
424+
425+
### 示例: 限速器
426+
为了保障系统的安全性和性能, 并保证重要资源不被滥用, 应用程序需要对用户的行为进行限制
427+
- 防止网络爬虫: 限制每个IP地址在固定时间段内访问的页面数量
428+
- 防止爆力破解: 当用户多次输入错误的密码, 会帐号进行冻结
429+
430+
上面机制的实现可以使用限速器, 下面是一个限速器示例代码, 该程序将操作最大可执行次数存储在一个字符串里面, 每次用户进行该操作后就将其减1
431+
```Python
432+
from redis import Redis
433+
434+
class Limter:
435+
def __init__(self, client, key):
436+
self.client = client
437+
self.key = key
438+
def set_max_execute_times(self, max_execut_time):
439+
self.client.set(self.key, max_execut_time)
440+
def still_valid_to_execute(self):
441+
num = self.client.decr(self.key)
442+
return (num >= 0)
443+
def remaining_execute_times(self):
444+
num = int(self.client.get(self.key))
445+
if num < 0:
446+
return 0
447+
else:
448+
return num
449+
450+
client = Redis(decode_responses=True)
451+
limter = Limter(client, "wrong_password_limter")
452+
453+
print(limter.set_max_execute_times(5)) # 最多5次输入错误密码
454+
print(limter.still_valid_to_execute()) # 前5次 True, 之后 False
455+
```
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
+++
2+
date = '2025-08-20T8:00:00+08:00'
3+
draft = false
4+
title = 'Redis Hash'
5+
tags = ['Redis', 'Database']
6+
+++
7+

0 commit comments

Comments
 (0)