搜索
写经验 领红包
 > 职场

edis在项目中的应用场景(edis项目中哪些用到)

导语:谈谈 redis 在项目中的常见使用场景

redis在项目中的应用场景(redis项目中哪些用到)

最近在写一个脚手架,其中 redis 的使用场景还挺多,于是总结下它的常见使用场景

缓存
> set User:1:name shanyue EX 100 NXOK> get User:1:name"shanyue"复制代码

缓存是 redis 出镜率最高的一种使用场景,仅仅使用 set/get 就可以实现,不过也有一些需要考虑的点

如何更好地设置缓存如何保持缓存与上游数据的一致性如何解决缓存血崩,缓存击穿问题session: 用户登录及验证码
> set 5d27e60e6fb9a07f03576687 '{"id": 10086, role: "ADMIN"}' EX 7200OK> get 5d27e60e6fb9a07f03576687"{\"id\": 10086, role: \"ADMIN\"}"复制代码

这也是很常用的一种场景,不过相对于有状态的 session,也可以考虑使用 JWT,各有利弊

消息队列
> lpush UserEmailQueue 1 2 3 4lpop UserEmailQueue> rpop UserEmailQueue1> rpop UserEmailQueue2复制代码

可以把 redis 的队列视为分布式队列,作为消息队列时,生产者在一头塞数据,消费者在另一头出数据: (lpush/rpop, rpush/lpop)。不过也有一些不足,而这些不足有可能是致命的,不过对于一些丢几条消息也没关系的场景还是可以考虑的

没有 ack,有可能丢消息需要做 redis 的持久化配置过滤器 (dupefilter)
> sadd UrlSet http://1(integer) 1> sadd UrlSet http://2(integer) 1> sadd UrlSet http://2(integer) 0> smembers UrlSet1) "http://1"2) "http://2"复制代码

scrapy-redis 作为分布式的爬虫框架,便是使用了 redis 的 Set 这个数据结构来对将要爬取的 url 进行去重处理。

 释放锁,一段 LUA 脚本if redis.call("get",KEYS[1]) == ARGV[1] then return redis.call("del",KEYS[1])else return 0end复制代码

这是一个最简单的单机版的分布式锁,有以下要点

EX 表示锁会过期释放NX 保证原子性解锁时对比资源对应产生的 UUID,避免误解锁

当你使用分布式锁是为了解决一些性能问题,如分布式定时任务防止执行多次 (做好幂等性),而且鉴于单点 redis 挂掉的可能性很小,可以使用这种单机版的分布式锁。

Rate Limit

限流即在单位时间内只允许通过特定数量的请求,有两个关键参数

window,单位时间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 的请求进行限流处理,但是要注意几个问题

在平滑的滑动窗口时间内在极限情况下会有两倍数量的请求数条件竞争 (Race Condition)

这时候可以通过编程,根据 TTL key 进行进一步限制,或者使用一个 LIST 来维护每次请求打来的时间戳进行实时过滤。以下是 node 实现的一个 Rate Limter。参考源码 node-rate-limiter-flexible

this.client .multi() .set(rlKey, 0, 'EX', secDuration, 'NX') .incrby(rlKey, points) .pttl(rlKey) .exec((err, res) => { if (err) { return reject(err); } return resolve(res); })if (res.consumedPoints > this.points) { // ...} else if (this.execEvenly && res.msBeforeNext > 0 && !res.isFirstInDuration) { // ... setTimeout(resolve, delay, res);} else { resolve(res);}复制代码
node-rate-limiter-flexible邮件发送,限流,漏桶与令牌桶分布式 websocket

可以通过 redis 的 PUB/SUB 来在 websocket server 间进行交流。可以参考以下项目

socket.io-redis

本文内容由小欣整理编辑!