Timetombs

泛义的工具是文明的基础,而确指的工具却是愚人的器物

66h / 117a
,更新于 2024-09-22T17:55:09Z+08:00 by   d729f8f

[Redis] 运行时架构

版权声明 - CC BY-NC-SA 4.0

redis自从诞生之处就被称之为单线程的方式实现的,这里的单线程指的是socket read解析执行socket write这四个阶段都是由主线程独自完成的。当然一个redis-server实例并不是只有这一个线程,比如还有执行RDB、AOF、LRU、AOFREWRITE等等后台线程,只是它们的运行不会参与到server的主线程处理client的request这个流程中。

1 主线程

# 启动一个redis的容器,开启AOF
docker run --name redis.test -d redis:6.2 redis-server --appendonly yes

# 进入容器查看
docker exec -it redis.test bash

# 安装包含top命令的工具包
root@4c3c02708a7a:/data# apt update && apt install procps

# 查看redis-server进程的信息
root@4c3c02708a7a:/data# top -H -n 1 -p 1

Threads:   5 total,   0 running,   5 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem :   4260.7 total,   2004.9 free,   1860.5 used,    395.3 buff/cache
MiB Swap:      0.0 total,      0.0 free,      0.0 used.   2180.8 avail Mem 

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
      1 redis     20   0   52952   7048   5632 S   0.0   0.2   0:02.27 redis-server
     14 redis     20   0   52952   7048   5632 S   0.0   0.2   0:00.00 bio_close_file
     15 redis     20   0   52952   7048   5632 S   0.0   0.2   0:00.00 bio_aof_fsync
     16 redis     20   0   52952   7048   5632 S   0.0   0.2   0:00.00 bio_lazy_free
     17 redis     20   0   52952   7048   5632 S   0.0   0.2   0:00.00 jemalloc_bg_thd 

从上面的top结果可以看到除了主线程外,还有bio的三个线程和jemalloc_bg一个线程。

为什么redis选择使用一个主线程处理整个完整的request1?主要原因有一下几点: 

  1. 性能瓶颈在于内存和网络I/O,而不是CPU。
  2. 单线程实现更简单。
  3. 多线程存在的线程切换,加锁导致性能下降。
  4. 多线程带来的实现上的复杂度上升。
  5. 多线程带来的线程不安全问题。

2 I/O线程

得益于I/O Multiplexing(linux上主要是epoll)2提供的高性能I/O,虽然redis-server是单线程,但是性能依然非常优秀。

但是I/O Multiplexing也并不是银弹,其I/O的读写阶段依然是阻塞的,这也是阻碍redis进一步提升性能主要的瓶颈点(socket read解析执行socket write)。所以redis6.0引入了I/O多线程的支持,socket read解析socket write)三部分交由I/O线程取执行,然后主线程只负责执行阶段。

2.1 配置

# 开启
io-threads-do-reads yes
# io线程数
io-threads 4

3 参考

上一篇 : [Redis] benchmark
下一篇 : [Redis] replication