多线程为什么要采用同步机制,因为不同的线程有自己的栈,栈中可能引用了多个对象,而多个线程可能引用到了堆中的同一个或多个对象,而线程的栈内存当中的数据只是临时数据,最终都是要刷新到堆中的对象内存,这里的刷新并不是最终的状态一次性刷新,而是在程序执行的过程中随时刷新(肯定有固定的机制,暂不考虑),也许在一个线程中被应用对象中的某一个方法执行到一半的时候就将该对象的变量状态刷新到了堆的对象内存中,那么再从多线程角度来看,当多个线程对同一个对象中的同一个变量进行读写的时候,就会出现类似数据库中的并发问题,假设被引用对象中有一个变量SA=10,线程A读取到10,并且在栈中修改成了15但还没有刷新到堆中,线程B也读取到10,此时A刷新到堆中,则堆中被引用的变量的值变成了15,这个时候B将读取到的10修改为20,再次刷新到堆中,堆中被引用对象的变量SA值为20,这个时候A重新获取SA,发现不是15,而是20,显然出现了问题。
我们知道redis操作是在内存中进行的,是非常快的,那么限制它性能的原因是啥呢,如官方所说是内存和网络
内存大小决定redis在内存中操作的数据量,内存不够是可以做数据结构优化来让内存足够用来操作,那么就剩下一个网络,多线程的引入就和网络有关。因为读写网络的read/write系统调用在Redis执行期间占用了大部分CPU时间,如果把网络读写做成多线程的方式对性能会有很大提升。
Redis6.0引入的多线程部分,实际上只是用来处理网络数据的读写和协议解析,执行命令仍然是单一工作线程。
Redis在处理网络数据时,调用epoll的过程是阻塞的,也就是说这个过程会阻塞线程,如果并发量很高,达到几万的QPS,此处可能会成为瓶颈。一般我们遇到此类网络IO瓶颈的问题,可以增加线程数来解决。开启多线程除了可以减少由于网络I/O等待造成的影响,还可以充分利用CPU的多核优势。Redis6.0也不例外,在此处增加了多线程来处理网络数据,以此来提高Redis的吞吐量。当然相关的命令处理还是单线程运行.