综合上述缺点 , 小曲痛定思痛 , 提出了下面的经营方式 。
经营方式二
小曲只雇佣一个快递员 。然后呢 , 客户送来的快递 , 小曲按送达地点标注好 , 然后依次放在一个地方 。
最后 , 那个快递员依次的去取快递 , 一次拿一个 , 然后开着车去送快递 , 送好了就回来拿下一个快递 。
上述两种经营方式对比 , 是不是明显觉得第二种 , 效率更高 , 更好呢?
在上述比喻中:
- 每个快递员→每个线程
- 每个快递→每个 Socket(I/O 流)
- 快递的送达地点→Socket 的不同状态
- 客户送快递请求→来自客户端的请求
- 小曲的经营方式→服务端运行的代码
- 一辆车→CPU 的核数
于是我们有如下结论:
- 经营方式一就是传统的并发模型 , 每个 I/O 流(快递)都有一个新的线程(快递员)管理 。
- 经营方式二就是 I/O 多路复用 。只有单个线程(一个快递员) , 通过跟踪每个 I/O 流的状态(每个快递的送达地点) , 来管理多个 I/O 流 。
下面类比到真实的 Redis 线程模型 , 如图所示:

文章插图
简单来说 , 就是我们的 redis-client 在操作的时候 , 会产生具有不同事件类型的 Socket 。
在服务端 , 有一段 I/O 多路复用程序 , 将其置入队列之中 。然后 , 文件事件分派器 , 依次去队列中取 , 转发到不同的事件处理器中 。
需要说明的是 , 这个 I/O 多路复用机制 , Redis 还提供了 select、epoll、evport、kqueue 等多路复用函数库 , 大家可以自行去了解 。
Redis 的数据类型 , 以及每种数据类型的使用场景
是不是觉得这个问题很基础?我也这么觉得 。然而根据面试经验发现 , 至少百分之八十的人答不上这个问题 。
建议 , 在项目中用到后 , 再类比记忆 , 体会更深 , 不要硬记 。基本上 , 一个合格的程序员 , 五种类型都会用到 。
String
这个没啥好说的 , 最常规的 set/get 操作 , Value 可以是 String 也可以是数字 。一般做一些复杂的计数功能的缓存 。
Hash
这里 Value 存放的是结构化的对象 , 比较方便的就是操作其中的某个字段 。
我在做单点登录的时候 , 就是用这种数据结构存储用户信息 , 以 CookieId 作为 Key , 设置 30 分钟为缓存过期时间 , 能很好的模拟出类似 Session 的效果 。
List
使用 List 的数据结构 , 可以做简单的消息队列的功能 。另外还有一个就是 , 可以利用 lrange 命令 , 做基于 Redis 的分页功能 , 性能极佳 , 用户体验好 。
Set
因为 Set 堆放的是一堆不重复值的集合 。所以可以做全局去重的功能 。为什么不用 JVM 自带的 Set 进行去重?
因为我们的系统一般都是集群部署 , 使用 JVM 自带的 Set , 比较麻烦 , 难道为了一个做一个全局去重 , 再起一个公共服务 , 太麻烦了 。
另外 , 就是利用交集、并集、差集等操作 , 可以计算共同喜好 , 全部的喜好 , 自己独有的喜好等功能 。
Sorted Set
Sorted Set多了一个权重参数 Score , 集合中的元素能够按 Score 进行排列 。
可以做排行榜应用 , 取 TOP N 操作 。Sorted Set 可以用来做延时任务 。最后一个应用就是可以做范围查找 。
Redis 的过期策略以及内存淘汰机制
这个问题相当重要 , 到底 Redis 有没用到家 , 这个问题就可以看出来 。
比如你 Redis 只能存 5G 数据 , 可是你写了 10G , 那会删 5G 的数据 。怎么删的 , 这个问题思考过么?
推荐阅读
- 支气管炎痰中为什么会带血?
- 四川为什么喜欢吃辣椒 四川人是不是很能吃辣
- 为什么茶越贵越有人追
- 推荐丨这辈子一定要去的七大生态旅游景点,你去过几个?
- 香椿为什么要用热水焯一下 香椿焯水为什么变黄
- 粽子为什么煮熟里面是散的 粽子熟了会浮起来吗
- 桃树上黏黏胶有什么作用 桃树表面为什么流胶
- 留尼旺:非洲大部地区都独立了,留尼汪为什么不愿脱离法国独立?
- 为什么说 爱喝茶的男人值得尊重
- 年薪 50 万的人生分水岭,为什么只有不到 3% 的人能跨越?
