资讯专栏INFORMATION COLUMN

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

Towers / 1141人阅读

摘要:参考源码邮件发送,限流,漏桶与令牌桶分布式可以通过的来在间进行交流。可以参考以下项目

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

本文链接: https://shanyue.tech/post/red...

github 备份: https://github.com/shfshanyue...

缓存
> set User:1:name shanyue EX 100 NX
OK
> get User:1:name
"shanyue"

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

如何更好地设置缓存

如何保持缓存与上游数据的一致性

如何解决缓存血崩,缓存击穿问题

session: 用户登录及验证码
> set 5d27e60e6fb9a07f03576687 "{"id": 10086, role: "ADMIN"}" EX 7200
OK
> get 5d27e60e6fb9a07f03576687
"{"id": 10086, role: "ADMIN"}"

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

json web token 实践登录以及校验码验证

消息队列
> lpush UserEmailQueue 1 2 3 4
lpop UserEmailQueue
> rpop UserEmailQueue
1
> rpop UserEmailQueue
2

可以把 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 UrlSet
1) "http://1"
2) "http://2"

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

# https://github.com/rmax/scrapy-redis/blob/master/src/scrapy_redis/dupefilter.py
def request_seen(self, request):
    """Returns True if request was already seen.
    Parameters
    ----------
    request : scrapy.http.Request
    Returns
    -------
    bool
    """
    fp = self.request_fingerprint(request)
    added = self.server.sadd(self.key, fp)
    return added == 0

不过当 url 过多时,会有内存占用过大的问题

分布式锁
set Lock:User:10086 06be97fc-f258-4202-b60b-8d5412dd5605 EX 60 NX

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

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

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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/37274.html

相关文章

  • 三年百度,五年阿里,阿里p8架构师浅谈:我是如何顺利进入BAT

    摘要:三年百度,五年阿里,阿里架构师浅谈我是如何顺利进入前些天在我群里认识了以为挺有意思的老哥,他也是工作年多技术和面试都不差,最近也是在找工作,是从京城来魔都的,也和他捞了不少。 说来惭愧,也不怕你们笑话。做开发8年多,到目前还是一名不折不扣的扫地僧。年前的辞职,到现在还在家静养中。其实也没什么,就是回家总结一下自己这些年来在外工作与面试等做一个简单的总结与反思。做一下自己后面一个人生规划...

    MudOnTire 评论0 收藏0
  • 三年百度,五年阿里,阿里p8架构师浅谈:我是如何顺利进入BAT

    摘要:三年百度,五年阿里,阿里架构师浅谈我是如何顺利进入前些天在我群里认识了以为挺有意思的老哥,他也是工作年多技术和面试都不差,最近也是在找工作,是从京城来魔都的,也和他捞了不少。 说来惭愧,也不怕你们笑话。做开发8年多,到目前还是一名不折不扣的扫地僧。年前的辞职,到现在还在家静养中。其实也没什么,就是回家总结一下自己这些年来在外工作与面试等做一个简单的总结与反思。做一下自己后面一个人生规划...

    seanlook 评论0 收藏0
  • Java面试通关要点汇总集

    摘要:本文会以引出问题为主,后面有时间的话,笔者陆续会抽些重要的知识点进行详细的剖析与解答。敬请关注服务端思维微信公众号,获取最新文章。 原文地址:梁桂钊的博客博客地址:http://blog.720ui.com 这里,笔者结合自己过往的面试经验,整理了一些核心的知识清单,帮助读者更好地回顾与复习 Java 服务端核心技术。本文会以引出问题为主,后面有时间的话,笔者陆续会抽些重要的知识点进...

    gougoujiang 评论0 收藏0
  • 史上最全阿里 Java 面试题总结

    摘要:以下为大家整理了阿里巴巴史上最全的面试题,涉及大量面试知识点和相关试题。的内存结构,和比例。多线程多线程的几种实现方式,什么是线程安全。点击这里有一套答案版的多线程试题。线上系统突然变得异常缓慢,你如何查找问题。 以下为大家整理了阿里巴巴史上最全的 Java 面试题,涉及大量 Java 面试知识点和相关试题。 JAVA基础 JAVA中的几种基本数据类型是什么,各自占用多少字节。 S...

    winterdawn 评论0 收藏0
  • 70 个 Spring 最常见面试题,Java 晋升必会

    摘要:容器自动完成装载,默认的方式是这部分重点在常用模块的使用以及的底层实现原理。 对于那些想面试高级 Java 岗位的同学来说,除了算法属于比较「天方夜谭」的题目外,剩下针对实际工作的题目就属于真正的本事了,热门技术的细节和难点成为了主要考察的内容。 这里说「天方夜谭」并不是说算法没用,不切实际,而是想说算法平时其实很少用到,甚至面试官都对自己出的算法题一知半解。 这里总结打磨了 70 道...

    Ashin 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<