文章原创于公众号:程序猿周先森。本平台不定时更新,喜欢我的文章,欢迎关注我的微信公众号。

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

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

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

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

欢迎关注公众号:程序猿周先森。

单线程Redis性能为何如此之高?的更多相关文章

  1. 【转载】单线程Redis性能为何如此之高?

    Redis的优势 性能高不仅跟线程模型有关,它有很多原因,主要有如下3点: 基于内存: 单线程,但IO多路复用的利用率高: 数据结构为高性能优化. 下面分别阐述. Redis的优势:基于内存 性能高低 ...

  2. redis和memcached有什么区别?redis的线程模型是什么?为什么单线程的redis比多线程的memcached效率要高得多(为什么redis是单线程的但是还可以支撑高并发)?

    1.redis和memcached有什么区别? 这个事儿吧,你可以比较出N多个区别来,但是我还是采取redis作者给出的几个比较吧 1)Redis支持服务器端的数据操作:Redis相比Memcache ...

  3. Redis性能问题排查解决手册(七)

     阅读目录: 性能相关的数据指标 内存使用率used_memory 命令处理总数total_commands_processed 延迟时间 内存碎片率 回收key 总结 性能相关的数据指标 通过Red ...

  4. Redis性能问题排查解决手册

    转自:http://www.cnblogs.com/mushroom/p/4738170.html 阅读目录: 性能相关的数据指标 内存使用率used_memory 命令处理总数total_comma ...

  5. redis性能调优笔记(can not get Resource from jedis pool和jedis connect time out)

    对这段时间redis性能调优做一个记录. 1.单进程单线程 redis是单进程单线程实现的,如果你没有特殊的配置,redis内部默认是FIFO排队,即你对redis的访问都是要在redis进行排队,先 ...

  6. 关于redis性能问题分析和优化

    一.如何查看Redis性能 info命令输出的数据可以分为10个分类,分别是: server,clients,memory,persistence,stats,replication,cpu,comm ...

  7. Redis(二十一):Redis性能问题排查解决手册(转)

    性能相关的数据指标 通过Redis-cli命令行界面访问到Redis服务器,然后使用info命令获取所有与Redis服务相关的信息.通过这些信息来分析文章后面提到的一些性能指标. info命令输出的数 ...

  8. Redis性能调优

    Redis性能调优 尽管Redis是一个非常快速的内存数据存储媒介,也并不代表Redis不会产生性能问题.前文中提到过,Redis采用单线程模型,所有的命令都是由一个线程串行执行的,所以当某个命令执行 ...

  9. 阅读之Redis性能

    Redis作为一种KV缓存服务器,有着极高的性能,相对于memcache,Redis支持更多中数据类型,因此在业界广泛应用. Redis为什么快: 数据是存储在内存中的. Redis是单线程的. 将数 ...

随机推荐

  1. AVL树(二叉平衡树)详解与实现

    AVL树概念 前面学习二叉查找树和二叉树的各种遍历,但是其查找效率不稳定(斜树),而二叉平衡树的用途更多.查找相比稳定很多.(欢迎关注数据结构专栏) AVL树是带有平衡条件的二叉查找树.这个平衡条件必 ...

  2. 使用Sigar做后台服务器管理时,遇到的linux上的问题

    首先是线下猛如虎,线上惨不忍赌........ 问题的出处是: function change() { /*获取cpu*/ $.ajax({ url: "http://localhost:8 ...

  3. Spring自定义属性编辑器及原理解释.md

    bean的自动装配解释 手动解决方式 自动注入解决方式 bean的自动装配解释 之前有构造注入和设值注入,但是也是手动的 autowire ="byname" 这里要注意自动装配的 ...

  4. pycharm使用教程

    https://www.cnblogs.com/tsingke/p/7392800.html

  5. 一块钱哪里去了?--java浮点型背后的故事

    有这样一道智力题:三人住旅馆,老板娘说30元她们付钱后进去了,老板娘想起今天是特价25元,就叫伙计拿5元还给三位顾客,可伙计藏了2元,给了她们3元,这样她们每人得1元,就是说每人付了9元,那3*9=2 ...

  6. 一、mysql数据库,忘记密码怎么处理及处理过程中遇见的问题

    1.输入cmd命令打开控制台: 2.进入mysql.exe所在的路径: 3.执行mysqld --skip-grant-tables(注意:在输入此命令之前先在任务管理器中结束mysqld.exe进程 ...

  7. 提升RabbitMQ消费速度的一些实践

    RabbitMQ是一个开源的消息中间件,自带管理界面友好.开发语言支持广泛.没有对其它中间件的依赖,而且社区非常活跃,特别适合中小型企业拿来就用.这篇文章主要探讨提升RabbitMQ消费速度的一些方法 ...

  8. codeforces 591 E. Three States(bfs+思维)

    题目链接:http://codeforces.com/contest/591/problem/E 题意:有3个数字表示3个城市,每种城市都是相互连通的,然后不同种的城市不一定联通,'.'表示可以建设道 ...

  9. poj 1797Heavy Transportation(dijkstra变形)

    题目链接:http://poj.org/problem?id=1797 题意:有n个城市,m条道路,在每条道路上有一个承载量,现在要求从1到n城市最大承载量,而最大承载量就是从城市1到城市n所有通路上 ...

  10. SQLi_LABS less5: GET-Double Injection - Single Quotes - String

    目录 前言 几种可能的注入方式 补充的相关知识点 前言 最近开始用SQLi_LABS学习注入,刚开始有点摸不到头脑,索性把看到的知识点记录下来,很多细节是看别人博客学的,就直接给链接了,在此向这些作者 ...