众所周知,Redis是一个单线程模型。但大部分人都会误以为Redis服务是只有一个线程,然而并非如此,本文将介绍Redis单线程模型
Redis作为一个单线程模型,指的是Redis执行命令的线程只有一个,但并不代表进程中只有一个线程,也有其他的线程在执行任务,例如有线程负责清除缓存,也有线程负责接收数据等。

谈及线程,我们经常谈到线程安全问题,那redis有没有"线程安全问题"呢?
我们先来简单介绍一下什么是线程安全问题,以两个线程同时自增一个变量为例,虽然看上去我们执行了两次自增操作,但实际上只自增了一次,这就是线程安全问题。
上文可知,redis内部只有一个线程处理命令,也就是说,无论是新增键值对,还是查询redis数据,都需要等待上一个命令结束之后才能轮到自己执行,未执行的命令会在队列中等待,如图片所示:
举个例子,比如我们在学校食堂排队打饭,如果整个食堂只有一个窗口,就不能同时多个人打饭,必须得排队一个个打饭,就像我们的redis命令一样,必须在队列排队等待,等到线程执行完操作之后才可以轮到自己。
可知,redis不是并发执行,而是"串行"执行,那就没有所谓的线程安全问题,因为不会有多个任务竞争同一把锁的情况出现。
或许你又会想问,为什么不选择多个线程来处理redis命令呢?
要知道,在什么样的情况下,我们选择多线程,是在命令消耗cpu较多的情况下,我们需要多线程提高执行效率,而redis大多数操作都是"短快平",根本消耗不了多少cpu,因此也不用怎么竞争资源。并且,redis一般运用在像点赞评论等比较追求快的场景中,如果我们现在使用多线程,那很大部分时间都会消耗在等待锁的释放的过程,而加锁解锁同样也会消耗时间,消耗资源的同时也不符合redis"快"的特性,而我们的命令都是简单的操作,那一次任务执行的速度就会比较快,很明显,串行的速度要比并发的速度快上不少。
另一方面,单线程也有弊端,由于只有一个线程负责任务执行,那如果一个任务他的操作时长是比较长的呢?比如:KEY *;那其他指令就会一直阻塞等待这个命令执行完毕。所以我们在生产过程中,尽量避免使用这种需要遍历整个redis缓存的操作。
总结:今天我们了解,redis之所以快,有一部分原因是它是一个单线程模型,很大程度上减少了线程等待锁释放的时间,同时也避免了线程安全问题,适合应用在对效率要求高,操作简单的场景中。同时我们也知道世界上没有"银弹",如果redis命令执行较长,其他任务等不了,就会去访问数据库,如MYSQL,大量请求到来可能会使mysql奔溃,其他服务无法访问数据库,也会从而导致整个服务奔溃。