redis单线程为什么慢

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: redis单线程为什么慢

本文分为以下几个部分说明介绍redis单线程

1.redis为何使用单线程

2.redis使用单线程为何性能那么高

3.redis哪些功能不是单线程

一.redis为何使用单线程

现在的cpu都是多核多线程的架构,理论上程序上开多个线程运行,就代表能有多个线程同时并发的在运行,N个线程运行的总时间等于运行时间最长的任务;单线程运行的总时间是每个任务运行时间之和。

举个例子:

有三个任务

任务 运行时间
任务1 10s
任务2 20s
任务3 15s

单线程执行的总时间:45s   多线程执行的总时间:20s

所以随着运行的线程数增多,系统的吞吐量也会上升。但是实际情况往往是这样:随着线程数的增加,吞吐量是会先上涨,后面,即使再增加线程数,吞吐量也是不会再上涨了,趋于平稳状态。

为什么会这样呢?

多线程运行时,通常都会访问一些共享资源,这些资源同时只能一个线程访问与修改,修改完后才能让别的线程访问,这就导致了多线程并发运行,变成了单线程串行运行,多线程都在排队等待,而且还有上下文切换的开销。这就导致了即使增加再多的线程也无法增加吞吐量。

举个例子:

假如redis是多线程处理请求的,一个线程从list集合LPOP获取元素,需要对集合的长度-1;有另一个线程从list集合LPUSH获取元素,需要对集合的长度+1;两个线程需要对共享资源(集合长度)访问,对共享资源的访问同时只能是一个线程,这样多线程就变成串行操作。

并发编程中,对共享资源的访问都是比较难处理的,如果只是简单的加一个粗粒度的锁来保证,这就会导致性能上不去的情况。

所以采用多线程会导致访问共享资源问题很难处理,而且会导致代码比较复杂,难易维护,所以redis采用了单线程模型。

二.redis使用单线程为何性能那么高

官方数据:redis单线程模型可以达到10Wtps/s。

我觉得redis那么快主要有两个原因:

  1. 数据都存放在内存,高效的数据结构,比如hash列表,通过计算key的hash值就能快速定位到存放位置。
  2. io多路复用的应用,一个线程就可以高效的管理多个连接。

redis的单线程操作是指:网络 IO和键值对读写是由一个线程来完成的,所以下面总结介绍一下阻塞io和非阻塞io的区别。以及非阻塞io在多路复用的应用。

  • 阻塞io

阻塞io模型下,由于调用socket的读写方法都会阻塞,一直等待有对端有数据传输,才会访问,所以一个线程只能处理一条连接,所以需要创建很多个线程来处理连接;这种模式可以由线程池来优化,但是也是治标不治本,因为很多线程其实是空闲不工作的。

  • 非阻塞io

非阻塞的模式下,调用socket的读写方法,如果没有数据可读,就会立即返回,线程可以做其他事情;如果有数据可读,就会从内核把数据拷贝到应用程序,完成数据的获取。

  • 多路复用

在多路复用的模式下,通常是( select/epoll模式  ),对建立好的连接,可以向操作系统订阅可读可写事件,当连接可读写时,操作系统就会发出通知。线程就可以处理这个连接的数据读写。

对redis来说,会向select/epoll注册读写事件和连接建立事件,系统内核一旦监听到有对应的事件发生,就会把事件放到一个队列中,由redis线程获取队列的事件处理,redis根据不同的事件会调用不同的处理器处理。

三.redis哪些功能不是单线程

redis是单线程处理客户端请求的,如果单线程处理的操作是比较耗时的,就会导致客户端的请求没办法处理,所以redis耗时的操作不能由处理客户端请求的线程来处理。

有哪些是耗时的请求呢?

持久化(自动生成RDB,客户端的bgsave命令)、异步删除(客户端异步删除命令)、集群数据同步(主节点和从节点的数据同步)

这些功能,都是主进程fork出子进程来进行操作的,不会影响到客户端请求的正常处理。当然,redis的处理客户端的请求也会存在耗时操作,导致其他客户端的请求无法处理,下节我们来看看redis有哪些耗时的操作,以及怎么优化。

四.总结

我们重点学习了 Redis 关于单线程的三个问题:“Redis 为何使用单线程?”“使用单线程为何性能那么高?”“哪些功能不是单线程?”

现在,我们知道了,Redis 单线程是指它网络 IO和键值对读写都是一个线程完成的,而 采用单线程的一个核心原因是避免多线程开发的访问共享资源的问题。单线程的 Redis 也能获得 高性能,多路复用的 IO 模型+高效的数据结构有密切相关,因为这避免了建立新连接和io读写方法 阻塞问题。

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
3天前
|
存储 缓存 NoSQL
Redis单线程已经很快了6.0引入多线程
Redis单线程已经很快了6.0引入多线程
35 3
|
3天前
|
NoSQL 数据处理 调度
【Redis深度专题】「踩坑技术提升」探索Redis 6.0为何必须启用多线程以提升性能与效率
【Redis深度专题】「踩坑技术提升」探索Redis 6.0为何必须启用多线程以提升性能与效率
293 0
|
3天前
|
存储 NoSQL Redis
深入浅出Redis(二):Redis单线程模型与通信流程
深入浅出Redis(二):Redis单线程模型与通信流程
|
3天前
|
NoSQL Redis
Redis 线程模型
Redis 线程模型
|
3天前
|
存储 缓存 NoSQL
为什么Redis使用单线程 性能会优于多线程?
在计算机领域,性能一直都是一个关键的话题。无论是应用开发还是系统优化,我们都需要关注如何在有限的资源下,实现最大程度的性能提升。Redis,作为一款高性能的开源内存数据库,因其出色的单线程性能而备受瞩目。那么,为什么Redis使用单线程性能会优于多线程呢?
25 1
|
3天前
|
存储 消息中间件 缓存
Redis是否为单线程?
【2月更文挑战第6天】
43 1
Redis是否为单线程?
|
3天前
|
缓存 NoSQL 安全
Redis 新特性篇:多线程模型解读
Redis 新特性篇:多线程模型解读
56 5
|
3天前
|
存储 缓存 NoSQL
Redis 数据结构+线程模型+持久化+内存淘汰+分布式
Redis 数据结构+线程模型+持久化+内存淘汰+分布式
313 0
|
缓存 NoSQL JavaScript
Redis之线程IO模型
Redis之线程IO模型
581 0
|
3天前
|
负载均衡 监控 NoSQL
Redis的几种主要集群方案
【5月更文挑战第15天】Redis集群方案包括主从复制(基础,读写分离,手动故障恢复)、哨兵模式(自动高可用,自动故障转移)和Redis Cluster(官方分布式解决方案,自动分片、容错和扩展)。此外,还有Codis、Redisson和Twemproxy等工具用于代理分片和负载均衡。选择方案需考虑应用场景、数据量和并发需求,权衡可用性、性能和扩展性。
29 2