# 参加抽奖活动

sadd key {userId}

获取所有抽奖用户,大轮盘转起来

smembers key

抽取count名中奖者,并从抽奖活动中移除

spop key count

抽取count名中奖者,不从抽奖活动中移除

srandmember key count

实现点赞,签到,like等功能(set)

# 1001用户给8001帖子点赞

sadd like::8001 1001

取消点赞

srem like::8001 1001

检查用户是否点过赞

sismember like::8001 1001

获取点赞的用户列表

smembers like::8001

获取点赞用户数

scard like::8001

实现关注模型,可能认识的人(set)

seven关注的人

sevenSub -> {qing, mic, james}

青山关注的人

qingSub->{seven,jack,mic,james}

Mic关注的人

MicSub->{seven,james,qing,jack,tom}

# 返回sevenSub和qingSub的交集,即seven和青山的共同关注

sinter sevenSub qingSub -> {mic,james}

我关注的人也关注他,下面例子中我是seven

qing在micSub中返回1,否则返回0

sismember micSub qing

sismember jamesSub qing

我可能认识的人,下面例子中我是seven

求qingSub和sevenSub的差集,并存在sevenMayKnow集合中

sdiffstore sevenMayKnow qingSub sevenSub -> {seven,jack}

电商商品筛选(set)

每个商品入库的时候即会建立他的静态标签列表如,品牌,尺寸,处理器,内存

# 将拯救者y700P-001和ThinkPad-T480这两个元素放到集合brand::lenovo

sadd brand::lenovo 拯救者y700P-001 ThinkPad-T480

sadd screenSize::15.6 拯救者y700P-001 机械革命Z2AIR

sadd processor::i7 拯救者y700P-001 机械革命X8TIPlus

获取品牌为联想,屏幕尺寸为15.6,并且处理器为i7的电脑品牌(sinter为获取集合的交集)

sinter brand::lenovo screenSize::15.6 processor::i7 -> 拯救者y700P-001

排行版(zset)

redis的zset天生是用来做排行榜的、好友列表, 去重, 历史记录等业务需求

# user1的用户分数为 10

zadd ranking 10 user1

zadd ranking 20 user2

取分数最高的3个用户

zrevrange ranking 0 2 withscores

过期策略

========

定期删除

redis 会将每个设置了过期时间的 key 放入到一个独立的字典中,以后会定期遍历这个字典来删除到期的 key。

定期删除策略

Redis 默认会每秒进行十次过期扫描(100ms一次),过期扫描不会遍历过期字典中所有的 key,而是采用了一种简单的贪心策略。

从过期字典中随机 20 个 key;

删除这 20 个 key 中已经过期的 key;

如果过期的 key 比率超过 1/4,那就重复步骤 1;

惰性删除

除了定期遍历之外,它还会使用惰性策略来删除过期的 key,所谓惰性策略就是在客户端访问这个 key 的时候,redis 对 key 的过期时间进行检查,如果过期了就立即删除,不会给你返回任何东西。

定期删除是集中处理,惰性删除是零散处理。

为什么要采用定期删除+惰性删除2种策略呢?

=========================

如果过期就删除。假设redis里放了10万个key,都设置了过期时间,你每隔几百毫秒,就检查10万个key,那redis基本上就死了,cpu负载会很高的,消耗在你的检查过期key上了

但是问题是,定期删除可能会导致很多过期key到了时间并没有被删除掉,那咋整呢?所以就是惰性删除了。这就是说,在你获取某个key的时候,redis会检查一下 ,这个key如果设置了过期时间那么是否过期了?如果过期了此时就会删除,不会给你返回任何东西。

并不是key到时间就被删除掉,而是你查询这个key的时候,redis再懒惰的检查一下

通过上述两种手段结合起来,保证过期的key一定会被干掉。

所以说用了上述2种策略后,下面这种现象就不难解释了:数据明明都过期了,但是还占有着内存

内存淘汰策略

==========

这个问题可能有小伙伴们遇到过,放到Redis中的数据怎么没了?

因为Redis将数据放到内存中,内存是有限的,比如redis就只能用10个G,你要是往里面写了20个G的数据,会咋办?当然会干掉10个G的数据,然后就保留10个G的数据了。那干掉哪些数据?保留哪些数据?当然是干掉不常用的数据,保留常用的数据了

