文章原创于公众号:程序猿周先森。本平台不定时更新,喜欢个人文章,欢迎关注个人微信公众号。面试
实际项目开发中如今没法逃避的一个问题就是缓存问题,而缓存问题也是面试必问知识点之一,若是面试官好一点可能会简单的问你二八定律或者热数据和冷数据,可是若是问的深刻一点可能就会问到缓存更新、降级、预热、雪崩、穿透等问题,而这些问题可能会拦下大部分平时不怎么关注缓存的朋友,这些问题实际上都和缓存服务器息息相关,咱们平常中常用的缓存服务器通常有两种:Redis和Memcached。本篇开始正式进入Redis系列文章,本篇主要讲讲Redis使用单线程为什么速度还能如此之快?redis
既然谈到缓存服务器有两种,那咱们为什么要选择Redis呢?Redis与Memcached二者之间有何区别呢?数据库
Redis 和 Memcached 的区别缓存
Redis是一个key-value存储系统。它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操做,并且这些操做都是原子性的。在此基础上,redis支持各类不一样方式的排序。为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操做写入追加的记录文件,而且在此基础上实现了主从同步。简单来讲 Redis 就是一个数据库,不过与传统数据库不一样的是 Redis 的数据是存在内存中的,因此存写速度很是快,所以 Redis 被普遍应用于缓存方向。Redis 也常常用来作分布式锁。Redis 提供了多种数据类型来支持不一样的业务场景。除此以外,Redis 支持事务 、持久化、LUA 脚本、LRU 驱动事件、多种集群方案。Redis中经常使用的数据类型实际上只有5种:String、Hash、List、Set、ZSet,咱们能够先看下这五种基本数据类型的用法:服务器
String微信
String 数据结构是简单的 Key-Value 类型,Value 能够是string或者数字。常规 Key-Value 缓存应用;常规计数:博客数,阅读数等。网络
Hash数据结构
Hash 特别适合用于存储对象。多线程
List并发
链表是 Redis 最重要的数据结构之一,Redis List 为一个双向链表,支持反向查找和遍历,更方便操做,不过带来了额外的内存开销。
Set
Set 其实和List都是列表的选项,Set 是能够自动去重的。当须要存储一个不出现重复数据的列表数据,Set 是一个最好的选择。你能够基于 Set 轻易实现交集、并集、差集的操做。
Sorted Set
Sorted Set 相比Set增长了一个权重参数 Score,使得集合中的元素可以按 Score 进行有序排列。
数据库工做模式若是按照存储方式进行划分能够分红两种:硬盘数据库和内存数据库。Redis读写数据之因此如此之快实际上就是因为Redis将数据存储在内存中,因此在读写数据时不会受到硬盘I/O速度限制,因此读写速度天然很快。而硬盘数据库则是在内存中储存一个索引,而后根据索引去硬盘中查询对应的值,因此效率确定会相对更慢。
Redis基于内存采用单线程单进程模型的Key-Value数据库,通过官方测试每秒查询次数能够高达100000+,那为何Redis如此快呢?最关键的一点其实刚才已经提到过,由于Redis彻底基于内存,Redis接收到的大部分请求都是直接操做内存就能够完成的,因此处理请求很是迅速,并且Redis中使用单线程,避免了没必要要的上下文切换和竞争锁机制,也不会出现频繁切换线程致使CPU消耗,不会存在多线程的死锁等一系列问题。在Redis中使用多路复用I/O模型,而不是非阻塞I/O,非阻塞I/O以前在Nginx提到过,因此咱们不重复介绍,咱们重点看看多路I/O复用模型。
多路I/O复用模型其实是使用select、poll、epoll同时监听多个流的I/O事件,在无I/O事件时也就是空闲状态下会将线程阻塞,当有I/O事件须要处理时,线程就是从阻塞状态下唤醒,而后使用epoll轮询一遍全部发生I/O事件的流。多路复用实际上还就是说多个网络链接复用同一个线程,采用多路I/O复用技术可让单个进程高效的处理多个链接请求,且Redis在内存中对数据进行操做,因此数据操做速度很是快,因此速度不会受到瓶颈,因此Redis才能够具备很高的吞吐量及性能。Redis的瓶颈主要来源于机器内存或网络带宽,CPU不是Redis的瓶颈所在,再加上单线程更易于实现,因此瓜熟蒂落Redis采用单线程的方式,可是使用单线程的方式是没法发挥多核CPU的优点的,好比在进行比较耗时的操做时会使得Redis并发量降低,由于单线程因此某一时刻只能处理一个操做,因此执行耗时操做会致使并发量的降低,有一个简单的解决方案就是在多核CPU下能够单机开多个Redis实例来解决这个问题。
欢迎关注公众号:程序猿周先森。