当我们在开发过程中需要用到分布式缓存 Redis 的时候, 我们首先要明白缓存在系统中用来做什么?
少量数据存储, 高速读写访问. 通过数据全部 in-momery 的方式来保证高速访问, 同时提供数据落地的功能, 实际这正是 Redis 最主要的适用场景.
海量数据存储, 分布式系统支持, 数据一致性保证, 方便的集群节点添加 / 删除. Redis3.0 以后开始支持集群, 实现了半自动化的数据分片, 不过需要 smart-client 的支持.
华为云分布式缓存 Redis, 目前已经进入 Redis5.0 公测阶段, 公测阶段注册既能免费使用, 那么我们在开发过程中需要用到 Redisde 时候, 需要明白哪些问题呢?
下面小编给大家一一道来.
一, 为什么使用 Redis?
我觉得在项目中使用 Redis, 主要是从两个角度去考虑: 性能和并发.
当然, Redis 还具备可以做分布式锁等其他功能, 但是如果只是为了分布式锁这些其他功能, 完全还有其他中间件, 如 ZooKpeer 等代替, 并不是非要使用 Redis. 因此, 这个问题主要从性能和并发两个角度去答.
性能:
如下图所示, 我们在碰到需要执行耗时特别久, 且结果不频繁变动的 SQL, 就特别适合将运行结果放入缓存. 这样, 后面的请求就去缓存中读取, 使得请求能够迅速响应.
题外话: 忽然想聊一下这个迅速响应的标准. 根据交互效果的不同, 这个响应时间没有固定标准.
不过曾经有人这么告诉我:"在理想状态下, 我们的页面跳转需要在瞬间解决, 对于页内操作则需要在刹那间解决. 另外, 超过一弹指的耗时操作要有进度提示, 并且可以随时中止或取消, 这样才能给用户最好的体验."
那么瞬间, 刹那, 一弹指具体是多少时间呢?
根据《摩诃僧祗律》记载:
一刹那者为一念, 二十念为一瞬, 二十瞬为一弹指, 二十弹指为一罗预, 二十罗预为一须臾, 一日一夜有三十须臾.
那么, 经过周密的计算, 一瞬间为 0.36 秒, 一刹那有 0.018 秒, 一弹指长达 7.2 秒.
并发:
如下图所示, 在大并发的情况下, 所有的请求直接访问数据库, 数据库会出现连接异常.
这个时候, 就需要使用 Redis 做一个缓冲操作, 让请求先访问到 Redis, 而不是直接访问数据库.
二, 使用 Redis 有什么缺点?
大家用 Redis 这么久, 这个问题是必须要了解的, 基本上使用 Redis 都会碰到一些问题, 常见的也就几个.
回答主要是四个问题:
◆缓存和数据库双写一致性问题
◆缓存雪崩问题
◆缓存击穿问题
◆缓存的并发竞争问题
这四个问题, 我个人觉得在项目中是常遇见的.
三, 单线程的 Redis 为什么这么快?
这个问题是对 Redis 内部机制的一个考察. 根据我的面试经验, 很多人都不知道 Redis 是单线程工作模型. 所以, 这个问题还是应该要复习一下的.
回答主要是以下三点:
◆纯内存操作
◆单线程操作, 避免了频繁的上下文切换
◆采用了非阻塞 I/O 多路复用机制
题外话: 我们现在要仔细的说一说 I/O 多路复用机制, 因为这个说法实在是太通俗了, 通俗到一般人都不懂是什么意思.
打一个比方: 小曲在 S 城开了一家快递店, 负责同城快送服务. 小曲因为资金限制, 雇佣了一批快递员, 然后小曲发现资金不够了, 只够买一辆车送快递.
经营方式一:
客户每送来一份快递, 小曲就让一个快递员盯着, 然后快递员开车去送快递.
慢慢的小曲就发现了这种经营方式存在下述问题:
◆几十个快递员基本上时间都花在了抢车上了, 大部分快递员都处在闲置状态, 谁抢到了车, 谁就能去送快递.
◆随着快递的增多, 快递员也越来越多, 小曲发现快递店里越来越挤, 没办法雇佣新的快递员了.
◆快递员之间的协调很花时间.
综合上述缺点, 小曲痛定思痛, 提出了下面的经营方式.
经营方式二:
小曲只雇佣一个快递员. 然后呢, 客户送来的快递, 小曲按送达地点标注好, 然后依次放在一个地方.
最后, 那个快递员依次的去取快递, 一次拿一个, 然后开着车去送快递, 送好了就回来拿下一个快递.
上述两种经营方式对比, 是不是明显觉得第二种, 效率更高, 更好呢?
在上述比喻中:
◆每个快递员→每个线程
◆每个快递→每个 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 等多路复用函数库, 大家可以自行去了解.
当然以上三点只是皮毛而已, 但却是最基本的, 如果想了解更多详细的操作细则, 可以去华为云官方论坛与各路大手子交流经验, 大咖云集必能学到很多东西.
来源: http://www.jianshu.com/p/5942a6269a44