Redis提供的内存淘汰策略有如下几种:

  1. noeviction 不会继续服务写请求 (DEL 请求可以继续服务),读请求可以继续进行。这样可以保证不会丢失数据,但是会让线上的业务不能持续进行。这是默认的淘汰策略。

  2. volatile-lru 尝试淘汰设置了过期时间的 key,最少使用的 key 优先被淘汰。没有设置过期时间的 key 不会被淘汰,这样可以保证需要持久化的数据不会突然丢失。(这个是使用最多的)

  3. volatile-ttl 跟上面一样,除了淘汰的策略不是 LRU,而是 key 的剩余寿命 ttl 的值,ttl 越小越优先被淘汰。

  4. volatile-random 跟上面一样,不过淘汰的 key 是过期 key 集合中随机的 key。

  5. allkeys-lru 区别于 volatile-lru,这个策略要淘汰的 key 对象是全体的 key 集合,而不只是过期的 key 集合。这意味着没有设置过期时间的 key 也会被淘汰。

  6. allkeys-random 跟上面一样,不过淘汰的策略是随机的 key。allkeys-random 跟上面一样,不过淘汰的策略是随机的 key。

持久化策略

=========

Redis的数据是存在内存中的,如果Redis发生宕机,那么数据会全部丢失,因此必须提供持久化机制。

Redis 的持久化机制有两种,第一种是快照(RDB),第二种是 AOF 日志。快照是一次全量备份,AOF 日志是连续的增量备份。快照是内存数据的二进制序列化形式,在存储上非常紧凑,而 AOF 日志记录的是内存数据修改的指令记录文本。AOF 日志在长期的运行过程中会变的无比庞大,数据库重启时需要加载 AOF 日志进行指令重放,这个时间就会无比漫长。所以需要定期进行 AOF 重写,给 AOF 日志进行瘦身。

RDB是通过Redis主进程fork子进程,让子进程执行磁盘 IO 操作来进行 RDB 持久化,AOF 日志存储的是 Redis 服务器的顺序指令序列,AOF 日志只记录对内存进行修改的指令记录。即RDB记录的是数据,AOF记录的是指令

RDB和AOF到底该如何选择?

  1. 不要仅仅使用 RDB,因为那样会导致你丢失很多数据,因为RDB是隔一段时间来备份数据

  2. 也不要仅仅使用 AOF,因为那样有两个问题,第一,通过 AOF 做冷备没有RDB恢复速度快; 第二,RDB 每次简单粗暴生成数据快照,更加健壮,可以避免 AOF 这种复杂的备份和恢复机制的 bug

  3. 用RDB恢复内存状态会丢失很多数据,重放AOP日志又很慢。Redis4.0推出了混合持久化来解决这个问题。将 rdb 文件的内容和增量的 AOF 日志文件存在一起。这里的 AOF 日志不再是全量的日志,而是自持久化开始到持久化结束的这段时间发生的增量 AOF 日志,通常这部分 AOF 日志很小。于是在 Redis 重启的时候,可以先加载 rdb 的内容,然后再重放增量 AOF 日志 《一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》无偿开源 威信搜索公众号【编程进阶路】 就可以完全替代之前的 AOF 全量文件重放,重启效率因此大幅得到提升。

缓存雪崩和缓存穿透

缓存雪崩是什么?

