专栏首页Node开发单线程Redis性能为何如此之高?

单线程Redis性能为何如此之高?

实际项目开发中现在无法逃避的一个问题就是缓存问题,而缓存问题也是面试必问知识点之一,如果面试官好一点可能会简单的问你二八定律或者热数据和冷数据,但是如果问的深入一点可能就会问到缓存更新、降级、预热、雪崩、穿透等问题,而这些问题可能会拦下大部分平时不怎么关注缓存的朋友,这些问题实际上都和缓存服务器息息相关,我们日常中经常使用的缓存服务器一般有两种:RedisMemcached。本篇开始正式进入Redis系列文章,本篇主要讲讲Redis使用单线程为何速度还能如此之快?

既然谈到缓存服务器有两种,那我们为何要选择Redis呢?RedisMemcached两者之间有何区别呢?

Redis 和 Memcached 的区别

  • Redis支持常见数据类型:Redis 不仅仅支持简单的 key/value 类型的数据,同时还提供string(字符串)、list(链表)、set(集合)、zset(有序集合)和hash(哈希类型)等数据结构的存储。而Memcache 只支持简单的数据类型 String
  • Redis 支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用,而 Memecache 把数据全部存在内存之中。
  • 集群模式:Memcached 没有原生的集群模式,需要依靠客户端来实现往集群中分片写入数据;但是 Redis 目前是原生支持 Cluster 模式的。
  • Memcached 是多线程,非阻塞 IO 复用的网络模型;Redis 使用单线程的多路 IO 复用模型。

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种:StringHashListSetZSet,我们可以先看下这五种基本数据类型的用法:

String

常用命令:set、get、decr、incr、mget 等。

String 数据结构是简单的 Key-Value 类型,Value 可以是string或者数字。常规 Key-Value 缓存应用;常规计数:博客数,阅读数等。

Hash

常用命令:hget、hset、hgetall 等。

Hash 特别适合用于存储对象。

List

常用命令:lpush、rpush、lpop、rpop、lrange 等。

链表是 Redis 最重要的数据结构之一,Redis List 为一个双向链表,支持反向查找和遍历,更方便操作,不过带来了额外的内存开销。

Set

常用命令:sadd、spop、smembers、sunion 等。

Set 其实和List都是列表的选项,Set 是可以自动去重的。当需要存储一个不出现重复数据的列表数据,Set 是一个最好的选择。你可以基于 Set 轻易实现交集、并集、差集的操作。

Sorted Set

常用命令:zadd、zrange、zrem、zcard 等。

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复用模型实际上是使用selectpollepoll同时监听多个流的I/O事件,在无I/O事件时也就是空闲状态下会将线程阻塞,当有I/O事件需要处理时,线程就是从阻塞状态下唤醒,然后使用epoll轮询一遍所有发生I/O事件的流。多路复用实际上还就是说多个网络连接复用同一个线程,采用多路I/O复用技术可以让单个进程高效的处理多个连接请求,且Redis在内存中对数据进行操作,所以数据操作速度非常快,所以速度不会受到瓶颈,所以Redis才可以具有很高的吞吐量及性能。Redis的瓶颈主要来源于机器内存或网络带宽,CPU不是Redis的瓶颈所在,再加上单线程更易于实现,所以顺理成章Redis采用单线程的方式,但是使用单线程的方式是无法发挥多核CPU的优势的,比如在进行比较耗时的操作时会使得Redis并发量下降,因为单线程所以某一时刻只能处理一个操作,所以执行耗时操作会导致并发量的下降,有一个简单的解决方案就是在多核CPU下可以单机开多个Redis实例来解决这个问题。

本文分享自微信公众号 - 程序猿周先森(zhanyue_org),作者:逆月翎

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-09-16

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Redis系列总结--这几点你会了吗?

    前面几篇已经对Redis中几个关键知识点做了介绍,本篇主要对Redis系列做一下总结以及对Redis中常见面试题简单进行介绍一下。首先我们对前面几篇谈到的Red...

    逆月翎
  • Redis缓存击穿、缓存穿透、缓存雪崩

    上篇文章谈到了Redis分布式锁,实际上就是为了解释为什么做缓存采用Redis而不使用map/guava。缓存分为本地缓存和分布式缓存。以 Java 为例,使...

    逆月翎
  • Redis分片机制

    前两篇文章对Redis主从复制和主从切换的知识点进行了介绍,但是也很明显的有一点小弊端:

    逆月翎
  • 这些 Redis 面试题虽然简单,但是面试常常问到

    Redis应该算面试中必问的一个知识点,但是发现很多童鞋并不熟悉这块,这篇就常见的一些问题做一些整理,有不对的地方欢迎留言指正!

    咸鱼学Python
  • Redis的高级特性一览

    慢查询只记录Redis在处理存储的时间计数(图中的3步骤),并不包含网络通信时间和排队时间,所以客户端超时分析时要综合每个因素。

    全菜工程师小辉
  • Redis高频面试题

    Redis,全称:Remote Dictionary Server,是一个基于内存的高性能key-value数据库,是应用服务提高效率和性能必不可少的一部分,因...

    小闫同学啊
  • 为什么要用Redis

    最近阅读了《Redis开发与运维》,非常不错。这里对书中的知识整理一下,方便自己回顾一下Redis的整个体系,来对相关知识点查漏补缺。

    大愚
  • 有了它,Redis不再是你技术面试中的阻碍

    Redis在互联网技术存储方面使用非常广泛,几乎所有的后端技术面试官都要在Redis的使用和原理方面对求职小伙伴们进行各种刁难,特别是那些优秀的、竞争激烈的大型...

    博文视点Broadview
  • 大厂和初创公司都在用!Redis好在哪?终于有人讲明白了

    Redis从一个不为人熟知、只有少量应用的崭新数据库,逐渐变成了内存数据库领域的事实标准。时至今日,经过大量的实践应用,Redis简洁高效、安全稳定的特性已经深...

    华章科技
  • 大厂和初创公司都在用!Redis好在哪?终于有人讲明白了

    Redis从一个不为人熟知、只有少量应用的崭新数据库,逐渐变成了内存数据库领域的事实标准。时至今日,经过大量的实践应用,Redis简洁高效、安全稳定的特性已经深...

    用户5548425

扫码关注云+社区

领取腾讯云代金券