Redis是如何实现高性能的?

Redis到底有多快?

redis到底有多快,可以通过 redis-benchmark 脚本进行基准测试。redis官方的性能基准测试报告

Redis为什么这么快?

redis之所以这么快,其实是一个综合性的结果。而能够支持其高性能的主要有以下几个点:

  • 基于内存redis的数据都保存在内存中,在接收到命令之后可以在微秒的时间单位内获取到数据,并返回给客户端。实际上在说微秒时间内获取到数据指的是请求已经到达服务端,仅仅是指命令的解析与处理可以在微秒的时间范围内完成,所以这里并不包括网络传输时间。因此,实际上在业务使用redis获取数据时,自己打日志发现redis的命令耗时更多的是毫秒范围时间,这主要是因为建立连接以及数据在网络传输占用了大部分时间。

  • *多路复用的IO模型

redis在网络层使用了基于epoll的NIO模型解决了高并发的问题。IO模型的基本理论知识

  • *丰富的数据结构

redis为了快速的根据key找到value,所以提供了一个全局的hash表来哭诉的获取到对应的value。

Redis是如何实现高性能的?

redis中的value其实有8种数据类型,但是比较常用的其实是5种(string、list、hash、set、sorted set | int、bit、[]int)。

Redis是如何实现高性能的?

对应每一种数据类型,redis的底层实现会根据当前的数据来选择不用的数据结构来进行优化,保证一些常用的操作可以在O(1)的时间内完成,但是实际上一些范围操作只能保证在O(N)以内。

Redis是如何实现高性能的?
  • *单线程执行

redis中在获取到所有客户端发来的命令请求后,都是由 一个线程来完成网络IO(协议解析)和键值对的读写,避免了在多线程下并发访问共享资源所带来的的一系列开销。

Redis的性能瓶颈常发生于哪些地方?

既然redis执行命令是单线程执行,那么很容易想到如果当执行命令的线程(主线程),被阻塞了或是执行耗时,那么在该命令之后的所有命令都必须等待当前的命令执行完成之后才会被执行。所以通常来说,redis的性能瓶颈会发生在以下几个地方:

1.大key的操作:无论是读或写,涉及到大key就必然意味着内存和性能的消耗都是较大的;

2.使用了复杂度较高的命令:只要是非O(1),其他如O(N)甚至O(logN)的操作[SORT/SUNION/ZUNIONSTORE]只要N足够大,依然会耗费大量的CPU计算时间,尤其是当宿主机有其他服务在抢资源的时候,延时更为严重;

3.大量的key集中过期:key的过期处理也是由主线程执行,所以大量的key过期时,必然导致主线程在执行过期处理完成之前,无法响应客户端的命令;

4.内存淘汰机制:内存淘汰也是由主线程自己处理的,当redis的内存被耗尽之后,会根据配置的算法【一般是lru或lfu】进行淘汰一定的key。这种情况下自然也会导致主线程无法快速响应客户端;

5.AOF的always刷盘机制:always的刷盘机制,也是有主线程完成的,由于是对磁盘的写操作,必然会对主线程产生一定的影响;

6.fork操作:fork操作是操作系统提供的一个内核API,redis在执行RDB或AOF重写时,会fork一个子线程去完成,并且使用CopyOnWrite的机制节约内存。但是fork出一个子线程的时候需要拷贝一个线程所必要的数据结构以及页表(虚拟内存与物理内存的映射)这个操作主线程必然是阻塞的。相对来说线程的数据结构是相对固定的,但是页表是和实例的大小相关的,实例内存越大,拷贝的页表的耗时也自然更大,延时自然更长;

7.redis所在实例cpu负载过高:负载过高必然导致cpu的争用,当redis的主线程抢占不到cpu执行权时,就只能自我阻塞;此外有一点需要注意的是,如果将redis的主线程与CPU进行核绑时,在fork操作时,fork出的子线程会继承父线程的核绑特性,子线程会与父线程争用同一个CPU;

8.redis的并发过高:虽然redis采用的是epoll的非阻塞IO,但本质上仍然是同步IO,读写客户端的数据只能采用单线程的机制,无法利用CPU的多核;此外,当并发过高,网卡的带宽被占光时,在客户端看来主线程也是被阻塞住了,这种场景通常发生在实例所在的服务器有其他服务消耗了大量的带宽,这种情况下只能将某些服务放到其他地方。另一种极端的情况是redis单机的实例的并发就将网卡打爆了,这种情况一般发生在机器硬件的差距上【CPU和内存都强悍,就是网卡差(可能是老机器遗留)】,这种情况可以选择换硬件、亦或是对redis进行水平拓展,如:哨兵、集群分片。

总的来说其实无非就是三个点:1.主线程等待CPU的执行、2.主线程执行单个命令耗时或是等待某个资源耗时,导致后续的命令被阻塞、3.主线程能处理,但是数据传输拉胯,导致客户端的请求进来慢或响应客户端的数据出去慢。但是CPU不够的情况下是相对少见【因为也就一个主线程可能在不间断的执行,而其他线程都是间歇性执行】,更多的是内存和网络IO上的瓶颈。

