2023年6月29日发(作者:)
谈谈redis在项⽬中的常见使⽤场景?最近在写⼀个脚⼿架,其中 redis 的使⽤场景还挺多,于是总结下它的常见使⽤场景01 缓存> set User:1:name shanyue EX 100 NXOK> get User:1:name"shanyue"缓存是 redis 出镜率最⾼的⼀种使⽤场景,仅仅使⽤ set/get 就可以实现,不过也有⼀些需要考虑的点(1)如何更好地设置缓存(2)如何保持缓存与上游数据的⼀致性(3)如何解决缓存⾎崩,缓存击穿问题02 session: ⽤户登录及验证码> set 5d27e60e6fb9a07f03576687 '{"id": 10086, role: "ADMIN"}' EX 7200OK> get 5d27e60e6fb9a07f03576687"{"id": 10086, role: "ADMIN"}"这也是很常⽤的⼀种场景,不过相对于有状态的 session,也可以考虑使⽤ JWT,各有利弊03 消息队列> lpush UserEmailQueue 1 2 3 4lpop UserEmailQueue> rpop UserEmailQueue1> rpop UserEmailQueue2可以把 redis 的队列视为分布式队列,作为消息队列时,⽣产者在⼀头塞数据,消费者在另⼀头出数据: (lpush/rpop, rpush/lpop)。不过也有⼀些不⾜,⽽这些不⾜有可能是致命的,不过对于⼀些丢⼏条消息也没关系的场景还是可以考虑的(1)没有 ack,有可能丢消息(2)需要做 redis 的持久化配置04 过滤器 (dupefilter)> sadd UrlSet 1(integer) 1> sadd UrlSet 2(integer) 1> sadd UrlSet 2(integer) 0> smembers UrlSet1) "1"2) "2"scrapy-redis作为分布式的爬⾍框架,便是使⽤了 redis 的 Set 这个数据结构来对将要爬取的 url 进⾏去重处理。# /rmax/scrapy-redis/blob/master/src/scrapy_redis/ request_seen(self, request): """Returns True if request was already seen. Parameters ---------- request : t Returns ------- bool """ fp = t_fingerprint(request) added = (, fp) return added == 0不过当 url 过多时,会有内存占⽤过⼤的问题05 分布式锁set Lock:User:10086 06be97fc-f258-4202-b60b-8d5412dd5605 EX 60 NX# 释放锁,⼀段 LUA 脚本if ("get",KEYS[1]) == ARGV[1] then return ("del",KEYS[1])else return 0end这是⼀个最简单的单机版的分布式锁,有以下要点(1)EX 表⽰锁会过期释放(2)NX 保证原⼦性解锁时对⽐资源对应产⽣的 UUID,避免误解锁当你使⽤分布式锁是为了解决⼀些性能问题,如分布式定时任务防⽌执⾏多次 (做好幂等性),⽽且鉴于单点 redis 挂掉的可能性很⼩,可以使⽤这种单机版的分布式锁。06 Rate Limit限流即在单位时间内只允许通过特定数量的请求,有两个关键参数(1)window,单位时间(2)max,最⼤请求数量最常见的场景: 短信验证码⼀分钟只能发送两次FUNCTION LIMIT_API_CALL(ip):current = GET(ip)IF current != NULL AND current > 10 THEN ERROR "too many requests per second"ELSE value = INCR(ip) IF value == 1 THEN EXPIRE(ip,1) END PERFORM_API_CALL()END可以使⽤计数器对 API 的请求进⾏限流处理,但是要注意⼏个问题(1)在平滑的滑动窗⼝时间内在极限情况下会有两倍数量的请求数(2)条件竞争 (Race Condition)这时候可以通过编程,根据 TTL key 进⾏进⼀步限制,或者使⽤⼀个 LIST 来维护每次请求打来的时间戳进⾏实时过滤。以下是 node 实现的⼀个 Rate Limter。 .multi() .set(rlKey, 0, 'EX', secDuration, 'NX') .incrby(rlKey, points) .pttl(rlKey) .exec((err, res) => { if (err) { return reject(err); } return resolve(res); })if (edPoints > ) { // ...} else if (enly && reNext > 0 && !tInDuration) { // ... setTimeout(resolve, delay, res);} else { resolve(res);}07 分布式 websocket可以通过 redis 的 PUB/SUB 来在 websocket server 间进⾏交流。免费分享Java技术资料,需要的私信我免费获取
作者:Java⽼王来源:简书简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处
发布者:admin,转转请注明出处:http://www.yc00.com/xiaochengxu/1687988095a64255.html
评论列表(0条)