1、缓存

2、数据共享分布式(Session)

3、分布式锁

  • Redisson 实现的分布式锁

    4、全局ID

    5、计数器

  • 例如:文章的阅读量、微博点赞数、允许一定的延迟,先写入Redis再定时同步到数据库

    6、 限流

  • 以访问者的ip和其他信息作为key,访问一次增加一次计数,超过次数则返回false

  • 使用Redisson 定义的限流器

    1. @GetMapping("/send")
    2. public void send(String mobile) throws InterruptedException {
    3. //初始化限流器
    4. RRateLimiter rateLimiter = this.redissonClient.getRateLimiter("limit:sms:"+mobile);
    5. //初始化设置频率
    6. //30秒内颁发一个令牌
    7. rateLimiter.trySetRate(RateType.OVERALL,1,30, RateIntervalUnit.SECONDS);
    8. if(rateLimiter.tryAcquire()){
    9. System.out.println("发送短信"+ DateUtil.formatDateTime(new Date())+" "+mobile);
    10. TimeUnit.SECONDS.sleep(5);
    11. }
    12. System.err.println("正在发送短信,不要重复发送!");
    13. }

7、 位统计

  • HyperLogLog ```shell PFADD hzeyun:dau:yyyyMMdd user_id1

统计

PFCOUNT hzeyun:dau:yyyyMMdd1

统计月,先合并

PFMERGE hzeyun:mau:yyyyMM hzeyun:dau:yyyyMMdd1 hzeyun:uv:yyyyMMdd2

可应用场景

  • 统计注册 IP 数   
  • 统计每日访问 IP 数
  • 统计页面实时 UV 数
  • 统计在线用户数
  • 统计用户每天搜索不同词条的个数
  • 去重 ```

  • bigmap ```shell

    BitMap 底层采用字符串实现,Redis 中字符串的最大长度是 512M

    bitmap 占用空间

    (8 1024 1024 * 512) -1 = 2^32 - 1

用户签到场景

key 设计 方案

按年 统计

根据日期 offset = (今天是一年中的第几天) % (今年的天数),key = 用户id:年份

按月统计

根据日期 offset = (今天是这个月的第几天) % (当月天数),key = 用户id:年月

用户id 递增

根据 用户id offset = 用户id , key = 年月日

bitmap 命令认识

SETBIT 对 key 所储存的字符串值,设置或清除指定偏移量上的位(bit)。 >= 2.2.0 O(1) GETBIT 对 key 所储存的字符串值,获取指定偏移量上的位(bit)。 >= 2.2.0 O(1) BITCOUNT 计算给定字符串中,被设置为 1 的比特位的数量。 >= 2.6.0 O(N) BITPOS 返回位图中第一个值为 bit 的二进制位的位置。 >= 2.8.7 O(N) BITOP 对一个或多个保存二进制位的字符串 key 进行位元操作。 >= 2.6.0 O(N) BITFIELD BITFIELD 命令可以在一次调用中同时对多个位范围进行操作。 >= 3.2.0 O(1)

用户2月17号签到

SETBIT u:sign:1000:2019 16 1 # 偏移量是从0开始,所以要把17减1

检查2月17号是否签到

GETBIT u:sign:1000:201902 16 # 偏移量是从0开始,所以要把17减1

统计2月份的签到次数

BITCOUNT u:sign:1000:201902

获取2月份前28天的签到数据

BITFIELD u:sign:1000:201902 get u28 0

获取2月份首次签到的日期

BITPOS u:sign:1000:201902 1 # 返回的首次签到的偏移量,加上1即为当月的某一天

  1. <a name="rIOJB"></a>
  2. ####
  3. <a name="fWtl6"></a>
  4. #### 8、购物车
  5. - 使用 Hash 数据结构保存
  6. ```shell
  7. * 添加商品 -> hset cart:1001 10088 1
  8. * 增加数量 -> hincrby cart:1001 10088 1
  9. * 商品总数 -> hlen cart:1001
  10. * 删除商品 -> hdel cart:1001 10088
  11. * 获取购物车所有商品 -> hgetall cart:1001

9、用户消息时间线timeline

  • 使用数据结构 - 有序集合

    10、消息队列

    11、抽奖

  • 使用数据结构 - 集合 ```shell

    使用命令 SRANDMEMBER 随机返回集合中的元素

    可以重复抽

    SRANDMEMBER myset

不重复则使用命令

spop myset

  1. <a name="v0RLG"></a>
  2. #### 12、点赞、签到、打卡、投票
  3. - 点赞 - 使用 集合
  4. ```shell
  5. # 点赞: 点赞成功返回 True, 已点赞返回 False
  6. sdd articleId userId == 1
  7. # 取消点赞
  8. SREM articleId userId
  9. # 检查用户是否已点赞
  10. SISMEMBER articleId userId
  11. #获取所有点赞的用户
  12. SMEMBERS articleId
  13. #返回已点赞用户数
  14. SCARD articleId

13、商品标签

  • set

    1. #添加产品标签
    2. SADD productId::tags "大内存" "高像素"

    14、商品筛选

    1. // 获取差集
    2. sdiff set1 set2
    3. // 获取交集(intersection )
    4. sinter set1 set2
    5. // 获取并集
    6. sunion set1 set2

    15、用户关注、社交关系、商品推荐

  • 使用数据结构-集合 ```shell

    用户使用两个集合保存 关注者名单和 正在关注用户名单

    格式

    添加 当前用户 userId 关注用户 userId2

    sadd userId:following userId2

userId2 关注 当前用户 userId

sadd userId:follower userId2

取消关注

SREM userId:following userId2

获取关注者名单数量

SCARD userId:follower

判断是否为 正在关注用户名单

返回 正在关注用户名单

SMEMBERS userId:following

返回 关注者名单

SMEMBERS userId:follower

userId 关注的人也关注了 userId2 (取交集):

sinter userId:following userId2:follower

用户1 可能认识的人

sdiff userId2:following userId:following

用户2 可能认识的人

sdiff userId:following userId2:following

follow 关注 fans 粉丝 相互关注: sadd 1:follow 2 sadd 2:fans 1 sadd 1:fans 2 sadd 2:follow 1 我关注的人也关注了他(取交集): sinter 1:follow 2:fans 可能认识的人: 用户1可能认识的人(差集):sdiff 2:follow 1:follow 用户2可能认识的人:sdiff 1:follow 2:follow

  1. <a name="aRH79"></a>
  2. #### 16、排行榜
  3. - 使用数据结构 - 有序集合
  4. ```shell
  5. # 添加排行榜
  6. ZADD myzset 1 "one"
  7. # 获取排行榜分数
  8. ZSCORE myzset "one"
  9. # 移除排行榜
  10. ZREM myzset "one"
  11. # 增加分数
  12. ZINCRBY myzset 2 "one"
  13. #降低分数
  14. ZINCRBY myzset -2 "one"
  15. #获取排名: 从 0 开始
  16. ZREVRANK myzset "one"
  17. # 获取排名前三
  18. ZREVRANGE myzset 0 2

参考

[

](https://ljd0620.github.io/2019/02/18/%E5%9F%BA%E4%BA%8ERedis%E4%BD%8D%E5%9B%BE%E5%AE%9E%E7%8E%B0%E7%94%A8%E6%88%B7%E7%AD%BE%E5%88%B0%E5%8A%9F%E8%83%BD/#%E7%A4%BA%E4%BE%8B%E4%BB%A3%E7%A0%81)