Redis的n种妙用,分布式锁,分布式唯一id相关推荐

  1. 百度开源的一款分布式高性能的唯一ID生成器,非常强大!

    来源:https://lilinchao.com/archives/1226.html 一.UidGenerator是什么 UidGenerator是百度开源的一款分布式高性能的唯一ID生成器,是基于 ...

  2. Redis的n种妙用,分布式锁,分布式唯一id,消息队列,抽奖……

    介绍 redis是键值对的数据库,常用的五种数据类型为字符串类型(string),散列类型(hash),列表类型(list),集合类型(set),有序集合类型(zset) Redis用作缓存,主要两个 ...

  3. Redis的N种妙用,不仅仅是缓存

    redis是键值对的数据库,常用的五种数据类型为字符串类型(string),散列类型(hash),列表类型(list),集合类型(set),有序集合类型(zset) Redis用作缓存,主要两个用途: ...

  4. 分布式锁+分布式事务+分布式缓存

    1.分布式缓存 1.1高并发下的分布式缓存 我们先从最开始的来说,我们现在一般都是B/S架构,一般都是中间挂一个服务器,后面有一个数据库.如下图: 如果客户端的访问量很大的话,那对于后端的服务来说就有 ...

  5. 缓存-分布式锁-分布式锁原理与使用

    怎么来实现这个分布式锁呢? 方案一: 这种设计方案,会出现一个问题:当线程获取到锁,然后执行完业务逻辑,准备去删除锁的时候,突然服务器宕机了,会导致这个锁一直存在,得不到释放,会造成死锁的情况. 解决 ...

  6. Zookeeper后端开发工具Curator的使用 | Curator对节点的增删改查 | ACL权限控制 | 分布式锁 | 分布式计数器 | 附带最新版本下载

    前言 Curator是Apache开源的一个Java工具类,通过它操作Zookeeper会变得极度舒适! 前置条件:已掌握的基本操作,比如在后台可以增减节点.ACL权限设置等. 1.Zookeeper ...

  7. 分布式面试全家桶:分布式事务+分布式锁+分布式缓存+分布式面试题+分布式项目

    一.分布式事务 1.分布式事务简介 2.Seata简介 3.Seata-Server安装 4.Seata配置Nacos注册中心和配置中心 5.Seata-AT模式   6.XA协议 7.Seata整体 ...

  8. 【融云分析】如何实现分布式场景下唯一 ID 生成?

    ◀背景▶ 对于一套分布式部署的 IM 系统,要求每条消息的 ID 要保证在集群中全局唯一且按生成时间有序排列.如何快速高效的生成消息数据的唯一 ID ,是影响系统吞吐量的关键因素.那么,融云是如何做到 ...

  9. js生成唯一id_【融云分析】如何实现分布式场景下唯一 ID 生成?

    ◀背景▶ 对于一套分布式部署的 IM 系统,要求每条消息的 ID 要保证在集群中全局唯一且按生成时间有序排列.如何快速高效的生成消息数据的唯一 ID ,是影响系统吞吐量的关键因素.那么,融云是如何做到 ...

最新文章

  1. oracle-imp导入小错filesize设置
  2. Linux命令cat
  3. UICollectionView入门--使用系统UICollectionViewFlowLayout布局类
  4. 使用PHP CURL的POST数据
  5. saml2_向SAML响应中添加自定义声明–(如何为WSO2 Identity Server编写自定义声明处理程序)...
  6. python输入input数组_python怎么输入数组
  7. 世上最简单的mysql_史上最简单安装MySQL教程
  8. Python数据分析学习笔记:Python数据可视化入门
  9. python中的random模块_Python中的random模块
  10. 使用React搭建初始化环境(React入门)
  11. 可行性研究报告模板 Shane版
  12. 国内外php主流开源cms汇总
  13. 以半桥驱动芯片FAN73933为例说明自举原理
  14. 中国莽草酸行业市场深度调查报告(2022版)
  15. 编译工具make、gmake、cmake、nmake和Dmake的区别
  16. SystemC自带example的pipe研习
  17. 【Educoder作业】绘制炸弹轨迹 I——绘制一个坐标点
  18. 如何使用 Java Servlet 处理 HTML 表单数据
  19. webuploader 实现图片批量上传
  20. CISP-DSG证书有效期多久?是否需要续证?

热门文章

  1. 详解设计模式之装饰者模式[以奶茶为案例介绍]
  2. Java基础(四)(根据尚硅谷宋红康老师Java基础第四部分)(重点)
  3. 我的世界命令计算机,我的世界有哪些指令?电脑版指令大全
  4. python设置画布的大小_Python tkinter框架画布调整大小
  5. 4314: 猴子吃桃子
  6. 网站端服务器返回错误8114,ROLLBACK TRANSACTION请求在SQL Server之后没有对应的BEGIN TRANSACTION错误8114...
  7. 学计算机激励标语口号,标语口号大全 计算机班级口号霸气
  8. Android Jpush极光推送
  9. 用NuGet管理好你的包包
  10. C#中的TemplateMethod模式