参考文章

1.极客时间专栏课-redis核心技术与实战
2.<

Original: https://www.cnblogs.com/zhenjungan/p/16492437.html
Author: zhenjungan
Title: Redis是如何实现高性能的?

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/581880/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • [20220106]ora-00600 kokasgi1.txt

    [20220106]ora-00600 kokasgi1.txt –//上午看了https://www.xifenfei.com/2022/01/2022-first-…

    Linux 2023年6月13日
    095
  • 基于 vite 创建 vue3 全家桶项目(vite + vue3 + tsx + pinia)

    vite 最近非常火,它是 vue 作者尤大神发布前端构建工具,底层基于 Rollup,无论是启动速度还是热加载速度都非常快。vite 随 vue3 正式版一起发布,刚开始的时候与…

    Linux 2023年6月7日
    0116
  • Python3.9.5安装

    基础环境:yum install openssl-devel bzip2-devel expat-devel gdbm-devel readline-devel sqlite-de…

    Linux 2023年6月6日
    098
  • 阿拉德之怒手游超详细图文架设教程

    写在前面 你是否还记得DNF,一天你不小心救了赛丽亚,从此变成了拯救阿拉德大陆的勇士,从此开始冒险之旅,不管你的职业是亲儿子还是下水道,你一直对你玩的角色情有独钟,在一次次刷图PK…

    Linux 2023年6月7日
    084
  • 2020年12月-第01阶段-前端基础-HTML CSS 项目阶段(四)

    品优购项目(四) 1). 详情页 detail.html 常用单词 名称 说明 主体 de_container 面包屑导航 crumb_wrap 产品介绍 product_intr…

    Linux 2023年6月8日
    0108
  • 巧用 JuiceFS Sync 命令跨云迁移和同步数据

    近年来,云计算已成为主流,企业从自身利益出发,或是不愿意被单一云服务商锁定,或是业务和数据冗余,或是出于成本优化考虑,会尝试将部分或者全部业务从线下机房迁移到云或者从一个云平台迁移…

    Linux 2023年6月14日
    0110
  • 【证券从业】金融基础知识-第四章 股票03

    注1:后续学习并整理到第八章,全书完结后再合并成一个笔记进行源文件分享 注2:本章内容巨多,大约分为三篇文章记录消化 posted @2022-06-08 01:28 陈景中 阅读…

    Linux 2023年6月13日
    0108
  • Servlet 学习总结

    Servlet学习笔记 Servlet学习 学习视频为:https://www.bilibili.com/video/BV1Ta4y1H7Vc IDEA的使用 IDEA的简介 ID…

    Linux 2023年6月7日
    070
  • Linux(Deepin)Qt引用ffmpeg的问题(: error: cannot find -l…)

    Linux(Deepin)Qt引用ffmpeg的问题 1、环境介绍 Deepin 20.4 Qt 5.15.1 2、问题描述 从git上找了一个项目打算在Linux练习,顺便熟悉L…

    Linux 2023年6月14日
    0112
  • 项目相关环境docker版安装教程总结

    项目环境docker及docker-compose文档 1、Linux环境介绍 centos7.6 16G以上内存空间(至少8G) 2、静态IP设置 1、找到配置文件 cd /et…

    Linux 2023年6月7日
    087
  • JavaScript json&ajax

    本博客所有文章仅用于学习、研究和交流目的,欢迎非商业性质转载。 博主的文章没有高度、深度和广度,只是凑字数。由于博主的水平不高,不足和错误之处在所难免,希望大家能够批评指出。 博主…

    Linux 2023年6月13日
    098
  • 前端基础之JavaScript(一)

    一、JavaScript概述 1.1 ECMAScript和JavaScript的关系 1996年11月,JavaScript的创造者–Netscape公司,决定将Ja…

    Linux 2023年6月14日
    0111
  • 美团笔试(22.03.19)

    代码题 一共五道代码题,看了前面三道,ac了三道,后面两道题没有时间看,此处将对前三题进行记录总结,后附代码。 题意:给定一组n个商品的价格,下单购买商品时,必须购买前i个商品,即…

    Linux 2023年6月13日
    0105
  • MySQL常见操作

    1.登录 mysql -uroot -p 2.如何查询数据库服务器中所有的 mysql> show databases; 3.如何选中一个数据库进行操作 mysql>u…

    Linux 2023年6月7日
    0107
  • powershell遇到错误即推出的方法

    $ErrorActionPreference = “Stop”; $tcpClient = new-object Net.Sockets.TcpClient…

    Linux 2023年5月28日
    094
  • 机器学习入门笔记02–流行学习与图嵌入理论基础

    核化线性降维 线性降维方法假设从高维空间到低维空间的函数映射是线性的,然而,在不少现实任务中,可能需要非线性映射才能找到恰当的低维嵌入。 流行学习 “流形”…

    Linux 2023年6月6日
    088
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球